     }
     
     open func enumerateKeysWith(predicate: NSPredicate?, backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBKeyCallback) {
-        guard let db = db else {
-            NSLog("Database reference is not existent (it has probably been closed)")
-            return
-        }
-        let iterator = levelDBIteratorNew(db)
-        var stop = false
-        guard let iteratorPointer = iterator else {
-            NSLog("iterator is nil")
-            return
-        }
-        _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
-        while levelDBIteratorIsValid(iterator) {
-            var iKey: UnsafeMutablePointer<Int8>? = nil
-            var iKeyLength: Int = 0
-            levelDBIteratorGetKey(iterator, &iKey, &iKeyLength)
-            if let iKey = iKey {
-                if let prefix = prefix {
-                    if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
-                        break
-                    }
-                }
-                let iKeyString = String.fromCString(iKey, length: iKeyLength)
-                if predicate != nil {
+        levelDBQueue.sync {
+            guard let db = db else {
+                NSLog("Database reference is not existent (it has probably been closed)")
+                return
+            }
+            let iterator = levelDBIteratorNew(db)
+            var stop = false
+            guard let iteratorPointer = iterator else {
+                NSLog("iterator is nil")
+                return
+            }
+            _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
+            while levelDBIteratorIsValid(iterator) {
+                var iKey: UnsafeMutablePointer<Int8>? = nil
+                var iKeyLength: Int = 0
+                levelDBIteratorGetKey(iterator, &iKey, &iKeyLength)
+                if let iKey = iKey {
+                    if let prefix = prefix {
+                        if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
+                            break
+                        }
+                    }
+                    let iKeyString = String.fromCString(iKey, length: iKeyLength)
+                    if predicate != nil {
+                        var iData: UnsafeMutableRawPointer? = nil
+                        var iDataLength: Int = 0
+                        levelDBIteratorGetValue(iterator, &iData, &iDataLength)
+                        if let iData = iData {
+                            let v = decoder(iKeyString, Data(bytes: iData, count: iDataLength))
+                            if predicate!.evaluate(with: v) {
+                                callback(iKeyString, &stop)
+                            }
+                        }
+                    } else {
+                        callback(iKeyString, &stop)
+                    }
+                }
+                if stop {
+                    break
+                }
+                backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
+            }
+            levelDBIteratorDelete(iterator)
+        }
+    }
+    
+    open func enumerateKeysAndValues(backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBKeyValueCallback) {
+        
+        enumerateKeysAndValuesWith(predicate: nil, backward: backward, startingAtKey: key, andPrefix: prefix, callback: callback)
+    }
+    
+    open func enumerateKeysAndValues(callback: LevelDBKeyValueCallback) {
+        enumerateKeysAndValuesWith(predicate: nil, backward: false, startingAtKey: nil, andPrefix: nil, callback: callback)
+    }
+    
+    open func enumerateKeysAndValuesWith(predicate: NSPredicate?, backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback:LevelDBKeyValueCallback) {
+        levelDBQueue.sync {
+            guard let db = db else {
+                NSLog("Database reference is not existent (it has probably been closed)")
+                return
+            }
+            let iterator = levelDBIteratorNew(db)
+            var stop = false
+            guard let iteratorPointer = iterator else {
+                NSLog("iterator is nil")
+                return
+            }
+            _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
+            while levelDBIteratorIsValid(iterator) {
+                var iKey: UnsafeMutablePointer<Int8>? = nil
+                var iKeyLength: Int = 0
+                levelDBIteratorGetKey(iterator, &iKey, &iKeyLength);
+                if let iKey = iKey {
+                    if let prefix = prefix {
+                        if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
+                            break
+                        }
+                    }
+                    let iKeyString = String.fromCString(iKey, length: iKeyLength)
                     var iData: UnsafeMutableRawPointer? = nil
                     var iDataLength: Int = 0
                     levelDBIteratorGetValue(iterator, &iData, &iDataLength)
-                    if let iData = iData {
-                        let v = decoder(iKeyString, Data(bytes: iData, count: iDataLength))
-                        if predicate!.evaluate(with: v) {
-                            callback(iKeyString, &stop)
-                        }
-                    }
-                } else {
-                    callback(iKeyString, &stop)
-                }
-            }
-            if stop {
-                break
-            }
-            backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
-        }
-        levelDBIteratorDelete(iterator)
-    }
-    
-    open func enumerateKeysAndValues(backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBKeyValueCallback) {
-        
-        enumerateKeysAndValuesWith(predicate: nil, backward: backward, startingAtKey: key, andPrefix: prefix, callback: callback)
-    }
-    
-    open func enumerateKeysAndValues(callback: LevelDBKeyValueCallback) {
-        enumerateKeysAndValuesWith(predicate: nil, backward: false, startingAtKey: nil, andPrefix: nil, callback: callback)
-    }
-    
-    open func enumerateKeysAndValuesWith(predicate: NSPredicate?, backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback:LevelDBKeyValueCallback) {
-        guard let db = db else {
-            NSLog("Database reference is not existent (it has probably been closed)")
-            return
-        }
-        let iterator = levelDBIteratorNew(db)
-        var stop = false
-        guard let iteratorPointer = iterator else {
-            NSLog("iterator is nil")
-            return
-        }
-        _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
-        while levelDBIteratorIsValid(iterator) {
-            var iKey: UnsafeMutablePointer<Int8>? = nil
-            var iKeyLength: Int = 0
-            levelDBIteratorGetKey(iterator, &iKey, &iKeyLength);
-            if let iKey = iKey {
-                if let prefix = prefix {
-                    if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
-                        break
-                    }
-                }
-                let iKeyString = String.fromCString(iKey, length: iKeyLength)
-                var iData: UnsafeMutableRawPointer? = nil
-                var iDataLength: Int = 0
-                levelDBIteratorGetValue(iterator, &iData, &iDataLength)
-                if let iData = iData, let v = decoder(iKeyString, Data(bytes: iData, count: iDataLength)) {
-                    if predicate != nil {
-                        if predicate!.evaluate(with: v) {
+                    if let iData = iData, let v = decoder(iKeyString, Data(bytes: iData, count: iDataLength)) {
+                        if predicate != nil {
+                            if predicate!.evaluate(with: v) {
+                                callback(iKeyString, v, &stop)
+                            }
+                        } else {
                             callback(iKeyString, v, &stop)
                         }
-                    } else {
-                        callback(iKeyString, v, &stop)
-                    }
-                }
-            }
-            if (stop) {
-                break;
-            }
-            backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
-        }
-        levelDBIteratorDelete(iterator);
+                    }
+                }
+                if (stop) {
+                    break;
+                }
+                backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
+            }
+            levelDBIteratorDelete(iterator);
+        }
     }
     
     open func enumerateKeysAndValuesLazily(backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBLazyKeyValueCallback) {
-        guard let db = db else {
-            NSLog("Database reference is not existent (it has probably been closed)")
-            return
-        }
-        let iterator = levelDBIteratorNew(db)
-        var stop = false
-        guard let iteratorPointer = iterator else {
-            NSLog("iterator is nil")
-            return
-        }
-        _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
-        while levelDBIteratorIsValid(iterator) {
-            var iKey: UnsafeMutablePointer<Int8>? = nil
-            var iKeyLength: Int = 0
-            levelDBIteratorGetKey(iterator, &iKey, &iKeyLength);
-            if let iKey = iKey {
-                if let prefix = prefix {
-                    if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
-                        break
-                    }
-                }
-                let iKeyString = String.fromCString(iKey, length: iKeyLength)
-                let getter : () -> [String : Any]? = {
-                    var iData: UnsafeMutableRawPointer? = nil
-                    var iDataLength: Int = 0
-                    levelDBIteratorGetValue(iterator, &iData, &iDataLength);
-                    if let iData = iData {
-                        return self.decoder(iKeyString, Data(bytes: iData, count: iDataLength));
-                    } else {
-                        return nil
-                    }
-                };
-                callback(iKeyString, getter, &stop);
-            }
-            if (stop) {
-                break;
-            }
-            backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
-        }
-        levelDBIteratorDelete(iterator);
+        levelDBQueue.sync {
+            guard let db = db else {
+                NSLog("Database reference is not existent (it has probably been closed)")
+                return
+            }
+            let iterator = levelDBIteratorNew(db)
+            var stop = false
+            guard let iteratorPointer = iterator else {
+                NSLog("iterator is nil")
+                return
+            }
+            _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
+            while levelDBIteratorIsValid(iterator) {
+                var iKey: UnsafeMutablePointer<Int8>? = nil
+                var iKeyLength: Int = 0
+                levelDBIteratorGetKey(iterator, &iKey, &iKeyLength);
+                if let iKey = iKey {
+                    if let prefix = prefix {
+                        if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
+                            break
+                        }
+                    }
+                    let iKeyString = String.fromCString(iKey, length: iKeyLength)
+                    let getter : () -> [String : Any]? = {
+                        var iData: UnsafeMutableRawPointer? = nil
+                        var iDataLength: Int = 0
+                        levelDBIteratorGetValue(iterator, &iData, &iDataLength);
+                        if let iData = iData {
+                            return self.decoder(iKeyString, Data(bytes: iData, count: iDataLength));
+                        } else {
+                            return nil
+                        }
+                    };
+                    callback(iKeyString, getter, &stop);
+                }
+                if (stop) {
+                    break;
+                }
+                backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
+            }
+            levelDBIteratorDelete(iterator);
+        }
     }
     
     // MARK: - Helper methods
     
     open func deleteDatabaseFromDisk() {
         self.close()
-        do {
-            let fileManager = FileManager.default
-            try fileManager.removeItem(atPath: path)
-        } catch {
-            NSLog("error deleting database at path \(path), \(error)")
+        levelDBQueue.sync {
+            do {
+                let fileManager = FileManager.default
+                try fileManager.removeItem(atPath: path)
+            } catch {
+                NSLog("error deleting database at path \(path), \(error)")
+            }
         }
     }
     
     public func open() {
-        self.db = levelDBOpen(path.cString)
+        levelDBQueue.sync {
+            self.db = levelDBOpen(path.cString)
+        }
     }
     
     open func close() {
-        if let db = db {
-            levelDBDelete(db)
-            self.db = nil
+        levelDBQueue.sync {
+            if let db = db {
+                levelDBDelete(db)
+                self.db = nil
+            }
         }
     }
     

    }
    
    open func valueExistsForKey(_ key: String) -> Bool {
        guard let db = db else {
            NSLog("Database reference is not existent (it has probably been closed)")
            return false
        }
        var rawData: UnsafeMutableRawPointer? = nil
        var rawDataLength: Int = 0
        let status = levelDBItemGet(db, key.cString, key.count, &rawData, &rawDataLength)
        if status == 0 {
            free(rawData)
            return true
        } else {
            return false
        }
    }
    
    open func removeValueForKey(_ key: String) {
        guard let db = db else {
            NSLog("Database reference is not existent (it has probably been closed)")
            return
        }
        let status = levelDBItemDelete(db, key.cString, key.count)
        if status != 0 {
            NSLog("Problem removing value with key: \(key) in database")
        }
    }
    

    }
    
    open func removeAllValuesWithPrefix(_ prefix: String) {
        levelDBQueue.sync {
            guard let db = db else {
                NSLog("Database reference is not existent (it has probably been closed)")
                return
            }
            let iterator = levelDBIteratorNew(db)
            let prefixPtr = prefix.cString
            let prefixLen = prefix.count
            
            if prefixLen > 0 {
                levelDBIteratorSeek(iterator, prefix.cString, prefixLen)
            } else {
                levelDBIteratorMoveToFirst(iterator)
            }
            while levelDBIteratorIsValid(iterator) {
                var iKey: UnsafeMutablePointer<Int8>? = nil
                var iKeyLength: Int = 0
                levelDBIteratorGetKey(iterator, &iKey, &iKeyLength)
                if let iKey = iKey {
                    if prefixLen > 0 {
                        if memcmp(iKey, prefixPtr, min(prefixLen, iKeyLength)) != 0 {
                            break;
                        }
                    }
                }
                levelDBItemDelete(db, iKey, iKeyLength)
                levelDBIteratorMoveForward(iterator)
            }
            levelDBIteratorDelete(iterator)
        }
    }
    
    open func allKeys() -> [String] {
