Create separate Lock class.
Add tests for Lock class.
diff --git a/lib/src/command_processor.dart b/lib/src/command_processor.dart
index d724bdf..8b02f53 100644
--- a/lib/src/command_processor.dart
+++ b/lib/src/command_processor.dart
@@ -6,10 +6,10 @@
 class _CommandProcessor {
   final HttpClient client = new HttpClient();
 
-  Completer _lock;
+  Lock _lock = new Lock();
 
   Future<Object> post(Uri uri, dynamic params, {bool value: true}) async {
-    await _getLock();
+    await _lock.acquire();
     HttpClientRequest request = await client.postUrl(uri);
     _setUpRequest(request);
     request.headers.contentType = _contentTypeJson;
@@ -24,14 +24,14 @@
   }
 
   Future<Object> get(Uri uri, {bool value: true}) async {
-    await _getLock();
+    await _lock.acquire();
     HttpClientRequest request = await client.getUrl(uri);
     _setUpRequest(request);
     return await _processResponse(await request.close(), value);
   }
 
   Future<Object> delete(Uri uri, {bool value: true}) async {
-    await _getLock();
+    await _lock.acquire();
     HttpClientRequest request = await client.deleteUrl(uri);
     _setUpRequest(request);
     return await _processResponse(await request.close(), value);
@@ -39,7 +39,7 @@
 
   _processResponse(HttpClientResponse response, bool value) async {
     var respBody = await UTF8.decodeStream(response);
-    _releaseLock();
+    _lock.release();
     try {
       respBody = JSON.decode(respBody);
     } catch (e) {}
@@ -65,18 +65,5 @@
     request.headers.add(HttpHeaders.CACHE_CONTROL, "no-cache");
   }
 
-  Future _getLock() async {
-    while (_lock != null) {
-      await _lock.future;
-    }
-    _lock = new Completer();
-  }
 
-  void _releaseLock() {
-    if (_lock == null) {
-      throw new StateError('No lock to release');
-    }
-    _lock.complete();
-    _lock = null;
-  }
 }
diff --git a/lib/src/lock.dart b/lib/src/lock.dart
new file mode 100644
index 0000000..8748b99
--- /dev/null
+++ b/lib/src/lock.dart
@@ -0,0 +1,24 @@
+library webdriver.lock;
+
+import 'dart:async';
+
+class Lock {
+  Completer _lock;
+
+  Future acquire() async {
+    while (isAcquired) {
+      await _lock.future;
+    }
+    _lock = new Completer();
+  }
+
+  void release() {
+    if (!isAcquired) {
+      throw new StateError('No lock to release');
+    }
+    _lock.complete();
+    _lock = null;
+  }
+
+  bool get isAcquired => _lock != null;
+}
\ No newline at end of file
diff --git a/lib/webdriver.dart b/lib/webdriver.dart
index 5e5f7e8..07177b2 100644
--- a/lib/webdriver.dart
+++ b/lib/webdriver.dart
@@ -12,6 +12,8 @@
 import 'package:crypto/crypto.dart';
 import 'package:matcher/matcher.dart';
 
+import 'src/lock.dart';
+
 part 'src/alert.dart';
 part 'src/capabilities.dart';
 part 'src/command_processor.dart';
diff --git a/test/src/lock_test.dart b/test/src/lock_test.dart
new file mode 100644
index 0000000..f7e9fa2
--- /dev/null
+++ b/test/src/lock_test.dart
@@ -0,0 +1,45 @@
+library webdriver.lock_test;
+
+import 'dart:async';
+
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/src/lock.dart';
+
+void main() {
+  group('Lock', () {
+
+    test('basic acquire/release', () async {
+      var lock = new Lock();
+      expect(lock.isAcquired, isFalse);
+      await lock.acquire();
+      expect(lock.isAcquired, isTrue);
+      lock.release();
+      expect(lock.isAcquired, isFalse);
+      await lock.acquire();
+      expect(lock.isAcquired, isTrue);
+      lock.release();
+    });
+
+    test('release without acquiring fails', () {
+      var lock = new Lock();
+      expect(() => lock.release(), throwsA(new isInstanceOf<StateError>()));
+    });
+
+    test('locking prevents acquisition of lock', () async {
+      var lock = new Lock();
+      var secondLockAcquired = false;
+      await lock.acquire();
+      lock.acquire().then((_) => secondLockAcquired = true);
+      // Make sure that lock is not unacquired just because of timing
+      await new Future.delayed(const Duration(seconds: 1));
+      expect(secondLockAcquired, isFalse);
+      lock.release();
+      // Make sure that enough time has occurred that lock is acquired
+      await new Future.delayed(const Duration(seconds: 1));
+      expect(secondLockAcquired, isTrue);
+    });
+  });
+
+
+
+}
\ No newline at end of file
diff --git a/test/webdriver_test.dart b/test/webdriver_test.dart
index 037d8fb..09a91e0 100644
--- a/test/webdriver_test.dart
+++ b/test/webdriver_test.dart
@@ -4,6 +4,7 @@
 
 import 'src/alert_test.dart' as alert;
 import 'src/keyboard_test.dart' as keyboard;
+import 'src/lock_test.dart' as lock;
 import 'src/logs_test.dart' as logs;
 import 'src/mouse_test.dart' as mouse;
 import 'src/navigation_test.dart' as navigation;
@@ -22,6 +23,7 @@
 
   alert.main();
   keyboard.main();
+  lock.main();
   logs.main();
   mouse.main();
   navigation.main();