diff --git a/src/main/java/net/onrc/onos/datastore/ramcloud/RCClient.java b/src/main/java/net/onrc/onos/datastore/ramcloud/RCClient.java
index 0f18d9c..a11e82f 100644
--- a/src/main/java/net/onrc/onos/datastore/ramcloud/RCClient.java
+++ b/src/main/java/net/onrc/onos/datastore/ramcloud/RCClient.java
@@ -47,16 +47,16 @@
 
     // FIXME come up with a proper way to retrieve configuration
     public static final int MAX_MULTI_READS = Math.max(1, Integer
-	    .valueOf(System.getProperty("ramcloud.max_multi_reads", "400")));
+            .valueOf(System.getProperty("ramcloud.max_multi_reads", "400")));
 
     public static final int MAX_MULTI_WRITES = Math.max(1, Integer
-	    .valueOf(System.getProperty("ramcloud.max_multi_writes", "800")));
+            .valueOf(System.getProperty("ramcloud.max_multi_writes", "800")));
 
     private static final ThreadLocal<JRamCloud> tlsRCClient = new ThreadLocal<JRamCloud>() {
-	@Override
-	protected JRamCloud initialValue() {
-	    return new JRamCloud(getCoordinatorUrl(config));
-	}
+        @Override
+        protected JRamCloud initialValue() {
+            return new JRamCloud(getCoordinatorUrl(config));
+        }
     };
 
     /**
@@ -66,47 +66,47 @@
      *       may be accessed later by another thread.
      */
     static JRamCloud getJRamCloudClient() {
-	return tlsRCClient.get();
+        return tlsRCClient.get();
     }
 
     // Currently RCClient is state-less
     private static final RCClient theInstance= new RCClient();
 
     public static RCClient getClient() {
-	return theInstance;
+        return theInstance;
     }
 
     public static final Configuration getConfiguration() {
-	final File configFile = new File(System.getProperty("ramcloud.config.path", DB_CONFIG_FILE));
-	return getConfiguration(configFile);
+        final File configFile = new File(System.getProperty("ramcloud.config.path", DB_CONFIG_FILE));
+        return getConfiguration(configFile);
     }
 
     public static final Configuration getConfiguration(final File configFile) {
-	if (configFile == null) {
-	    throw new IllegalArgumentException("Need to specify a configuration file or storage directory");
-	}
+        if (configFile == null) {
+            throw new IllegalArgumentException("Need to specify a configuration file or storage directory");
+        }
 
-	if (!configFile.isFile()) {
-	    throw new IllegalArgumentException("Location of configuration must be a file");
-	}
+        if (!configFile.isFile()) {
+            throw new IllegalArgumentException("Location of configuration must be a file");
+        }
 
-	try {
-	    return new PropertiesConfiguration(configFile);
-	} catch (ConfigurationException e) {
-	    throw new IllegalArgumentException("Could not load configuration at: " + configFile, e);
-	}
+        try {
+            return new PropertiesConfiguration(configFile);
+        } catch (ConfigurationException e) {
+            throw new IllegalArgumentException("Could not load configuration at: " + configFile, e);
+        }
     }
 
     public static String getCoordinatorUrl(final Configuration configuration) {
-	final String coordinatorIp = configuration.getString("ramcloud.coordinatorIp", "fast+udp:host=127.0.0.1");
-	final String coordinatorPort = configuration.getString("ramcloud.coordinatorPort", "port=12246");
-	final String coordinatorURL = coordinatorIp + "," + coordinatorPort;
-	return coordinatorURL;
+        final String coordinatorIp = configuration.getString("ramcloud.coordinatorIp", "fast+udp:host=127.0.0.1");
+        final String coordinatorPort = configuration.getString("ramcloud.coordinatorPort", "port=12246");
+        final String coordinatorURL = coordinatorIp + "," + coordinatorPort;
+        return coordinatorURL;
     }
 
     @Override
     public IMultiEntryOperation createOp(IKVTableID tableId, byte[] key, byte[] value) {
-	return RCMultiEntryOperation.create(tableId, key, value);
+        return RCMultiEntryOperation.create(tableId, key, value);
     }
 
     /**
@@ -114,459 +114,459 @@
      */
     @Override
     public long create(IKVTableID tableId, byte[] key, byte[] value)
-	    throws ObjectExistsException {
+            throws ObjectExistsException {
 
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	RejectRules rules = new RejectRules();
-	rules.rejectIfExists();
+        RejectRules rules = new RejectRules();
+        rules.rejectIfExists();
 
-	try {
-	    return rcClient.write(rcTableId.getTableID(), key, value, rules);
-	} catch (JRamCloud.ObjectExistsException e) {
-	    throw new ObjectExistsException(rcTableId, key, e);
-	} catch (JRamCloud.RejectRulesException e) {
-	    log.error("Unexpected RejectRulesException", e);
-	    return JRamCloud.VERSION_NONEXISTENT;
-	}
+        try {
+            return rcClient.write(rcTableId.getTableID(), key, value, rules);
+        } catch (JRamCloud.ObjectExistsException e) {
+            throw new ObjectExistsException(rcTableId, key, e);
+        } catch (JRamCloud.RejectRulesException e) {
+            log.error("Unexpected RejectRulesException", e);
+            return JRamCloud.VERSION_NONEXISTENT;
+        }
     }
 
     @Override
     public IMultiEntryOperation forceCreateOp(IKVTableID tableId, byte[] key, byte[] value) {
-	return RCMultiEntryOperation.forceCreate(tableId, key, value);
+        return RCMultiEntryOperation.forceCreate(tableId, key, value);
     }
 
     @Override
     public long forceCreate(IKVTableID tableId, byte[] key, byte[] value) {
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	long updated_version = rcClient.write(rcTableId.getTableID(), key, value);
-	return updated_version;
+        long updated_version = rcClient.write(rcTableId.getTableID(), key, value);
+        return updated_version;
     }
 
     @Override
     public IMultiEntryOperation readOp(IKVTableID tableId, byte[] key) {
-	return RCMultiEntryOperation.read(tableId, key);
+        return RCMultiEntryOperation.read(tableId, key);
     }
 
     @Override
     public IKVEntry read(IKVTableID tableId, byte[] key)
-	    throws ObjectDoesntExistException {
+            throws ObjectDoesntExistException {
 
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	RejectRules rules = new RejectRules();
-	rules.rejectIfDoesntExists();
-	try {
-	    JRamCloud.Object rcObj = rcClient.read(rcTableId.getTableID(), key, rules);
-	    return new Entry(rcObj.key, rcObj.value, rcObj.version);
-	} catch (JRamCloud.ObjectDoesntExistException e) {
-	    throw new ObjectDoesntExistException(rcTableId, key, e);
-	} catch (JRamCloud.RejectRulesException e) {
-	    log.error("Unexpected RejectRulesException", e);
-	    return null;
-	}
+        RejectRules rules = new RejectRules();
+        rules.rejectIfDoesntExists();
+        try {
+            JRamCloud.Object rcObj = rcClient.read(rcTableId.getTableID(), key, rules);
+            return new Entry(rcObj.key, rcObj.value, rcObj.version);
+        } catch (JRamCloud.ObjectDoesntExistException e) {
+            throw new ObjectDoesntExistException(rcTableId, key, e);
+        } catch (JRamCloud.RejectRulesException e) {
+            log.error("Unexpected RejectRulesException", e);
+            return null;
+        }
     }
 
     @Override
     public IMultiEntryOperation updateOp(IKVTableID tableId, byte[] key, byte[] value,long version) {
-	return RCMultiEntryOperation.update(tableId, key, value, version);
+        return RCMultiEntryOperation.update(tableId, key, value, version);
     }
 
     @Override
     public long update(IKVTableID tableId, byte[] key, byte[] value,
-	    long version) throws ObjectDoesntExistException,
-	    WrongVersionException {
+            long version) throws ObjectDoesntExistException,
+            WrongVersionException {
 
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	RejectRules rules = new RejectRules();
-	rules.rejectIfDoesntExists();
-	rules.rejectIfNeVersion(version);
+        RejectRules rules = new RejectRules();
+        rules.rejectIfDoesntExists();
+        rules.rejectIfNeVersion(version);
 
-	try {
-	    return rcClient.write(rcTableId.getTableID(), key, value, rules);
-	} catch (JRamCloud.ObjectDoesntExistException e) {
-	    throw new ObjectDoesntExistException(rcTableId, key, e);
-	} catch (JRamCloud.WrongVersionException e) {
-	    throw new WrongVersionException(rcTableId, key, version, e);
-	} catch (JRamCloud.RejectRulesException e) {
-	    log.error("Unexpected RejectRulesException", e);
-	    return JRamCloud.VERSION_NONEXISTENT;
-	}
+        try {
+            return rcClient.write(rcTableId.getTableID(), key, value, rules);
+        } catch (JRamCloud.ObjectDoesntExistException e) {
+            throw new ObjectDoesntExistException(rcTableId, key, e);
+        } catch (JRamCloud.WrongVersionException e) {
+            throw new WrongVersionException(rcTableId, key, version, e);
+        } catch (JRamCloud.RejectRulesException e) {
+            log.error("Unexpected RejectRulesException", e);
+            return JRamCloud.VERSION_NONEXISTENT;
+        }
     }
 
 
     @Override
     public long update(IKVTableID tableId, byte[] key, byte[] value)
-	    throws ObjectDoesntExistException {
+            throws ObjectDoesntExistException {
 
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	RejectRules rules = new RejectRules();
-	rules.rejectIfDoesntExists();
+        RejectRules rules = new RejectRules();
+        rules.rejectIfDoesntExists();
 
-	try {
-	    return rcClient.write(rcTableId.getTableID(), key, value, rules);
-	} catch (JRamCloud.ObjectDoesntExistException e) {
-	    throw new ObjectDoesntExistException(rcTableId, key, e);
-	} catch (JRamCloud.RejectRulesException e) {
-	    log.error("Unexpected RejectRulesException", e);
-	    return JRamCloud.VERSION_NONEXISTENT;
-	}
+        try {
+            return rcClient.write(rcTableId.getTableID(), key, value, rules);
+        } catch (JRamCloud.ObjectDoesntExistException e) {
+            throw new ObjectDoesntExistException(rcTableId, key, e);
+        } catch (JRamCloud.RejectRulesException e) {
+            log.error("Unexpected RejectRulesException", e);
+            return JRamCloud.VERSION_NONEXISTENT;
+        }
     }
 
     @Override
     public IMultiEntryOperation deleteOp(IKVTableID tableId, byte[] key, byte[] value,long version) {
-	return RCMultiEntryOperation.delete(tableId, key, value, version);
+        return RCMultiEntryOperation.delete(tableId, key, value, version);
     }
 
     @Override
     public long delete(IKVTableID tableId, byte[] key, long version)
-	    throws ObjectDoesntExistException, WrongVersionException {
+            throws ObjectDoesntExistException, WrongVersionException {
 
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	RejectRules rules = new RejectRules();
-	rules.rejectIfDoesntExists();
-	rules.rejectIfNeVersion(version);
+        RejectRules rules = new RejectRules();
+        rules.rejectIfDoesntExists();
+        rules.rejectIfNeVersion(version);
 
-	try {
-	    return rcClient.remove(rcTableId.getTableID(), key, rules);
-	} catch (JRamCloud.ObjectDoesntExistException e) {
-	    throw new ObjectDoesntExistException(rcTableId, key, e);
-	} catch (JRamCloud.WrongVersionException e) {
-	    throw new WrongVersionException(rcTableId, key, version, e);
-	} catch (JRamCloud.RejectRulesException e) {
-	    log.error("Unexpected RejectRulesException", e);
-	    return JRamCloud.VERSION_NONEXISTENT;
-	}
+        try {
+            return rcClient.remove(rcTableId.getTableID(), key, rules);
+        } catch (JRamCloud.ObjectDoesntExistException e) {
+            throw new ObjectDoesntExistException(rcTableId, key, e);
+        } catch (JRamCloud.WrongVersionException e) {
+            throw new WrongVersionException(rcTableId, key, version, e);
+        } catch (JRamCloud.RejectRulesException e) {
+            log.error("Unexpected RejectRulesException", e);
+            return JRamCloud.VERSION_NONEXISTENT;
+        }
     }
 
     @Override
     public IMultiEntryOperation forceDeleteOp(IKVTableID tableId, byte[] key) {
-	return RCMultiEntryOperation.forceDelete(tableId, key);
+        return RCMultiEntryOperation.forceDelete(tableId, key);
     }
 
     @Override
     public long forceDelete(IKVTableID tableId, byte[] key) {
-	RCTableID rcTableId = (RCTableID) tableId;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
-	long removed_version = rcClient.remove(rcTableId.getTableID(), key);
-	return removed_version;
+        RCTableID rcTableId = (RCTableID) tableId;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
+        long removed_version = rcClient.remove(rcTableId.getTableID(), key);
+        return removed_version;
     }
 
     @Override
     public Iterable<IKVEntry> getAllEntries(IKVTableID tableId) {
-	return new RCTableEntryIterable((RCTableID) tableId);
+        return new RCTableEntryIterable((RCTableID) tableId);
     }
 
     static class RCTableEntryIterable implements Iterable<IKVEntry> {
-	private final RCTableID tableId;
+        private final RCTableID tableId;
 
-	public RCTableEntryIterable(final RCTableID tableId) {
-	    this.tableId = tableId;
-	}
+        public RCTableEntryIterable(final RCTableID tableId) {
+            this.tableId = tableId;
+        }
 
-	@Override
-	public Iterator<IKVEntry> iterator() {
-	    return new RCClient.RCTableIterator(tableId);
-	}
+        @Override
+        public Iterator<IKVEntry> iterator() {
+            return new RCClient.RCTableIterator(tableId);
+        }
     }
 
     public static class RCTableIterator implements Iterator<IKVEntry> {
-	private final RCTableID tableId;
-	protected final TableEnumerator2 enumerator;
-	private JRamCloud.Object last;
+        private final RCTableID tableId;
+        protected final TableEnumerator2 enumerator;
+        private JRamCloud.Object last;
 
-	public RCTableIterator(final RCTableID tableId) {
-	    this.tableId = tableId;
-	    this.enumerator = getJRamCloudClient().new TableEnumerator2(tableId.getTableID());
-	    this.last = null;
-	}
+        public RCTableIterator(final RCTableID tableId) {
+            this.tableId = tableId;
+            this.enumerator = getJRamCloudClient().new TableEnumerator2(tableId.getTableID());
+            this.last = null;
+        }
 
-	@Override
-	public boolean hasNext() {
-	    return this.enumerator.hasNext();
-	}
+        @Override
+        public boolean hasNext() {
+            return this.enumerator.hasNext();
+        }
 
-	@Override
-	public RCTable.Entry next() {
-	    last = enumerator.next();
-	    return new RCTable.Entry(last.key, last.value, last.version);
-	}
+        @Override
+        public RCTable.Entry next() {
+            last = enumerator.next();
+            return new RCTable.Entry(last.key, last.value, last.version);
+        }
 
-	@Override
-	public void remove() {
-	    if (last != null) {
-		getJRamCloudClient();
-		JRamCloud rcClient = RCClient.getJRamCloudClient();
+        @Override
+        public void remove() {
+            if (last != null) {
+                getJRamCloudClient();
+                JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-		RejectRules rules = new RejectRules();
-		rules.rejectIfNeVersion(last.version);
-		try {
-		    rcClient.remove(tableId.getTableID(), last.key, rules);
-		} catch (RejectRulesException e) {
-		    log.trace("remove failed", e);
-		}
-		last = null;
-	    }
-	}
+                RejectRules rules = new RejectRules();
+                rules.rejectIfNeVersion(last.version);
+                try {
+                    rcClient.remove(tableId.getTableID(), last.key, rules);
+                } catch (RejectRulesException e) {
+                    log.trace("remove failed", e);
+                }
+                last = null;
+            }
+        }
     }
 
     @Override
     public boolean multiRead(final Collection<IMultiEntryOperation> ops) {
 
-	if ( ops.size() <= MAX_MULTI_READS && ops instanceof ArrayList) {
-	    @SuppressWarnings({ "unchecked", "rawtypes" })
-	    final ArrayList<RCMultiEntryOperation> arrays = (ArrayList)ops;
-	    return multiReadInternal(arrays);
-	}
+        if ( ops.size() <= MAX_MULTI_READS && ops instanceof ArrayList) {
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            final ArrayList<RCMultiEntryOperation> arrays = (ArrayList)ops;
+            return multiReadInternal(arrays);
+        }
 
-	boolean fail_exists = false;
+        boolean fail_exists = false;
 
-	ArrayList<RCMultiEntryOperation> req = new ArrayList<>();
-	Iterator<IMultiEntryOperation> it = ops.iterator();
-	while (it.hasNext()) {
+        ArrayList<RCMultiEntryOperation> req = new ArrayList<>();
+        Iterator<IMultiEntryOperation> it = ops.iterator();
+        while (it.hasNext()) {
 
-	    req.add((RCMultiEntryOperation) it.next());
+            req.add((RCMultiEntryOperation) it.next());
 
-	    if (req.size() >= MAX_MULTI_READS) {
-		// dispatch multiRead
-		fail_exists |= multiReadInternal(req);
-		req.clear();
-	    }
-	}
+            if (req.size() >= MAX_MULTI_READS) {
+                // dispatch multiRead
+                fail_exists |= multiReadInternal(req);
+                req.clear();
+            }
+        }
 
-	if (!req.isEmpty()) {
-	    // dispatch multiRead
-	    fail_exists |= multiReadInternal(req);
-	    req.clear();
-	}
+        if (!req.isEmpty()) {
+            // dispatch multiRead
+            fail_exists |= multiReadInternal(req);
+            req.clear();
+        }
 
-	return fail_exists;
+        return fail_exists;
     }
 
     @Override
     public boolean multiWrite(final List<IMultiEntryOperation> ops) {
 
-	if ( ops.size() <= MAX_MULTI_WRITES && ops instanceof ArrayList) {
-	    @SuppressWarnings({ "unchecked", "rawtypes" })
-	    final ArrayList<RCMultiEntryOperation> arrays = (ArrayList)ops;
-	    return multiWriteInternal(arrays);
-	}
+        if ( ops.size() <= MAX_MULTI_WRITES && ops instanceof ArrayList) {
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            final ArrayList<RCMultiEntryOperation> arrays = (ArrayList)ops;
+            return multiWriteInternal(arrays);
+        }
 
-	boolean fail_exists = false;
+        boolean fail_exists = false;
 
-	ArrayList<RCMultiEntryOperation> req = new ArrayList<>();
-	Iterator<IMultiEntryOperation> it = ops.iterator();
-	while (it.hasNext()) {
+        ArrayList<RCMultiEntryOperation> req = new ArrayList<>();
+        Iterator<IMultiEntryOperation> it = ops.iterator();
+        while (it.hasNext()) {
 
-	    req.add((RCMultiEntryOperation) it.next());
+            req.add((RCMultiEntryOperation) it.next());
 
-	    if (req.size() >= MAX_MULTI_WRITES) {
-		// dispatch multiWrite
-		fail_exists |= multiWriteInternal(req);
-		req.clear();
-	    }
-	}
+            if (req.size() >= MAX_MULTI_WRITES) {
+                // dispatch multiWrite
+                fail_exists |= multiWriteInternal(req);
+                req.clear();
+            }
+        }
 
-	if (!req.isEmpty()) {
-	    // dispatch multiWrite
-	    fail_exists |= multiWriteInternal(req);
-	    req.clear();
-	}
+        if (!req.isEmpty()) {
+            // dispatch multiWrite
+            fail_exists |= multiWriteInternal(req);
+            req.clear();
+        }
 
-	return fail_exists;
+        return fail_exists;
     }
 
     @Override
     public boolean multiDelete(final Collection<IMultiEntryOperation> ops) {
 
-	// TODO implement multiRemove JNI, etc. if we need performance
+        // TODO implement multiRemove JNI, etc. if we need performance
 
-	boolean fail_exists = false;
-	JRamCloud rcClient = getJRamCloudClient();
+        boolean fail_exists = false;
+        JRamCloud rcClient = getJRamCloudClient();
 
-	for (IMultiEntryOperation iop : ops) {
-	    RCMultiEntryOperation op = (RCMultiEntryOperation)iop;
-	    switch (op.getOperation()) {
-	    case DELETE:
-		RejectRules rules = new RejectRules();
-		rules.rejectIfDoesntExists();
-		rules.rejectIfNeVersion(op.getVersion());
+        for (IMultiEntryOperation iop : ops) {
+            RCMultiEntryOperation op = (RCMultiEntryOperation)iop;
+            switch (op.getOperation()) {
+            case DELETE:
+                RejectRules rules = new RejectRules();
+                rules.rejectIfDoesntExists();
+                rules.rejectIfNeVersion(op.getVersion());
 
-		try {
-		    long removed_version = rcClient.remove(op.tableId.getTableID(), op.entry.getKey(), rules);
-		    op.entry.setVersion(removed_version);
-		    op.status = STATUS.SUCCESS;
-		} catch (JRamCloud.ObjectDoesntExistException|JRamCloud.WrongVersionException e) {
-		    log.error("Failed to remove key:" + ByteArrayUtil.toHexStringBuffer(op.entry.getKey(), "") + " from tableID:" + op.tableId, e );
-		    fail_exists = true;
-		    op.status = STATUS.FAILED;
-		} catch (JRamCloud.RejectRulesException e) {
-		    log.error("Failed to remove key:" + ByteArrayUtil.toHexStringBuffer(op.entry.getKey(), "") + " from tableID:" + op.tableId, e );
-		    fail_exists = true;
-		    op.status = STATUS.FAILED;
-		}
-		break;
+                try {
+                    long removed_version = rcClient.remove(op.tableId.getTableID(), op.entry.getKey(), rules);
+                    op.entry.setVersion(removed_version);
+                    op.status = STATUS.SUCCESS;
+                } catch (JRamCloud.ObjectDoesntExistException|JRamCloud.WrongVersionException e) {
+                    log.error("Failed to remove key:" + ByteArrayUtil.toHexStringBuffer(op.entry.getKey(), "") + " from tableID:" + op.tableId, e );
+                    fail_exists = true;
+                    op.status = STATUS.FAILED;
+                } catch (JRamCloud.RejectRulesException e) {
+                    log.error("Failed to remove key:" + ByteArrayUtil.toHexStringBuffer(op.entry.getKey(), "") + " from tableID:" + op.tableId, e );
+                    fail_exists = true;
+                    op.status = STATUS.FAILED;
+                }
+                break;
 
-	    case FORCE_DELETE:
-		long removed_version = rcClient.remove(op.tableId.getTableID(), op.entry.getKey());
-		if (removed_version != JRamCloud.VERSION_NONEXISTENT) {
-		    op.entry.setVersion(removed_version);
-		    op.status = STATUS.SUCCESS;
-		} else {
-		    log.error("Failed to remove key:{} from tableID:{}", ByteArrayUtil.toHexStringBuffer(op.entry.getKey(), ""), op.tableId );
-		    fail_exists = true;
-		    op.status = STATUS.FAILED;
-		}
-		break;
+            case FORCE_DELETE:
+                long removed_version = rcClient.remove(op.tableId.getTableID(), op.entry.getKey());
+                if (removed_version != JRamCloud.VERSION_NONEXISTENT) {
+                    op.entry.setVersion(removed_version);
+                    op.status = STATUS.SUCCESS;
+                } else {
+                    log.error("Failed to remove key:{} from tableID:{}", ByteArrayUtil.toHexStringBuffer(op.entry.getKey(), ""), op.tableId );
+                    fail_exists = true;
+                    op.status = STATUS.FAILED;
+                }
+                break;
 
-	    default:
-		log.error("Invalid operation {} specified on multiDelete", op.getOperation() );
-		fail_exists = true;
-		op.status = STATUS.FAILED;
-		break;
-	    }
-	}
-	return fail_exists;
+            default:
+                log.error("Invalid operation {} specified on multiDelete", op.getOperation() );
+                fail_exists = true;
+                op.status = STATUS.FAILED;
+                break;
+            }
+        }
+        return fail_exists;
     }
 
     private boolean multiReadInternal(final ArrayList<RCMultiEntryOperation> ops) {
-	boolean fail_exists = false;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        boolean fail_exists = false;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	final int reqs = ops.size();
+        final int reqs = ops.size();
 
-	MultiReadObject multiReadObjects = new MultiReadObject(reqs);
+        MultiReadObject multiReadObjects = new MultiReadObject(reqs);
 
-	// setup multi-read operation objects
-	for (int i = 0; i < reqs; ++i) {
-	    IMultiEntryOperation op = ops.get(i);
-	    multiReadObjects.setObject(i, ((RCTableID)op.getTableId()).getTableID(), op.getKey());
-	}
+        // setup multi-read operation objects
+        for (int i = 0; i < reqs; ++i) {
+            IMultiEntryOperation op = ops.get(i);
+            multiReadObjects.setObject(i, ((RCTableID)op.getTableId()).getTableID(), op.getKey());
+        }
 
-	// execute
-	JRamCloud.Object[] results = rcClient.multiRead(multiReadObjects.tableId, multiReadObjects.key, multiReadObjects.keyLength, reqs);
-	if (results.length != reqs) {
-	    log.error("multiRead returned unexpected number of results. (requested:{}, returned:{})", reqs, results.length);
-	    fail_exists = true;
-	}
+        // execute
+        JRamCloud.Object[] results = rcClient.multiRead(multiReadObjects.tableId, multiReadObjects.key, multiReadObjects.keyLength, reqs);
+        if (results.length != reqs) {
+            log.error("multiRead returned unexpected number of results. (requested:{}, returned:{})", reqs, results.length);
+            fail_exists = true;
+        }
 
-	for (int i = 0; i < results.length; ++i) {
-	    IModifiableMultiEntryOperation op = ops.get(i);
-	    if (results[i] == null) {
-		log.error("MultiRead error, skipping {}, {}", op.getTableId(), op);
-		fail_exists = true;
-		op.setStatus(STATUS.FAILED);
-		continue;
-	    }
-	    assert (Arrays.equals(results[i].key, op.getKey()));
+        for (int i = 0; i < results.length; ++i) {
+            IModifiableMultiEntryOperation op = ops.get(i);
+            if (results[i] == null) {
+                log.error("MultiRead error, skipping {}, {}", op.getTableId(), op);
+                fail_exists = true;
+                op.setStatus(STATUS.FAILED);
+                continue;
+            }
+            assert (Arrays.equals(results[i].key, op.getKey()));
 
-	    op.setValue(results[i].value, results[i].version);
-	    if (results[i].version == JRamCloud.VERSION_NONEXISTENT) {
-		fail_exists = true;
-		op.setStatus(STATUS.FAILED);
-	    } else {
-		op.setStatus(STATUS.SUCCESS);
-	    }
-	}
+            op.setValue(results[i].value, results[i].version);
+            if (results[i].version == JRamCloud.VERSION_NONEXISTENT) {
+                fail_exists = true;
+                op.setStatus(STATUS.FAILED);
+            } else {
+                op.setStatus(STATUS.SUCCESS);
+            }
+        }
 
-	return fail_exists;
+        return fail_exists;
     }
 
     private boolean multiWriteInternal(final ArrayList<RCMultiEntryOperation> ops) {
-	boolean fail_exists = false;
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
+        boolean fail_exists = false;
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
 
-	final int reqs = ops.size();
+        final int reqs = ops.size();
 
-	MultiWriteObject multiWriteObjects = new MultiWriteObject(reqs);
+        MultiWriteObject multiWriteObjects = new MultiWriteObject(reqs);
 
-	for (int i = 0; i < reqs; ++i) {
+        for (int i = 0; i < reqs; ++i) {
 
-	    IModifiableMultiEntryOperation op = ops.get(i);
-	    RejectRules rules = new RejectRules();
+            IModifiableMultiEntryOperation op = ops.get(i);
+            RejectRules rules = new RejectRules();
 
-	    switch (op.getOperation()) {
-	    case CREATE:
-		rules.rejectIfExists();
-		break;
-	    case FORCE_CREATE:
-		// no reject rule
-		break;
-	    case UPDATE:
-		rules.rejectIfDoesntExists();
-		rules.rejectIfNeVersion(op.getVersion());
-		break;
+            switch (op.getOperation()) {
+            case CREATE:
+                rules.rejectIfExists();
+                break;
+            case FORCE_CREATE:
+                // no reject rule
+                break;
+            case UPDATE:
+                rules.rejectIfDoesntExists();
+                rules.rejectIfNeVersion(op.getVersion());
+                break;
 
-	    default:
-		log.error("Invalid operation {} specified on multiWriteInternal", op.getOperation() );
-		fail_exists = true;
-		op.setStatus(STATUS.FAILED);
-		return fail_exists;
-	    }
-	    multiWriteObjects.setObject(i, ((RCTableID)op.getTableId()).getTableID(), op.getKey(), op.getValue(), rules);
-	}
+            default:
+                log.error("Invalid operation {} specified on multiWriteInternal", op.getOperation() );
+                fail_exists = true;
+                op.setStatus(STATUS.FAILED);
+                return fail_exists;
+            }
+            multiWriteObjects.setObject(i, ((RCTableID)op.getTableId()).getTableID(), op.getKey(), op.getValue(), rules);
+        }
 
-	MultiWriteRspObject[] results = rcClient.multiWrite(multiWriteObjects.tableId, multiWriteObjects.key, multiWriteObjects.keyLength, multiWriteObjects.value, multiWriteObjects.valueLength, ops.size(), multiWriteObjects.rules);
-	if (results.length != reqs) {
-	    log.error("multiWrite returned unexpected number of results. (requested:{}, returned:{})", reqs, results.length);
-	    fail_exists = true;
-	}
+        MultiWriteRspObject[] results = rcClient.multiWrite(multiWriteObjects.tableId, multiWriteObjects.key, multiWriteObjects.keyLength, multiWriteObjects.value, multiWriteObjects.valueLength, ops.size(), multiWriteObjects.rules);
+        if (results.length != reqs) {
+            log.error("multiWrite returned unexpected number of results. (requested:{}, returned:{})", reqs, results.length);
+            fail_exists = true;
+        }
 
-	for (int i = 0; i < results.length; ++i) {
-	    IModifiableMultiEntryOperation op = ops.get(i);
+        for (int i = 0; i < results.length; ++i) {
+            IModifiableMultiEntryOperation op = ops.get(i);
 
-	    if (results[i] != null
-		    && results[i].getStatus() == RCClient.STATUS_OK) {
-		op.setStatus(STATUS.SUCCESS);
-		op.setVersion(results[i].getVersion());
-	    } else {
-		op.setStatus(STATUS.FAILED);
-		fail_exists = true;
-	    }
-	}
+            if (results[i] != null
+                    && results[i].getStatus() == RCClient.STATUS_OK) {
+                op.setStatus(STATUS.SUCCESS);
+                op.setVersion(results[i].getVersion());
+            } else {
+                op.setStatus(STATUS.FAILED);
+                fail_exists = true;
+            }
+        }
 
-	return fail_exists;
+        return fail_exists;
     }
 
     private static final ConcurrentHashMap<String, RCTable> tables = new ConcurrentHashMap<>();
 
     @Override
     public IKVTable getTable(final String tableName) {
-	RCTable table = tables.get(tableName);
-	if (table == null) {
-	    RCTable new_table = new RCTable(tableName);
-	    RCTable existing_table = tables
-		    .putIfAbsent(tableName, new_table);
-	    if (existing_table != null) {
-		return existing_table;
-	    } else {
-		return new_table;
-	    }
-	}
-	return table;
+        RCTable table = tables.get(tableName);
+        if (table == null) {
+            RCTable new_table = new RCTable(tableName);
+            RCTable existing_table = tables
+                    .putIfAbsent(tableName, new_table);
+            if (existing_table != null) {
+                return existing_table;
+            } else {
+                return new_table;
+            }
+        }
+        return table;
     }
 
     @Override
     public void dropTable(IKVTable table) {
-	JRamCloud rcClient = RCClient.getJRamCloudClient();
-	rcClient.dropTable(table.getTableId().getTableName());
-	tables.remove(table.getTableId().getTableName());
+        JRamCloud rcClient = RCClient.getJRamCloudClient();
+        rcClient.dropTable(table.getTableId().getTableName());
+        tables.remove(table.getTableId().getTableName());
     }
 
     static final long VERSION_NONEXISTENT = JRamCloud.VERSION_NONEXISTENT;
 
     @Override
     public long VERSION_NONEXISTENT() {
-	return VERSION_NONEXISTENT;
+        return VERSION_NONEXISTENT;
     }
 }
