Reworked DatabaseService API.
Initial implementation of LockManager.
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/BatchReadRequest.java b/core/api/src/main/java/org/onlab/onos/store/service/BatchReadRequest.java
new file mode 100644
index 0000000..1cf422c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/store/service/BatchReadRequest.java
@@ -0,0 +1,70 @@
+package org.onlab.onos.store.service;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Collection of read requests to be submitted as one batch.
+ */
+public class BatchReadRequest {
+
+	private final List<ReadRequest> readRequests;
+
+	/**
+	 * Creates a new BatchReadRequest object from the specified list of read requests.
+	 * @param readRequests read requests.
+	 * @return BatchReadRequest object.
+	 */
+	public static BatchReadRequest create(List<ReadRequest> readRequests) {
+		return new BatchReadRequest(readRequests);
+	}
+
+	private BatchReadRequest(List<ReadRequest> readRequests) {
+		this.readRequests = Collections.unmodifiableList(readRequests);
+	}
+
+	/**
+	 * Returns the number of requests in this batch.
+	 * @return size of request batch.
+	 */
+	public int batchSize() {
+		return readRequests.size();
+	}
+
+	/**
+	 * Returns the requests in this batch as a list.
+	 * @return list of read requests
+	 */
+	public List<ReadRequest> getAsList() {
+		return readRequests;
+	}
+
+	/**
+	 * Builder for BatchReadRequest.
+	 */
+	public static class Builder {
+
+		private final List<ReadRequest> readRequests = Lists.newLinkedList();
+
+		/**
+		 * Append a get request.
+		 * @param tableName table name
+		 * @param key key to fetch.
+		 * @return this Builder
+		 */
+		public Builder get(String tableName, String key) {
+			readRequests.add(new ReadRequest(tableName, key));
+			return this;
+		}
+
+		/**
+		 * Builds a BatchReadRequest
+		 * @return BatchReadRequest
+		 */
+		public BatchReadRequest build() {
+			return new BatchReadRequest(readRequests);
+		}
+	}
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/BatchReadResult.java b/core/api/src/main/java/org/onlab/onos/store/service/BatchReadResult.java
new file mode 100644
index 0000000..7281eff
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/store/service/BatchReadResult.java
@@ -0,0 +1,21 @@
+package org.onlab.onos.store.service;
+
+import java.util.Collections;
+import java.util.List;
+
+public class BatchReadResult {
+	
+	private final List<ReadResult> readResults;
+	
+	public BatchReadResult(List<ReadResult> readResults)  {
+		this.readResults = Collections.unmodifiableList(readResults);
+	}
+	
+	public List<ReadResult> getAsList() {
+		return readResults;
+	}
+	
+	public int batchSize() {
+		return readResults.size();
+	}
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/BatchWriteRequest.java b/core/api/src/main/java/org/onlab/onos/store/service/BatchWriteRequest.java
new file mode 100644
index 0000000..9ce14a1
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/store/service/BatchWriteRequest.java
@@ -0,0 +1,90 @@
+package org.onlab.onos.store.service;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Collection of write requests to be submitted as one batch.
+ */
+public class BatchWriteRequest {
+
+	private final List<WriteRequest> writeRequests;
+
+	/**
+	 * Creates a new BatchWriteRequest object from the specified list of write requests.
+	 * @param writeRequests write requests.
+	 * @return BatchWriteRequest object.
+	 */
+	public static BatchWriteRequest create(List<WriteRequest> writeRequests) {
+		return new BatchWriteRequest(writeRequests);
+	}
+
+	private BatchWriteRequest(List<WriteRequest> writeRequests) {
+		this.writeRequests = Collections.unmodifiableList(writeRequests);
+	}
+
+	/**
+	 * Returns the requests in this batch as a list.
+	 * @return list of write requests
+	 */
+	public List<WriteRequest> getAsList() {
+		return writeRequests;
+	}
+
+	/**
+	 * Returns the number of requests in this batch.
+	 * @return size of request batch.
+	 */
+	public int batchSize() {
+		return writeRequests.size();
+	}
+
+	/**
+	 * Builder for BatchWriteRequest.
+	 */
+	public static class Builder {
+
+		private final List<WriteRequest> writeRequests = Lists.newLinkedList();
+
+		public Builder put(String tableName, String key, byte[] value) {
+			writeRequests.add(WriteRequest.put(tableName, key, value));
+			return this;
+		}
+
+		public Builder putIfAbsent(String tableName, String key, byte[] value) {
+			writeRequests.add(WriteRequest.putIfAbsent(tableName, key, value));
+			return this;
+		}
+
+		public Builder putIfValueMatches(String tableName, String key, byte[] oldValue, byte[] newValue) {
+			writeRequests.add(WriteRequest.putIfValueMatches(tableName, key, oldValue, newValue));
+			return this;
+		}
+
+		public Builder putIfVersionMatches(String tableName, String key, byte[] value, long version) {
+			writeRequests.add(WriteRequest.putIfVersionMatches(tableName, key, value, version));
+			return this;
+		}
+
+		public Builder remove(String tableName, String key) {
+			writeRequests.add(WriteRequest.remove(tableName, key));
+			return this;
+		}
+
+		public Builder removeIfVersionMatches(String tableName, String key, long version) {
+			writeRequests.add(WriteRequest.removeIfVersionMatches(tableName, key, version));
+			return this;
+		}
+
+		public Builder removeIfValueMatches(String tableName, String key, byte[] value) {
+			writeRequests.add(WriteRequest.removeIfValueMatches(tableName, key, value));
+			return this;
+		}
+
+		public BatchWriteRequest build() {
+			return new BatchWriteRequest(writeRequests);
+		}
+	}
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/BatchWriteResult.java b/core/api/src/main/java/org/onlab/onos/store/service/BatchWriteResult.java
new file mode 100644
index 0000000..22c653c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/store/service/BatchWriteResult.java
@@ -0,0 +1,30 @@
+package org.onlab.onos.store.service;
+
+import java.util.Collections;
+import java.util.List;
+
+public class BatchWriteResult {
+	
+	private final List<WriteResult> writeResults;
+	
+	public BatchWriteResult(List<WriteResult> writeResults) {
+		this.writeResults = Collections.unmodifiableList(writeResults);
+	}
+	
+	public boolean isSuccessful() {
+		for (WriteResult result : writeResults) {
+			if (result.status() != WriteStatus.OK) {
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	public List<WriteResult> getAsList() {
+		return this.writeResults;
+	}
+	
+	public int batchSize() {
+		return writeResults.size();
+	}
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/DatabaseService.java b/core/api/src/main/java/org/onlab/onos/store/service/DatabaseService.java
index cf0ef0a..57d81f2 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/DatabaseService.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/DatabaseService.java
@@ -1,7 +1,5 @@
 package org.onlab.onos.store.service;
 
-import java.util.List;
-
 /**
  * Service interface for a strongly consistent and durable
  * key value data store.
@@ -9,46 +7,93 @@
 public interface DatabaseService {
 
     /**
-     * Performs a read on the database.
-     * @param request read request.
-     * @return ReadResult
-     * @throws DatabaseException if there is a failure in executing read.
+     * Reads the specified key.
+     * @param tableName name of the table associated with this operation.
+     * @return key key to read.
+     * @returns value (and version) associated with this key. This calls returns null if the key does not exist.
      */
-    ReadResult read(ReadRequest request);
-
+    VersionedValue get(String tableName, String key);
+    
     /**
-     * Performs a batch read operation on the database.
-     * The main advantage of batch read operation is parallelization.
-     * @param batch batch of read requests to execute.
-     * @return batch read result.
+     * Associate the key with a value.
+     * @param tableName table name in which this key/value resides.
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with the specified key, or null if there was no mapping for the key.
      */
-    List<OptionalResult<ReadResult, DatabaseException>> batchRead(List<ReadRequest> batch);
-
-    // FIXME Give me a better name
+    VersionedValue put(String tableName, String key, byte[] value);
+    
     /**
-     * Performs a write operation on the database.
-     * @param request write request
-     * @return write result.
-     * @throws DatabaseException if there is failure in execution write.
+     * If the specified key is not already associated with a value, associate it with the given value.
+     * @param tableName table name in which this key/value resides.
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return true if put was successful, false if there is already a value associated with this key
      */
-    OptionalResult<WriteResult, DatabaseException> writeNothrow(WriteRequest request);
-
+    boolean putIfAbsent(String tableName, String key, byte[] value);
+    
     /**
-     * Performs a write operation on the database.
-     * @param request write request
-     * @return write result.
-     * @throws OptimisticLockException FIXME define conditional failure
-     * @throws PreconditionFailedException FIXME define conditional failure
-     * @throws DatabaseException if there is failure in execution write.
+     * Sets the key to the specified value if the version in the database (for that key)
+     * matches the specified version.
+     * @param tableName name of table associated with this operation.
+     * @param key key
+     * @param value value
+     * @param version version that should present in the database for the put to be successful.
+     * @return true if put was successful, false if there version in database is different from what is specified.
      */
-    WriteResult write(WriteRequest request)/* throws OptimisticLockException, PreconditionFailedException*/;
-
+    boolean putIfVersionMatches(String tableName, String key, byte[] value, long version);
+    
     /**
-     * Performs a batch write operation on the database.
-     * Batch write provides transactional semantics. Either all operations
-     * succeed or none of them do.
-     * @param batch batch of write requests to execute as a transaction.
-     * @return result of executing the batch write operation.
+     * Replaces the entry for a key only if currently mapped to a given value.
+     * @param tableName name of table associated with this operation.
+     * @param key with which the specified value is associated
+     * @param oldValue value expected to be associated with the specified key
+     * @param newValue value to be associated with the specified key
+     * @return true if put was successful, false if there version in database is different from what is specified.
      */
-    List<OptionalResult<WriteResult, DatabaseException>> batchWrite(List<WriteRequest> batch);
-}
+    boolean putIfValueMatches(String tableName, String key, byte[] oldValue, byte[] newValue);
+    
+    /**
+     * Removes the key (and associated value).
+     * @param tableName name of table associated with this operation.
+     * @param key key to remove
+     * @return value previously associated with the key. This call returns null if the key does not exist.
+     */
+    VersionedValue remove(String tableName, String key);
+    
+    /**
+     * Removes the key (and associated value) if the version in the database matches specified version.
+     * @param tableName name of table associated with this operation.
+     * @param key key to remove
+     * @param version version that should present in the database for the remove to be successful.
+     * @return true if remove was successful, false if there version in database is different from what is specified.
+     */
+    boolean removeIfVersionMatches(String tableName, String key, long version);
+    
+    /**
+     * Removes the key (and associated value) if the value in the database matches specified value.
+     * @param tableName name of table associated with this operation.
+     * @param key key to remove
+     * @param value value that should present in the database for the remove to be successful.
+     * @return true if remove was successful, false if there value in database is different from what is specified.
+     */
+    boolean removeIfValueMatches(String tableName, String key, byte[] value);
+    
+    /**
+     * Performs a batch read operation and returns the results.
+     * @param batchRequest batch request.
+     * @return result of the batch operation.
+     */
+    BatchReadResult batchRead(BatchReadRequest batchRequest);
+    
+    /**
+     * Performs a batch write operation and returns the results.
+     * This method provides transactional semantics. Either all writes succeed or none do.
+     * Even a single write failure would cause the entire batch to be aborted.
+     * In the case of unsuccessful operation, the batch result can be inspected to determine
+     * which operation(s) caused the batch to fail.
+     * @param batchRequest batch request.
+     * @return result of the batch operation.
+     */
+    BatchWriteResult batchWrite(BatchWriteRequest batchRequest);
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/Lock.java b/core/api/src/main/java/org/onlab/onos/store/service/Lock.java
index 6d68133..510df82 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/Lock.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/Lock.java
@@ -9,6 +9,12 @@
  */
 public interface Lock {
 
+	/**
+	 * Returns the path this lock will be used to guard from concurrent access.
+	 * @return path.
+	 */
+	String path();
+
     /**
      * Acquires the lock.
      * If the lock is not available then the caller thread becomes
@@ -26,7 +32,7 @@
      * already been released by invoking unlock(). Must be in the range
      * (0, LockManager.MAX_LEASE_MILLIS]
      */
-    void lock(long leaseDurationMillis);
+    void lock(int leaseDurationMillis);
 
     /**
      * Acquires the lock only if it is free at the time of invocation.
@@ -36,7 +42,7 @@
      * (0, LockManager.MAX_LEASE_MILLIS]
      * @return true if the lock was acquired and false otherwise
      */
-    boolean tryLock(long leaseDurationMillis);
+    boolean tryLock(int leaseDurationMillis);
 
     /**
      * Acquires the lock if it is free within the given waiting
@@ -49,7 +55,7 @@
      * @return true if the lock was acquired and false if the waiting time
      * elapsed before the lock was acquired
      */
-    boolean tryLock(long waitTimeMillis, long leaseDurationMillis);
+    boolean tryLock(long waitTimeMillis, int leaseDurationMillis);
 
     /**
      * Returns true if this Lock instance currently holds the lock.
@@ -72,5 +78,5 @@
      * @return true if successfully extended expiration, false if attempt to
      * extend expiration fails or if the path is currently not locked by this instance.
      */
-    boolean extendExpiration(long leaseDurationMillis);
+    boolean extendExpiration(int leaseDurationMillis);
 }
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/ReadRequest.java b/core/api/src/main/java/org/onlab/onos/store/service/ReadRequest.java
index 9f7af4a..f30529e 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/ReadRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/ReadRequest.java
@@ -75,5 +75,4 @@
         return Objects.equals(this.key, other.key) &&
                 Objects.equals(this.tableName, other.tableName);
     }
-
 }
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/ReadResult.java b/core/api/src/main/java/org/onlab/onos/store/service/ReadResult.java
index 49e9665..3f253f2 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/ReadResult.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/ReadResult.java
@@ -11,12 +11,21 @@
     private final String tableName;
     private final String key;
     private final VersionedValue value;
+    private final ReadStatus status;
 
-    public ReadResult(String tableName, String key, VersionedValue value) {
+    public ReadResult(ReadStatus status, String tableName, String key, VersionedValue value) {
+    	this.status = status;
         this.tableName = tableName;
         this.key = key;
         this.value = value;
     }
+    
+    /**
+     * Returns the status of the read operation.
+     */
+    public ReadStatus status() {
+    	return status;
+    }
 
     /**
      * Returns database table name.
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/ReadStatus.java b/core/api/src/main/java/org/onlab/onos/store/service/ReadStatus.java
new file mode 100644
index 0000000..2039a1c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/store/service/ReadStatus.java
@@ -0,0 +1,6 @@
+package org.onlab.onos.store.service;
+
+public enum ReadStatus {
+	OK,
+	NO_SUCH_TABLE
+}
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java b/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java
index fb736e5..6607cfe 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java
@@ -112,7 +112,7 @@
      * @param previousVersion previous version expected
      * @return WriteRequest
      */
-    public static WriteRequest remove(String tableName, String key,
+    public static WriteRequest removeIfVersionMatches(String tableName, String key,
                                       long previousVersion) {
         return new WriteRequest(REMOVE_IF_VALUE, tableName, key,
                                 null, previousVersion, null);
@@ -127,7 +127,7 @@
      * @param oldValue  previous value expected, must not be null
      * @return WriteRequest
      */
-    public static WriteRequest remove(String tableName, String key,
+    public static WriteRequest removeIfValueMatches(String tableName, String key,
                                       byte[] oldValue) {
         return new WriteRequest(Type.REMOVE_IF_VALUE, tableName, key,
                                 null, ANY_VERSION, checkNotNull(oldValue));
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/WriteResult.java b/core/api/src/main/java/org/onlab/onos/store/service/WriteResult.java
index aec3046..3cc11b0 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/WriteResult.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/WriteResult.java
@@ -7,34 +7,27 @@
  * Database write result.
  */
 public class WriteResult {
-
-    private final String tableName;
-    private final String key;
+	
+    private final WriteStatus status;
     private final VersionedValue previousValue;
-
-    public WriteResult(String tableName, String key, VersionedValue previousValue) {
-        this.tableName = tableName;
-        this.key = key;
+    
+    public WriteResult(WriteStatus status, VersionedValue previousValue) {
+    	this.status = status;
         this.previousValue = previousValue;
     }
 
-    public String tableName() {
-        return tableName;
-    }
-
-    public String key() {
-        return key;
-    }
-
     public VersionedValue previousValue() {
         return previousValue;
     }
+    
+    public WriteStatus status() {
+    	return status;
+    }
 
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
-                .add("tableName", tableName)
-                .add("key", key)
+        		.add("status", status)
                 .add("previousValue", previousValue)
                 .toString();
     }
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/WriteStatus.java b/core/api/src/main/java/org/onlab/onos/store/service/WriteStatus.java
new file mode 100644
index 0000000..ebb4f6d
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/store/service/WriteStatus.java
@@ -0,0 +1,8 @@
+package org.onlab.onos.store.service;
+
+public enum WriteStatus {
+	OK,
+	ABORTED,
+	PRECONDITION_VIOLATION,
+	NO_SUCH_TABLE,
+}