diff --git a/bip/utils/__init__.py b/bip/utils/__init__.py
index 4cbd17a5c5f00a3154e8a5e3f3c9c8d9ecdb6a74..e97e10008947ae74a4c5693d70acae53da762d64 100644
--- a/bip/utils/__init__.py
+++ b/bip/utils/__init__.py
@@ -1,13 +1,45 @@
-import shutil
-from fsl.wrappers.wrapperutils import cmdwrapper
-
-installed_sienax = shutil.which('bb_sienax')
-
-if installed_sienax:
-    @cmdwrapper
-    def bb_sienax(input, output=None, **kwargs):
-        return ['bb_sienax', input, output]
-else:
-    def bb_sienax(input, output=None, **kwargs):
-        from . import sienax
-        sienax.bb_sienax(input, output)
+#!/usr/bin/env python
+"""The bip.utils package contains a range of miscellaneous utilities. """
+
+
+import            contextlib
+import            logging
+import os.path as op
+import            os
+import            time
+
+
+log = logging.getLogger(__name__)
+
+
+@contextlib.contextmanager
+def lockdir(dirname, delay=5):
+    """Lock a directory for exclusive access.
+
+    Primitive mechanism by which concurrent access to a directory can be
+    prevented. Attempts to create a semaphore file in the directory, but waits
+    if that file already exists. Removes the file when finished.
+    """
+
+    lockfile = op.join(dirname, '.fsl_ci.lockdir')
+
+    while True:
+        try:
+            log.debug(f'Attempting to lock %s for exclusive access.', dirname)
+            fd = os.open(lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
+            break
+        except OSError as e:
+            if e.errno != errno.EEXIST:
+                raise e
+            log.debug('%s is already locked - trying again '
+                      'in %s seconds ...', dirname, delay)
+        time.sleep(10)
+
+    log.debug('Exclusive access acquired for %s ...', dirname)
+    try:
+        yield
+
+    finally:
+        log.debug('Relinquishing lock on %s', dirname)
+        os.close( fd)
+        os.unlink(lockfile)