You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ps...@apache.org on 2019/05/15 15:28:49 UTC

[hbase] branch master updated: HBASE-13798 TestFromClientSide* don't close the Table

This is an automated email from the ASF dual-hosted git repository.

psomogyi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/master by this push:
     new 7878389  HBASE-13798 TestFromClientSide* don't close the Table
7878389 is described below

commit 7878389669740c7da3689d56c7906881b834e0bf
Author: Andor Molnár <an...@cloudera.com>
AuthorDate: Wed May 15 17:28:41 2019 +0200

    HBASE-13798 TestFromClientSide* don't close the Table
---
 .../hadoop/hbase/client/TestFromClientSide.java    | 8086 ++++++++++----------
 .../hadoop/hbase/client/TestFromClientSide3.java   |  823 +-
 2 files changed, 4508 insertions(+), 4401 deletions(-)

diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
index 77b5f93..894f8a7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
@@ -182,29 +182,29 @@ public class TestFromClientSide {
     c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
 
     Connection connection = ConnectionFactory.createConnection(c);
-    Table t = connection.getTable(TableName.valueOf(name.getMethodName()));
-    if (t instanceof HTable) {
-      HTable table = (HTable) t;
-      table.setOperationTimeout(3 * 1000);
+    try (Table t = connection.getTable(TableName.valueOf(name.getMethodName()))) {
+      if (t instanceof HTable) {
+        HTable table = (HTable) t;
+        table.setOperationTimeout(3 * 1000);
 
-      try {
-        Append append = new Append(ROW);
-        append.addColumn(HBaseTestingUtility.fam1, QUALIFIER, VALUE);
-        Result result = table.append(append);
-
-        // Verify expected result
-        Cell[] cells = result.rawCells();
-        assertEquals(1, cells.length);
-        assertKey(cells[0], ROW, HBaseTestingUtility.fam1, QUALIFIER, VALUE);
-
-        // Verify expected result again
-        Result readResult = table.get(new Get(ROW));
-        cells = readResult.rawCells();
-        assertEquals(1, cells.length);
-        assertKey(cells[0], ROW, HBaseTestingUtility.fam1, QUALIFIER, VALUE);
-      } finally {
-        table.close();
-        connection.close();
+        try {
+          Append append = new Append(ROW);
+          append.addColumn(HBaseTestingUtility.fam1, QUALIFIER, VALUE);
+          Result result = table.append(append);
+
+          // Verify expected result
+          Cell[] cells = result.rawCells();
+          assertEquals(1, cells.length);
+          assertKey(cells[0], ROW, HBaseTestingUtility.fam1, QUALIFIER, VALUE);
+
+          // Verify expected result again
+          Result readResult = table.get(new Get(ROW));
+          cells = readResult.rawCells();
+          assertEquals(1, cells.length);
+          assertKey(cells[0], ROW, HBaseTestingUtility.fam1, QUALIFIER, VALUE);
+        } finally {
+          connection.close();
+        }
       }
     }
   }
@@ -227,53 +227,52 @@ public class TestFromClientSide {
     HTableDescriptor desc = new HTableDescriptor(tableName);
     desc.addFamily(hcd);
     TEST_UTIL.getAdmin().createTable(desc);
-    Table h = TEST_UTIL.getConnection().getTable(tableName);
-
-    long ts = System.currentTimeMillis();
-    Put p = new Put(T1, ts);
-    p.addColumn(FAMILY, C0, T1);
-    h.put(p);
-    p = new Put(T1, ts + 2);
-    p.addColumn(FAMILY, C0, T2);
-    h.put(p);
-    p = new Put(T1, ts + 4);
-    p.addColumn(FAMILY, C0, T3);
-    h.put(p);
-
-    Delete d = new Delete(T1, ts + 3);
-    h.delete(d);
-
-    d = new Delete(T1, ts + 3);
-    d.addColumns(FAMILY, C0, ts + 3);
-    h.delete(d);
-
-    Get g = new Get(T1);
-    // does *not* include the delete
-    g.setTimeRange(0, ts + 3);
-    Result r = h.get(g);
-    assertArrayEquals(T2, r.getValue(FAMILY, C0));
-
-    Scan s = new Scan(T1);
-    s.setTimeRange(0, ts + 3);
-    s.setMaxVersions();
-    ResultScanner scanner = h.getScanner(s);
-    Cell[] kvs = scanner.next().rawCells();
-    assertArrayEquals(T2, CellUtil.cloneValue(kvs[0]));
-    assertArrayEquals(T1, CellUtil.cloneValue(kvs[1]));
-    scanner.close();
-
-    s = new Scan(T1);
-    s.setRaw(true);
-    s.setMaxVersions();
-    scanner = h.getScanner(s);
-    kvs = scanner.next().rawCells();
-    assertTrue(PrivateCellUtil.isDeleteFamily(kvs[0]));
-    assertArrayEquals(T3, CellUtil.cloneValue(kvs[1]));
-    assertTrue(CellUtil.isDelete(kvs[2]));
-    assertArrayEquals(T2, CellUtil.cloneValue(kvs[3]));
-    assertArrayEquals(T1, CellUtil.cloneValue(kvs[4]));
-    scanner.close();
-    h.close();
+    try (Table h = TEST_UTIL.getConnection().getTable(tableName)) {
+      long ts = System.currentTimeMillis();
+      Put p = new Put(T1, ts);
+      p.addColumn(FAMILY, C0, T1);
+      h.put(p);
+      p = new Put(T1, ts + 2);
+      p.addColumn(FAMILY, C0, T2);
+      h.put(p);
+      p = new Put(T1, ts + 4);
+      p.addColumn(FAMILY, C0, T3);
+      h.put(p);
+
+      Delete d = new Delete(T1, ts + 3);
+      h.delete(d);
+
+      d = new Delete(T1, ts + 3);
+      d.addColumns(FAMILY, C0, ts + 3);
+      h.delete(d);
+
+      Get g = new Get(T1);
+      // does *not* include the delete
+      g.setTimeRange(0, ts + 3);
+      Result r = h.get(g);
+      assertArrayEquals(T2, r.getValue(FAMILY, C0));
+
+      Scan s = new Scan(T1);
+      s.setTimeRange(0, ts + 3);
+      s.setMaxVersions();
+      ResultScanner scanner = h.getScanner(s);
+      Cell[] kvs = scanner.next().rawCells();
+      assertArrayEquals(T2, CellUtil.cloneValue(kvs[0]));
+      assertArrayEquals(T1, CellUtil.cloneValue(kvs[1]));
+      scanner.close();
+
+      s = new Scan(T1);
+      s.setRaw(true);
+      s.setMaxVersions();
+      scanner = h.getScanner(s);
+      kvs = scanner.next().rawCells();
+      assertTrue(PrivateCellUtil.isDeleteFamily(kvs[0]));
+      assertArrayEquals(T3, CellUtil.cloneValue(kvs[1]));
+      assertTrue(CellUtil.isDelete(kvs[2]));
+      assertArrayEquals(T2, CellUtil.cloneValue(kvs[3]));
+      assertArrayEquals(T1, CellUtil.cloneValue(kvs[4]));
+      scanner.close();
+    }
   }
 
   /**
@@ -287,47 +286,45 @@ public class TestFromClientSide {
     final byte[] COLUMN = Bytes.toBytes("column");
     final byte[] VALUE = Bytes.toBytes("value");
 
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
-
-    // future timestamp
-    long ts = System.currentTimeMillis() * 2;
-    Put put = new Put(ROW, ts);
-    put.addColumn(FAMILY, COLUMN, VALUE);
-    table.put(put);
-
-    Get get = new Get(ROW);
-    Result result = table.get(get);
-    assertArrayEquals(VALUE, result.getValue(FAMILY, COLUMN));
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
+      // future timestamp
+      long ts = System.currentTimeMillis() * 2;
+      Put put = new Put(ROW, ts);
+      put.addColumn(FAMILY, COLUMN, VALUE);
+      table.put(put);
 
-    Delete del = new Delete(ROW);
-    del.addColumn(FAMILY, COLUMN, ts);
-    table.delete(del);
+      Get get = new Get(ROW);
+      Result result = table.get(get);
+      assertArrayEquals(VALUE, result.getValue(FAMILY, COLUMN));
 
-    get = new Get(ROW);
-    result = table.get(get);
-    assertNull(result.getValue(FAMILY, COLUMN));
+      Delete del = new Delete(ROW);
+      del.addColumn(FAMILY, COLUMN, ts);
+      table.delete(del);
 
-    // major compaction, purged future deletes
-    TEST_UTIL.getAdmin().flush(tableName);
-    TEST_UTIL.getAdmin().majorCompact(tableName);
+      get = new Get(ROW);
+      result = table.get(get);
+      assertNull(result.getValue(FAMILY, COLUMN));
 
-    // waiting for the major compaction to complete
-    TEST_UTIL.waitFor(6000, new Waiter.Predicate<IOException>() {
-      @Override
-      public boolean evaluate() throws IOException {
-        return TEST_UTIL.getAdmin().getCompactionState(tableName) == CompactionState.NONE;
-      }
-    });
+      // major compaction, purged future deletes
+      TEST_UTIL.getAdmin().flush(tableName);
+      TEST_UTIL.getAdmin().majorCompact(tableName);
 
-    put = new Put(ROW, ts);
-    put.addColumn(FAMILY, COLUMN, VALUE);
-    table.put(put);
+      // waiting for the major compaction to complete
+      TEST_UTIL.waitFor(6000, new Waiter.Predicate<IOException>() {
+        @Override
+        public boolean evaluate() throws IOException {
+          return TEST_UTIL.getAdmin().getCompactionState(tableName) == CompactionState.NONE;
+        }
+      });
 
-    get = new Get(ROW);
-    result = table.get(get);
-    assertArrayEquals(VALUE, result.getValue(FAMILY, COLUMN));
+      put = new Put(ROW, ts);
+      put.addColumn(FAMILY, COLUMN, VALUE);
+      table.put(put);
 
-    table.close();
+      get = new Get(ROW);
+      result = table.get(get);
+      assertArrayEquals(VALUE, result.getValue(FAMILY, COLUMN));
+    }
   }
 
   /**
@@ -339,8 +336,9 @@ public class TestFromClientSide {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     byte[][] FAMILIES = new byte[][] { Bytes.toBytes("foo") };
     Configuration conf = TEST_UTIL.getConfiguration();
-    Table table = TEST_UTIL.createTable(tableName, FAMILIES);
-    assertSame(conf, table.getConfiguration());
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILIES)) {
+      assertSame(conf, table.getConfiguration());
+    }
   }
 
   /**
@@ -353,38 +351,40 @@ public class TestFromClientSide {
     byte [][] FAMILIES = new byte[][] { Bytes.toBytes("trans-blob"),
         Bytes.toBytes("trans-type"), Bytes.toBytes("trans-date"),
         Bytes.toBytes("trans-tags"), Bytes.toBytes("trans-group") };
-    Table ht = TEST_UTIL.createTable(tableName, FAMILIES);
-    String value = "this is the value";
-    String value2 = "this is some other value";
-    String keyPrefix1 = TEST_UTIL.getRandomUUID().toString();
-    String keyPrefix2 = TEST_UTIL.getRandomUUID().toString();
-    String keyPrefix3 = TEST_UTIL.getRandomUUID().toString();
-    putRows(ht, 3, value, keyPrefix1);
-    putRows(ht, 3, value, keyPrefix2);
-    putRows(ht, 3, value, keyPrefix3);
-    putRows(ht, 3, value2, keyPrefix1);
-    putRows(ht, 3, value2, keyPrefix2);
-    putRows(ht, 3, value2, keyPrefix3);
-    Table table = TEST_UTIL.getConnection().getTable(tableName);
-    System.out.println("Checking values for key: " + keyPrefix1);
-    assertEquals("Got back incorrect number of rows from scan", 3,
-        getNumberOfRows(keyPrefix1, value2, table));
-    System.out.println("Checking values for key: " + keyPrefix2);
-    assertEquals("Got back incorrect number of rows from scan", 3,
-        getNumberOfRows(keyPrefix2, value2, table));
-    System.out.println("Checking values for key: " + keyPrefix3);
-    assertEquals("Got back incorrect number of rows from scan", 3,
-        getNumberOfRows(keyPrefix3, value2, table));
-    deleteColumns(ht, value2, keyPrefix1);
-    deleteColumns(ht, value2, keyPrefix2);
-    deleteColumns(ht, value2, keyPrefix3);
-    System.out.println("Starting important checks.....");
-    assertEquals("Got back incorrect number of rows from scan: " + keyPrefix1,
-      0, getNumberOfRows(keyPrefix1, value2, table));
-    assertEquals("Got back incorrect number of rows from scan: " + keyPrefix2,
-      0, getNumberOfRows(keyPrefix2, value2, table));
-    assertEquals("Got back incorrect number of rows from scan: " + keyPrefix3,
-      0, getNumberOfRows(keyPrefix3, value2, table));
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES)) {
+      String value = "this is the value";
+      String value2 = "this is some other value";
+      String keyPrefix1 = TEST_UTIL.getRandomUUID().toString();
+      String keyPrefix2 = TEST_UTIL.getRandomUUID().toString();
+      String keyPrefix3 = TEST_UTIL.getRandomUUID().toString();
+      putRows(ht, 3, value, keyPrefix1);
+      putRows(ht, 3, value, keyPrefix2);
+      putRows(ht, 3, value, keyPrefix3);
+      putRows(ht, 3, value2, keyPrefix1);
+      putRows(ht, 3, value2, keyPrefix2);
+      putRows(ht, 3, value2, keyPrefix3);
+      try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+        System.out.println("Checking values for key: " + keyPrefix1);
+        assertEquals("Got back incorrect number of rows from scan", 3,
+                getNumberOfRows(keyPrefix1, value2, table));
+        System.out.println("Checking values for key: " + keyPrefix2);
+        assertEquals("Got back incorrect number of rows from scan", 3,
+                getNumberOfRows(keyPrefix2, value2, table));
+        System.out.println("Checking values for key: " + keyPrefix3);
+        assertEquals("Got back incorrect number of rows from scan", 3,
+                getNumberOfRows(keyPrefix3, value2, table));
+        deleteColumns(ht, value2, keyPrefix1);
+        deleteColumns(ht, value2, keyPrefix2);
+        deleteColumns(ht, value2, keyPrefix3);
+        System.out.println("Starting important checks.....");
+        assertEquals("Got back incorrect number of rows from scan: " + keyPrefix1,
+                0, getNumberOfRows(keyPrefix1, value2, table));
+        assertEquals("Got back incorrect number of rows from scan: " + keyPrefix2,
+                0, getNumberOfRows(keyPrefix2, value2, table));
+        assertEquals("Got back incorrect number of rows from scan: " + keyPrefix3,
+                0, getNumberOfRows(keyPrefix3, value2, table));
+      }
+    }
   }
 
   private void deleteColumns(Table ht, String value, String keyPrefix)
@@ -475,53 +475,54 @@ public class TestFromClientSide {
   public void testFilterAcrossMultipleRegions()
   throws IOException, InterruptedException {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table t = TEST_UTIL.createTable(tableName, FAMILY);
-    int rowCount = TEST_UTIL.loadTable(t, FAMILY, false);
-    assertRowCount(t, rowCount);
-    // Split the table.  Should split on a reasonable key; 'lqj'
-    List<HRegionLocation> regions  = splitTable(t);
-    assertRowCount(t, rowCount);
-    // Get end key of first region.
-    byte [] endKey = regions.get(0).getRegionInfo().getEndKey();
-    // Count rows with a filter that stops us before passed 'endKey'.
-    // Should be count of rows in first region.
-    int endKeyCount = TEST_UTIL.countRows(t, createScanWithRowFilter(endKey));
-    assertTrue(endKeyCount < rowCount);
-
-    // How do I know I did not got to second region?  Thats tough.  Can't really
-    // do that in client-side region test.  I verified by tracing in debugger.
-    // I changed the messages that come out when set to DEBUG so should see
-    // when scanner is done. Says "Finished with scanning..." with region name.
-    // Check that its finished in right region.
-
-    // New test.  Make it so scan goes into next region by one and then two.
-    // Make sure count comes out right.
-    byte [] key = new byte [] {endKey[0], endKey[1], (byte)(endKey[2] + 1)};
-    int plusOneCount = TEST_UTIL.countRows(t, createScanWithRowFilter(key));
-    assertEquals(endKeyCount + 1, plusOneCount);
-    key = new byte [] {endKey[0], endKey[1], (byte)(endKey[2] + 2)};
-    int plusTwoCount = TEST_UTIL.countRows(t, createScanWithRowFilter(key));
-    assertEquals(endKeyCount + 2, plusTwoCount);
-
-    // New test.  Make it so I scan one less than endkey.
-    key = new byte [] {endKey[0], endKey[1], (byte)(endKey[2] - 1)};
-    int minusOneCount = TEST_UTIL.countRows(t, createScanWithRowFilter(key));
-    assertEquals(endKeyCount - 1, minusOneCount);
-    // For above test... study logs.  Make sure we do "Finished with scanning.."
-    // in first region and that we do not fall into the next region.
-
-    key = new byte [] {'a', 'a', 'a'};
-    int countBBB = TEST_UTIL.countRows(t,
-      createScanWithRowFilter(key, null, CompareOperator.EQUAL));
-    assertEquals(1, countBBB);
-
-    int countGreater = TEST_UTIL.countRows(t, createScanWithRowFilter(endKey, null,
-      CompareOperator.GREATER_OR_EQUAL));
-    // Because started at start of table.
-    assertEquals(0, countGreater);
-    countGreater = TEST_UTIL.countRows(t, createScanWithRowFilter(endKey, endKey,
-      CompareOperator.GREATER_OR_EQUAL));
-    assertEquals(rowCount - endKeyCount, countGreater);
+    try (Table t = TEST_UTIL.createTable(tableName, FAMILY)) {
+      int rowCount = TEST_UTIL.loadTable(t, FAMILY, false);
+      assertRowCount(t, rowCount);
+      // Split the table.  Should split on a reasonable key; 'lqj'
+      List<HRegionLocation> regions = splitTable(t);
+      assertRowCount(t, rowCount);
+      // Get end key of first region.
+      byte[] endKey = regions.get(0).getRegionInfo().getEndKey();
+      // Count rows with a filter that stops us before passed 'endKey'.
+      // Should be count of rows in first region.
+      int endKeyCount = TEST_UTIL.countRows(t, createScanWithRowFilter(endKey));
+      assertTrue(endKeyCount < rowCount);
+
+      // How do I know I did not got to second region?  Thats tough.  Can't really
+      // do that in client-side region test.  I verified by tracing in debugger.
+      // I changed the messages that come out when set to DEBUG so should see
+      // when scanner is done. Says "Finished with scanning..." with region name.
+      // Check that its finished in right region.
+
+      // New test.  Make it so scan goes into next region by one and then two.
+      // Make sure count comes out right.
+      byte[] key = new byte[]{endKey[0], endKey[1], (byte) (endKey[2] + 1)};
+      int plusOneCount = TEST_UTIL.countRows(t, createScanWithRowFilter(key));
+      assertEquals(endKeyCount + 1, plusOneCount);
+      key = new byte[]{endKey[0], endKey[1], (byte) (endKey[2] + 2)};
+      int plusTwoCount = TEST_UTIL.countRows(t, createScanWithRowFilter(key));
+      assertEquals(endKeyCount + 2, plusTwoCount);
+
+      // New test.  Make it so I scan one less than endkey.
+      key = new byte[]{endKey[0], endKey[1], (byte) (endKey[2] - 1)};
+      int minusOneCount = TEST_UTIL.countRows(t, createScanWithRowFilter(key));
+      assertEquals(endKeyCount - 1, minusOneCount);
+      // For above test... study logs.  Make sure we do "Finished with scanning.."
+      // in first region and that we do not fall into the next region.
+
+      key = new byte[]{'a', 'a', 'a'};
+      int countBBB = TEST_UTIL.countRows(t,
+              createScanWithRowFilter(key, null, CompareOperator.EQUAL));
+      assertEquals(1, countBBB);
+
+      int countGreater = TEST_UTIL.countRows(t, createScanWithRowFilter(endKey, null,
+              CompareOperator.GREATER_OR_EQUAL));
+      // Because started at start of table.
+      assertEquals(0, countGreater);
+      countGreater = TEST_UTIL.countRows(t, createScanWithRowFilter(endKey, endKey,
+              CompareOperator.GREATER_OR_EQUAL));
+      assertEquals(rowCount - endKeyCount, countGreater);
+    }
   }
 
   /*
@@ -602,16 +603,17 @@ public class TestFromClientSide {
   @Test
   public void testSuperSimple() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    Scan scan = new Scan();
-    scan.addColumn(FAMILY, tableName.toBytes());
-    ResultScanner scanner = ht.getScanner(scan);
-    Result result = scanner.next();
-    assertTrue("Expected null result", result == null);
-    scanner.close();
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      Scan scan = new Scan();
+      scan.addColumn(FAMILY, tableName.toBytes());
+      ResultScanner scanner = ht.getScanner(scan);
+      Result result = scanner.next();
+      assertTrue("Expected null result", result == null);
+      scanner.close();
+    }
   }
 
   @Test
@@ -619,127 +621,133 @@ public class TestFromClientSide {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     Configuration conf = TEST_UTIL.getConfiguration();
     String oldMaxSize = conf.get(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY);
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte[] value = new byte[4 * 1024 * 1024];
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, value);
-    ht.put(put);
-    try {
-      TEST_UTIL.getConfiguration().setInt(
-          ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, 2 * 1024 * 1024);
-      // Create new table so we pick up the change in Configuration.
-      try (Connection connection =
-          ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
-        try (Table t = connection.getTable(TableName.valueOf(FAMILY))) {
-          put = new Put(ROW);
-          put.addColumn(FAMILY, QUALIFIER, value);
-          t.put(put);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[] value = new byte[4 * 1024 * 1024];
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, value);
+      ht.put(put);
+
+      try {
+        TEST_UTIL.getConfiguration().setInt(
+                ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, 2 * 1024 * 1024);
+        // Create new table so we pick up the change in Configuration.
+        try (Connection connection =
+                     ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
+          try (Table t = connection.getTable(TableName.valueOf(FAMILY))) {
+            put = new Put(ROW);
+            put.addColumn(FAMILY, QUALIFIER, value);
+            t.put(put);
+          }
         }
+        fail("Inserting a too large KeyValue worked, should throw exception");
+      } catch (Exception e) {
       }
-      fail("Inserting a too large KeyValue worked, should throw exception");
-    } catch(Exception e) {}
+    }
     conf.set(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY, oldMaxSize);
   }
 
   @Test
   public void testFilters() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte [][] ROWS = makeN(ROW, 10);
-    byte [][] QUALIFIERS = {
-        Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>")
-    };
-    for(int i=0;i<10;i++) {
-      Put put = new Put(ROWS[i]);
-      put.setDurability(Durability.SKIP_WAL);
-      put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
-      ht.put(put);
-    }
-    Scan scan = new Scan();
-    scan.addFamily(FAMILY);
-    Filter filter = new QualifierFilter(CompareOperator.EQUAL,
-      new RegexStringComparator("col[1-5]"));
-    scan.setFilter(filter);
-    ResultScanner scanner = ht.getScanner(scan);
-    int expectedIndex = 1;
-    for(Result result : ht.getScanner(scan)) {
-      assertEquals(1, result.size());
-      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[expectedIndex]));
-      assertTrue(Bytes.equals(CellUtil.cloneQualifier(result.rawCells()[0]),
-          QUALIFIERS[expectedIndex]));
-      expectedIndex++;
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 10);
+      byte[][] QUALIFIERS = {
+              Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>")
+      };
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(ROWS[i]);
+        put.setDurability(Durability.SKIP_WAL);
+        put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
+        ht.put(put);
+      }
+      Scan scan = new Scan();
+      scan.addFamily(FAMILY);
+      Filter filter = new QualifierFilter(CompareOperator.EQUAL,
+              new RegexStringComparator("col[1-5]"));
+      scan.setFilter(filter);
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int expectedIndex = 1;
+        for (Result result : scanner) {
+          assertEquals(1, result.size());
+          assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[expectedIndex]));
+          assertTrue(Bytes.equals(CellUtil.cloneQualifier(result.rawCells()[0]),
+                  QUALIFIERS[expectedIndex]));
+          expectedIndex++;
+        }
+        assertEquals(6, expectedIndex);
+      }
     }
-    assertEquals(6, expectedIndex);
-    scanner.close();
   }
 
   @Test
   public void testFilterWithLongCompartor() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte [][] ROWS = makeN(ROW, 10);
-    byte [][] values = new byte[10][];
-    for (int i = 0; i < 10; i ++) {
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 10);
+      byte[][] values = new byte[10][];
+      for (int i = 0; i < 10; i++) {
         values[i] = Bytes.toBytes(100L * i);
+      }
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(ROWS[i]);
+        put.setDurability(Durability.SKIP_WAL);
+        put.addColumn(FAMILY, QUALIFIER, values[i]);
+        ht.put(put);
+      }
+      Scan scan = new Scan();
+      scan.addFamily(FAMILY);
+      Filter filter = new SingleColumnValueFilter(FAMILY, QUALIFIER, CompareOperator.GREATER,
+              new LongComparator(500));
+      scan.setFilter(filter);
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int expectedIndex = 0;
+        for (Result result : scanner) {
+          assertEquals(1, result.size());
+          assertTrue(Bytes.toLong(result.getValue(FAMILY, QUALIFIER)) > 500);
+          expectedIndex++;
+        }
+        assertEquals(4, expectedIndex);
+      }
     }
-    for(int i = 0; i < 10; i ++) {
-      Put put = new Put(ROWS[i]);
-      put.setDurability(Durability.SKIP_WAL);
-      put.addColumn(FAMILY, QUALIFIER, values[i]);
-      ht.put(put);
-    }
-    Scan scan = new Scan();
-    scan.addFamily(FAMILY);
-    Filter filter = new SingleColumnValueFilter(FAMILY, QUALIFIER, CompareOperator.GREATER,
-      new LongComparator(500));
-    scan.setFilter(filter);
-    ResultScanner scanner = ht.getScanner(scan);
-    int expectedIndex = 0;
-    for(Result result : ht.getScanner(scan)) {
-      assertEquals(1, result.size());
-      assertTrue(Bytes.toLong(result.getValue(FAMILY, QUALIFIER)) > 500);
-      expectedIndex++;
-    }
-    assertEquals(4, expectedIndex);
-    scanner.close();
-}
+  }
 
   @Test
   public void testKeyOnlyFilter() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte [][] ROWS = makeN(ROW, 10);
-    byte [][] QUALIFIERS = {
-        Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>")
-    };
-    for(int i=0;i<10;i++) {
-      Put put = new Put(ROWS[i]);
-      put.setDurability(Durability.SKIP_WAL);
-      put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
-      ht.put(put);
-    }
-    Scan scan = new Scan();
-    scan.addFamily(FAMILY);
-    Filter filter = new KeyOnlyFilter(true);
-    scan.setFilter(filter);
-    ResultScanner scanner = ht.getScanner(scan);
-    int count = 0;
-    for(Result result : ht.getScanner(scan)) {
-      assertEquals(1, result.size());
-      assertEquals(Bytes.SIZEOF_INT, result.rawCells()[0].getValueLength());
-      assertEquals(VALUE.length, Bytes.toInt(CellUtil.cloneValue(result.rawCells()[0])));
-      count++;
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 10);
+      byte[][] QUALIFIERS = {
+              Bytes.toBytes("col0-<d2v1>-<d3v2>"), Bytes.toBytes("col1-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col2-<d2v1>-<d3v2>"), Bytes.toBytes("col3-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col4-<d2v1>-<d3v2>"), Bytes.toBytes("col5-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col6-<d2v1>-<d3v2>"), Bytes.toBytes("col7-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col8-<d2v1>-<d3v2>"), Bytes.toBytes("col9-<d2v1>-<d3v2>")
+      };
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(ROWS[i]);
+        put.setDurability(Durability.SKIP_WAL);
+        put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
+        ht.put(put);
+      }
+      Scan scan = new Scan();
+      scan.addFamily(FAMILY);
+      Filter filter = new KeyOnlyFilter(true);
+      scan.setFilter(filter);
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int count = 0;
+        for (Result result : scanner) {
+          assertEquals(1, result.size());
+          assertEquals(Bytes.SIZEOF_INT, result.rawCells()[0].getValueLength());
+          assertEquals(VALUE.length, Bytes.toInt(CellUtil.cloneValue(result.rawCells()[0])));
+          count++;
+        }
+        assertEquals(10, count);
+      }
     }
-    assertEquals(10, count);
-    scanner.close();
   }
 
   /**
@@ -748,108 +756,108 @@ public class TestFromClientSide {
   @Test
   public void testSimpleMissing() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte [][] ROWS = makeN(ROW, 4);
-
-    // Try to get a row on an empty table
-    Get get = new Get(ROWS[0]);
-    Result result = ht.get(get);
-    assertEmptyResult(result);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 4);
 
-    get = new Get(ROWS[0]);
-    get.addFamily(FAMILY);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      // Try to get a row on an empty table
+      Get get = new Get(ROWS[0]);
+      Result result = ht.get(get);
+      assertEmptyResult(result);
 
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILY, QUALIFIER);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      get = new Get(ROWS[0]);
+      get.addFamily(FAMILY);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    Scan scan = new Scan();
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILY, QUALIFIER);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
+      Scan scan = new Scan();
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan(ROWS[0]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan(ROWS[0]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan(ROWS[0],ROWS[1]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan(ROWS[0], ROWS[1]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan();
-    scan.addFamily(FAMILY);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan();
+      scan.addFamily(FAMILY);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan();
-    scan.addColumn(FAMILY, QUALIFIER);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan();
+      scan.addColumn(FAMILY, QUALIFIER);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    // Insert a row
+      // Insert a row
 
-    Put put = new Put(ROWS[2]);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
+      Put put = new Put(ROWS[2]);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
 
-    // Try to get empty rows around it
+      // Try to get empty rows around it
 
-    get = new Get(ROWS[1]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      get = new Get(ROWS[1]);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    get = new Get(ROWS[0]);
-    get.addFamily(FAMILY);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      get = new Get(ROWS[0]);
+      get.addFamily(FAMILY);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    get = new Get(ROWS[3]);
-    get.addColumn(FAMILY, QUALIFIER);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      get = new Get(ROWS[3]);
+      get.addColumn(FAMILY, QUALIFIER);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    // Try to scan empty rows around it
+      // Try to scan empty rows around it
 
-    scan = new Scan(ROWS[3]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan(ROWS[3]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan(ROWS[0],ROWS[2]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan(ROWS[0], ROWS[2]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    // Make sure we can actually get the row
+      // Make sure we can actually get the row
 
-    get = new Get(ROWS[2]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      get = new Get(ROWS[2]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    get = new Get(ROWS[2]);
-    get.addFamily(FAMILY);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      get = new Get(ROWS[2]);
+      get.addFamily(FAMILY);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    get = new Get(ROWS[2]);
-    get.addColumn(FAMILY, QUALIFIER);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      get = new Get(ROWS[2]);
+      get.addColumn(FAMILY, QUALIFIER);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    // Make sure we can scan the row
+      // Make sure we can scan the row
 
-    scan = new Scan();
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      scan = new Scan();
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    scan = new Scan(ROWS[0],ROWS[3]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      scan = new Scan(ROWS[0], ROWS[3]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    scan = new Scan(ROWS[2],ROWS[3]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      scan = new Scan(ROWS[2], ROWS[3]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+    }
   }
 
   /**
@@ -864,297 +872,297 @@ public class TestFromClientSide {
     byte [][] QUALIFIERS = makeN(QUALIFIER, 10);
     byte [][] VALUES = makeN(VALUE, 10);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILIES);
-
-    Get get;
-    Scan scan;
-    Delete delete;
-    Put put;
-    Result result;
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Insert one column to one family
-    ////////////////////////////////////////////////////////////////////////////
-
-    put = new Put(ROWS[0]);
-    put.addColumn(FAMILIES[4], QUALIFIERS[0], VALUES[0]);
-    ht.put(put);
-
-    // Get the single column
-    getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
-
-    // Scan the single column
-    scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
-
-    // Get empty results around inserted column
-    getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
-
-    // Scan empty results around inserted column
-    scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Flush memstore and run same tests from storefiles
-    ////////////////////////////////////////////////////////////////////////////
-
-    TEST_UTIL.flush();
-
-    // Redo get and scan tests from storefile
-    getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
-    scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
-    getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
-    scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Now, Test reading from memstore and storefiles at once
-    ////////////////////////////////////////////////////////////////////////////
-
-    // Insert multiple columns to two other families
-    put = new Put(ROWS[0]);
-    put.addColumn(FAMILIES[2], QUALIFIERS[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIERS[4], VALUES[4]);
-    put.addColumn(FAMILIES[4], QUALIFIERS[4], VALUES[4]);
-    put.addColumn(FAMILIES[6], QUALIFIERS[6], VALUES[6]);
-    put.addColumn(FAMILIES[6], QUALIFIERS[7], VALUES[7]);
-    put.addColumn(FAMILIES[7], QUALIFIERS[7], VALUES[7]);
-    put.addColumn(FAMILIES[9], QUALIFIERS[0], VALUES[0]);
-    ht.put(put);
-
-    // Get multiple columns across multiple families and get empties around it
-    singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
-
-    // Scan multiple columns across multiple families and scan empties around it
-    singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Flush the table again
-    ////////////////////////////////////////////////////////////////////////////
-
-    TEST_UTIL.flush();
-
-    // Redo tests again
-    singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
-    singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
-
-    // Insert more data to memstore
-    put = new Put(ROWS[0]);
-    put.addColumn(FAMILIES[6], QUALIFIERS[5], VALUES[5]);
-    put.addColumn(FAMILIES[6], QUALIFIERS[8], VALUES[8]);
-    put.addColumn(FAMILIES[6], QUALIFIERS[9], VALUES[9]);
-    put.addColumn(FAMILIES[4], QUALIFIERS[3], VALUES[3]);
-    ht.put(put);
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Delete a storefile column
-    ////////////////////////////////////////////////////////////////////////////
-    delete = new Delete(ROWS[0]);
-    delete.addColumns(FAMILIES[6], QUALIFIERS[7]);
-    ht.delete(delete);
-
-    // Try to get deleted column
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[7]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES)) {
 
-    // Try to scan deleted column
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[7]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      Get get;
+      Scan scan;
+      Delete delete;
+      Put put;
+      Result result;
 
-    // Make sure we can still get a column before it and after it
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[6]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      ////////////////////////////////////////////////////////////////////////////
+      // Insert one column to one family
+      ////////////////////////////////////////////////////////////////////////////
 
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[8]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]);
+      put = new Put(ROWS[0]);
+      put.addColumn(FAMILIES[4], QUALIFIERS[0], VALUES[0]);
+      ht.put(put);
 
-    // Make sure we can still scan a column before it and after it
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      // Get the single column
+      getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
 
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[8]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]);
+      // Scan the single column
+      scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
 
-    ////////////////////////////////////////////////////////////////////////////
-    // Delete a memstore column
-    ////////////////////////////////////////////////////////////////////////////
-    delete = new Delete(ROWS[0]);
-    delete.addColumns(FAMILIES[6], QUALIFIERS[8]);
-    ht.delete(delete);
+      // Get empty results around inserted column
+      getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
 
-    // Try to get deleted column
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[8]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      // Scan empty results around inserted column
+      scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
 
-    // Try to scan deleted column
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[8]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      ////////////////////////////////////////////////////////////////////////////
+      // Flush memstore and run same tests from storefiles
+      ////////////////////////////////////////////////////////////////////////////
 
-    // Make sure we can still get a column before it and after it
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[6]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      TEST_UTIL.flush();
 
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[9]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      // Redo get and scan tests from storefile
+      getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
+      scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
+      getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
+      scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
+
+      ////////////////////////////////////////////////////////////////////////////
+      // Now, Test reading from memstore and storefiles at once
+      ////////////////////////////////////////////////////////////////////////////
+
+      // Insert multiple columns to two other families
+      put = new Put(ROWS[0]);
+      put.addColumn(FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIERS[4], VALUES[4]);
+      put.addColumn(FAMILIES[4], QUALIFIERS[4], VALUES[4]);
+      put.addColumn(FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      put.addColumn(FAMILIES[6], QUALIFIERS[7], VALUES[7]);
+      put.addColumn(FAMILIES[7], QUALIFIERS[7], VALUES[7]);
+      put.addColumn(FAMILIES[9], QUALIFIERS[0], VALUES[0]);
+      ht.put(put);
 
-    // Make sure we can still scan a column before it and after it
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      // Get multiple columns across multiple families and get empties around it
+      singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
 
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      // Scan multiple columns across multiple families and scan empties around it
+      singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
 
-    ////////////////////////////////////////////////////////////////////////////
-    // Delete joint storefile/memstore family
-    ////////////////////////////////////////////////////////////////////////////
+      ////////////////////////////////////////////////////////////////////////////
+      // Flush the table again
+      ////////////////////////////////////////////////////////////////////////////
 
-    delete = new Delete(ROWS[0]);
-    delete.addFamily(FAMILIES[4]);
-    ht.delete(delete);
+      TEST_UTIL.flush();
 
-    // Try to get storefile column in deleted family
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[4], QUALIFIERS[4]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      // Redo tests again
+      singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
+      singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
 
-    // Try to get memstore column in deleted family
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[4], QUALIFIERS[3]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      // Insert more data to memstore
+      put = new Put(ROWS[0]);
+      put.addColumn(FAMILIES[6], QUALIFIERS[5], VALUES[5]);
+      put.addColumn(FAMILIES[6], QUALIFIERS[8], VALUES[8]);
+      put.addColumn(FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      put.addColumn(FAMILIES[4], QUALIFIERS[3], VALUES[3]);
+      ht.put(put);
 
-    // Try to get deleted family
-    get = new Get(ROWS[0]);
-    get.addFamily(FAMILIES[4]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      ////////////////////////////////////////////////////////////////////////////
+      // Delete a storefile column
+      ////////////////////////////////////////////////////////////////////////////
+      delete = new Delete(ROWS[0]);
+      delete.addColumns(FAMILIES[6], QUALIFIERS[7]);
+      ht.delete(delete);
 
-    // Try to scan storefile column in deleted family
-    scan = new Scan();
-    scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      // Try to get deleted column
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[7]);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    // Try to scan memstore column in deleted family
-    scan = new Scan();
-    scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      // Try to scan deleted column
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[7]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    // Try to scan deleted family
-    scan = new Scan();
-    scan.addFamily(FAMILIES[4]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      // Make sure we can still get a column before it and after it
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[6]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
 
-    // Make sure we can still get another family
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[2], QUALIFIERS[2]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[8]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]);
 
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[9]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      // Make sure we can still scan a column before it and after it
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
 
-    // Make sure we can still scan another family
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[8]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]);
 
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      ////////////////////////////////////////////////////////////////////////////
+      // Delete a memstore column
+      ////////////////////////////////////////////////////////////////////////////
+      delete = new Delete(ROWS[0]);
+      delete.addColumns(FAMILIES[6], QUALIFIERS[8]);
+      ht.delete(delete);
 
-    ////////////////////////////////////////////////////////////////////////////
-    // Flush everything and rerun delete tests
-    ////////////////////////////////////////////////////////////////////////////
+      // Try to get deleted column
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[8]);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    TEST_UTIL.flush();
+      // Try to scan deleted column
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[8]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    // Try to get storefile column in deleted family
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[4], QUALIFIERS[4]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      // Make sure we can still get a column before it and after it
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[6]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
 
-    // Try to get memstore column in deleted family
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[4], QUALIFIERS[3]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[9]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
 
-    // Try to get deleted family
-    get = new Get(ROWS[0]);
-    get.addFamily(FAMILIES[4]);
-    result = ht.get(get);
-    assertEmptyResult(result);
+      // Make sure we can still scan a column before it and after it
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
 
-    // Try to scan storefile column in deleted family
-    scan = new Scan();
-    scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
 
-    // Try to scan memstore column in deleted family
-    scan = new Scan();
-    scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      ////////////////////////////////////////////////////////////////////////////
+      // Delete joint storefile/memstore family
+      ////////////////////////////////////////////////////////////////////////////
 
-    // Try to scan deleted family
-    scan = new Scan();
-    scan.addFamily(FAMILIES[4]);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      delete = new Delete(ROWS[0]);
+      delete.addFamily(FAMILIES[4]);
+      ht.delete(delete);
 
-    // Make sure we can still get another family
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[2], QUALIFIERS[2]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+      // Try to get storefile column in deleted family
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[4], QUALIFIERS[4]);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    get = new Get(ROWS[0]);
-    get.addColumn(FAMILIES[6], QUALIFIERS[9]);
-    result = ht.get(get);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      // Try to get memstore column in deleted family
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[4], QUALIFIERS[3]);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    // Make sure we can still scan another family
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+      // Try to get deleted family
+      get = new Get(ROWS[0]);
+      get.addFamily(FAMILIES[4]);
+      result = ht.get(get);
+      assertEmptyResult(result);
 
-    scan = new Scan();
-    scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+      // Try to scan storefile column in deleted family
+      scan = new Scan();
+      scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+
+      // Try to scan memstore column in deleted family
+      scan = new Scan();
+      scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+
+      // Try to scan deleted family
+      scan = new Scan();
+      scan.addFamily(FAMILIES[4]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+
+      // Make sure we can still get another family
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[2], QUALIFIERS[2]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[9]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+      // Make sure we can still scan another family
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+      ////////////////////////////////////////////////////////////////////////////
+      // Flush everything and rerun delete tests
+      ////////////////////////////////////////////////////////////////////////////
+
+      TEST_UTIL.flush();
 
+      // Try to get storefile column in deleted family
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[4], QUALIFIERS[4]);
+      result = ht.get(get);
+      assertEmptyResult(result);
+
+      // Try to get memstore column in deleted family
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[4], QUALIFIERS[3]);
+      result = ht.get(get);
+      assertEmptyResult(result);
+
+      // Try to get deleted family
+      get = new Get(ROWS[0]);
+      get.addFamily(FAMILIES[4]);
+      result = ht.get(get);
+      assertEmptyResult(result);
+
+      // Try to scan storefile column in deleted family
+      scan = new Scan();
+      scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+
+      // Try to scan memstore column in deleted family
+      scan = new Scan();
+      scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+
+      // Try to scan deleted family
+      scan = new Scan();
+      scan.addFamily(FAMILIES[4]);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+
+      // Make sure we can still get another family
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[2], QUALIFIERS[2]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+
+      get = new Get(ROWS[0]);
+      get.addColumn(FAMILIES[6], QUALIFIERS[9]);
+      result = ht.get(get);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+      // Make sure we can still scan another family
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+      scan = new Scan();
+      scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+    }
   }
 
   @Test
@@ -1173,365 +1181,382 @@ public class TestFromClientSide {
       fail("Creating a table with a null family passed, should fail");
     } catch(Exception e) {}
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
 
-    // Null row (should NOT work)
-    try {
-      Put put = new Put((byte[])null);
-      put.addColumn(FAMILY, QUALIFIER, VALUE);
-      ht.put(put);
-      fail("Inserting a null row worked, should throw exception");
-    } catch(Exception e) {}
+      // Null row (should NOT work)
+      try {
+        Put put = new Put((byte[]) null);
+        put.addColumn(FAMILY, QUALIFIER, VALUE);
+        ht.put(put);
+        fail("Inserting a null row worked, should throw exception");
+      } catch (Exception e) {
+      }
 
-    // Null qualifier (should work)
-    {
-      Put put = new Put(ROW);
-      put.addColumn(FAMILY, null, VALUE);
-      ht.put(put);
+      // Null qualifier (should work)
+      {
+        Put put = new Put(ROW);
+        put.addColumn(FAMILY, null, VALUE);
+        ht.put(put);
 
-      getTestNull(ht, ROW, FAMILY, VALUE);
+        getTestNull(ht, ROW, FAMILY, VALUE);
 
-      scanTestNull(ht, ROW, FAMILY, VALUE);
+        scanTestNull(ht, ROW, FAMILY, VALUE);
 
-      Delete delete = new Delete(ROW);
-      delete.addColumns(FAMILY, null);
-      ht.delete(delete);
+        Delete delete = new Delete(ROW);
+        delete.addColumns(FAMILY, null);
+        ht.delete(delete);
 
-      Get get = new Get(ROW);
-      Result result = ht.get(get);
-      assertEmptyResult(result);
+        Get get = new Get(ROW);
+        Result result = ht.get(get);
+        assertEmptyResult(result);
+      }
     }
 
     // Use a new table
-    ht = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName() + "2"), FAMILY);
+    try (Table ht = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName() + "2"), FAMILY)) {
 
-    // Empty qualifier, byte[0] instead of null (should work)
-    try {
-      Put put = new Put(ROW);
-      put.addColumn(FAMILY, HConstants.EMPTY_BYTE_ARRAY, VALUE);
-      ht.put(put);
+      // Empty qualifier, byte[0] instead of null (should work)
+      try {
+        Put put = new Put(ROW);
+        put.addColumn(FAMILY, HConstants.EMPTY_BYTE_ARRAY, VALUE);
+        ht.put(put);
 
-      getTestNull(ht, ROW, FAMILY, VALUE);
+        getTestNull(ht, ROW, FAMILY, VALUE);
 
-      scanTestNull(ht, ROW, FAMILY, VALUE);
+        scanTestNull(ht, ROW, FAMILY, VALUE);
 
-      // Flush and try again
+        // Flush and try again
 
-      TEST_UTIL.flush();
+        TEST_UTIL.flush();
 
-      getTestNull(ht, ROW, FAMILY, VALUE);
+        getTestNull(ht, ROW, FAMILY, VALUE);
 
-      scanTestNull(ht, ROW, FAMILY, VALUE);
+        scanTestNull(ht, ROW, FAMILY, VALUE);
 
-      Delete delete = new Delete(ROW);
-      delete.addColumns(FAMILY, HConstants.EMPTY_BYTE_ARRAY);
-      ht.delete(delete);
+        Delete delete = new Delete(ROW);
+        delete.addColumns(FAMILY, HConstants.EMPTY_BYTE_ARRAY);
+        ht.delete(delete);
 
-      Get get = new Get(ROW);
-      Result result = ht.get(get);
-      assertEmptyResult(result);
+        Get get = new Get(ROW);
+        Result result = ht.get(get);
+        assertEmptyResult(result);
+
+      } catch (Exception e) {
+        throw new IOException("Using a row with null qualifier threw exception, should ");
+      }
 
-    } catch(Exception e) {
-      throw new IOException("Using a row with null qualifier threw exception, should ");
+      // Null value
+      try {
+        Put put = new Put(ROW);
+        put.addColumn(FAMILY, QUALIFIER, null);
+        ht.put(put);
+
+        Get get = new Get(ROW);
+        get.addColumn(FAMILY, QUALIFIER);
+        Result result = ht.get(get);
+        assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+
+        Scan scan = new Scan();
+        scan.addColumn(FAMILY, QUALIFIER);
+        result = getSingleScanResult(ht, scan);
+        assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+
+        Delete delete = new Delete(ROW);
+        delete.addColumns(FAMILY, QUALIFIER);
+        ht.delete(delete);
+
+        get = new Get(ROW);
+        result = ht.get(get);
+        assertEmptyResult(result);
+
+      } catch (Exception e) {
+        throw new IOException("Null values should be allowed, but threw exception");
+      }
     }
+  }
 
-    // Null value
-    try {
-      Put put = new Put(ROW);
-      put.addColumn(FAMILY, QUALIFIER, null);
-      ht.put(put);
+  @Test
+  public void testNullQualifier() throws Exception {
+    final TableName tableName = TableName.valueOf(name.getMethodName());
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
 
-      Get get = new Get(ROW);
-      get.addColumn(FAMILY, QUALIFIER);
-      Result result = ht.get(get);
-      assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+      // Work for Put
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, null, VALUE);
+      table.put(put);
 
-      Scan scan = new Scan();
-      scan.addColumn(FAMILY, QUALIFIER);
-      result = getSingleScanResult(ht, scan);
-      assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+      // Work for Get, Scan
+      getTestNull(table, ROW, FAMILY, VALUE);
+      scanTestNull(table, ROW, FAMILY, VALUE);
 
+      // Work for Delete
       Delete delete = new Delete(ROW);
-      delete.addColumns(FAMILY, QUALIFIER);
-      ht.delete(delete);
+      delete.addColumns(FAMILY, null);
+      table.delete(delete);
 
-      get = new Get(ROW);
-      result = ht.get(get);
+      Get get = new Get(ROW);
+      Result result = table.get(get);
       assertEmptyResult(result);
 
-    } catch(Exception e) {
-      throw new IOException("Null values should be allowed, but threw exception");
+      // Work for Increment/Append
+      Increment increment = new Increment(ROW);
+      increment.addColumn(FAMILY, null, 1L);
+      table.increment(increment);
+      getTestNull(table, ROW, FAMILY, 1L);
+
+      table.incrementColumnValue(ROW, FAMILY, null, 1L);
+      getTestNull(table, ROW, FAMILY, 2L);
+
+      delete = new Delete(ROW);
+      delete.addColumns(FAMILY, null);
+      table.delete(delete);
+
+      Append append = new Append(ROW);
+      append.addColumn(FAMILY, null, VALUE);
+      table.append(append);
+      getTestNull(table, ROW, FAMILY, VALUE);
+
+      // Work for checkAndMutate using thenPut, thenMutate and thenDelete
+      put = new Put(ROW);
+      put.addColumn(FAMILY, null, Bytes.toBytes("checkAndPut"));
+      table.put(put);
+      table.checkAndMutate(ROW, FAMILY).ifEquals(VALUE).thenPut(put);
+
+      RowMutations mutate = new RowMutations(ROW);
+      mutate.add(new Put(ROW).addColumn(FAMILY, null, Bytes.toBytes("checkAndMutate")));
+      table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndPut")).thenMutate(mutate);
+
+      delete = new Delete(ROW);
+      delete.addColumns(FAMILY, null);
+      table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndMutate"))
+              .thenDelete(delete);
     }
   }
 
   @Test
-  public void testNullQualifier() throws Exception {
+  public void testVersions() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
 
-    // Work for Put
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, null, VALUE);
-    table.put(put);
+    long [] STAMPS = makeStamps(20);
+    byte [][] VALUES = makeNAscii(VALUE, 20);
 
-    // Work for Get, Scan
-    getTestNull(table, ROW, FAMILY, VALUE);
-    scanTestNull(table, ROW, FAMILY, VALUE);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    // Work for Delete
-    Delete delete = new Delete(ROW);
-    delete.addColumns(FAMILY, null);
-    table.delete(delete);
+      // Insert 4 versions of same column
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      ht.put(put);
 
-    Get get = new Get(ROW);
-    Result result = table.get(get);
-    assertEmptyResult(result);
+      // Verify we can get each one properly
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+      // Verify we don't accidentally get others
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+      // Ensure maxVersions in query is respected
+      Get get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(2);
+      Result result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[4], STAMPS[5]},
+          new byte[][] {VALUES[4], VALUES[5]},
+          0, 1);
 
-    // Work for Increment/Append
-    Increment increment = new Increment(ROW);
-    increment.addColumn(FAMILY, null, 1L);
-    table.increment(increment);
-    getTestNull(table, ROW, FAMILY, 1L);
+      Scan scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(2);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+              new long[]{STAMPS[4], STAMPS[5]},
+              new byte[][]{VALUES[4], VALUES[5]},
+              0, 1);
 
-    table.incrementColumnValue(ROW, FAMILY, null, 1L);
-    getTestNull(table, ROW, FAMILY, 2L);
+      // Flush and redo
 
-    delete = new Delete(ROW);
-    delete.addColumns(FAMILY, null);
-    table.delete(delete);
+      TEST_UTIL.flush();
 
-    Append append = new Append(ROW);
-    append.addColumn(FAMILY, null, VALUE);
-    table.append(append);
-    getTestNull(table, ROW, FAMILY, VALUE);
+      // Verify we can get each one properly
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+      // Verify we don't accidentally get others
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+      // Ensure maxVersions in query is respected
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(2);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[4], STAMPS[5]},
+          new byte[][] {VALUES[4], VALUES[5]},
+          0, 1);
 
-    // Work for checkAndMutate using thenPut, thenMutate and thenDelete
-    put = new Put(ROW);
-    put.addColumn(FAMILY, null, Bytes.toBytes("checkAndPut"));
-    table.put(put);
-    table.checkAndMutate(ROW, FAMILY).ifEquals(VALUE).thenPut(put);
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(2);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+              new long[]{STAMPS[4], STAMPS[5]},
+              new byte[][]{VALUES[4], VALUES[5]},
+              0, 1);
 
-    RowMutations mutate = new RowMutations(ROW);
-    mutate.add(new Put(ROW).addColumn(FAMILY, null, Bytes.toBytes("checkAndMutate")));
-    table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndPut")).thenMutate(mutate);
 
-    delete = new Delete(ROW);
-    delete.addColumns(FAMILY, null);
-    table.checkAndMutate(ROW, FAMILY).ifEquals(Bytes.toBytes("checkAndMutate")).thenDelete(delete);
-  }
+      // Add some memstore and retest
 
-  @Test
-  public void testVersions() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+      // Insert 4 more versions of same column and a dupe
+      put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]);
+      ht.put(put);
 
-    long [] STAMPS = makeStamps(20);
-    byte [][] VALUES = makeNAscii(VALUE, 20);
+      // Ensure maxVersions in query is respected
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readAllVersions();
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7],
+                  STAMPS[8]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7],
+                  VALUES[8]},
+          0, 7);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions();
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long[]{STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7],
+                  STAMPS[8]},
+          new byte[][]{VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7],
+                  VALUES[8]},0, 7);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
-
-    // Insert 4 versions of same column
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    ht.put(put);
-
-    // Verify we can get each one properly
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-
-    // Verify we don't accidentally get others
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-
-    // Ensure maxVersions in query is respected
-    Get get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(2);
-    Result result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-    Scan scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(2);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-    // Flush and redo
-
-    TEST_UTIL.flush();
-
-    // Verify we can get each one properly
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-
-    // Verify we don't accidentally get others
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-
-    // Ensure maxVersions in query is respected
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(2);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(2);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-
-    // Add some memstore and retest
-
-    // Insert 4 more versions of same column and a dupe
-    put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]);
-    ht.put(put);
-
-    // Ensure maxVersions in query is respected
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readAllVersions();
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
-        0, 7);
-
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions();
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
-        0, 7);
+      get = new Get(ROW);
+      get.readAllVersions();
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7],
+                  STAMPS[8]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7],
+                  VALUES[8]},
+          0, 7);
+
+      scan = new Scan(ROW);
+      scan.setMaxVersions();
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long[]{STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7],
+                  STAMPS[8]},
+          new byte[][]{VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7],
+                  VALUES[8]},0, 7);
+
+      // Verify we can get each one properly
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+
+      // Verify we don't accidentally get others
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+
+      // Ensure maxVersions of table is respected
 
-    get = new Get(ROW);
-    get.readAllVersions();
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
-        0, 7);
+      TEST_UTIL.flush();
 
-    scan = new Scan(ROW);
-    scan.setMaxVersions();
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
-        0, 7);
-
-    // Verify we can get each one properly
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
-
-    // Verify we don't accidentally get others
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
-
-    // Ensure maxVersions of table is respected
-
-    TEST_UTIL.flush();
-
-    // Insert 4 more versions of same column and a dupe
-    put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]);
-    ht.put(put);
-
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], STAMPS[11], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
-        0, 9);
+      // Insert 4 more versions of same column and a dupe
+      put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]);
+      ht.put(put);
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], STAMPS[11], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
-        0, 9);
-
-    // Delete a version in the memstore and a version in a storefile
-    Delete delete = new Delete(ROW);
-    delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]);
-    delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]);
-    ht.delete(delete);
-
-    // Test that it's gone
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], STAMPS[9], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
-        0, 9);
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9],
+                  STAMPS[11], STAMPS[13], STAMPS[15]},
+          new byte[][] {VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9],
+                  VALUES[11], VALUES[13], VALUES[15]},
+          0, 9);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long[]{STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9],
+                  STAMPS[11], STAMPS[13], STAMPS[15]},
+          new byte[][]{VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9],
+                  VALUES[11], VALUES[13], VALUES[15]},0, 9);
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], STAMPS[9], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
-        0, 9);
+      // Delete a version in the memstore and a version in a storefile
+      Delete delete = new Delete(ROW);
+      delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]);
+      delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]);
+      ht.delete(delete);
 
+      // Test that it's gone
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8],
+                  STAMPS[9], STAMPS[13], STAMPS[15]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8],
+                  VALUES[9], VALUES[13], VALUES[15]},
+          0, 9);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long[]{STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8],
+                  STAMPS[9], STAMPS[13], STAMPS[15]},
+          new byte[][]{VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8],
+                  VALUES[9], VALUES[13], VALUES[15]},0, 9);
+    }
   }
 
   @Test
@@ -1541,230 +1566,232 @@ public class TestFromClientSide {
     int [] LIMITS = {1,3,5};
     long [] STAMPS = makeStamps(10);
     byte [][] VALUES = makeNAscii(VALUE, 10);
-    Table ht = TEST_UTIL.createTable(tableName, FAMILIES, LIMITS);
-
-    // Insert limit + 1 on each family
-    Put put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[4], VALUES[4]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[5], VALUES[5]);
-    put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[6], VALUES[6]);
-    ht.put(put);
-
-    // Verify we only get the right number out of each
-
-    // Family0
-
-    Get get = new Get(ROW);
-    get.addColumn(FAMILIES[0], QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    Result result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {STAMPS[1]},
-        new byte[][] {VALUES[1]},
-        0, 0);
-
-    get = new Get(ROW);
-    get.addFamily(FAMILIES[0]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {STAMPS[1]},
-        new byte[][] {VALUES[1]},
-        0, 0);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, LIMITS)) {
 
-    Scan scan = new Scan(ROW);
-    scan.addColumn(FAMILIES[0], QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {STAMPS[1]},
-        new byte[][] {VALUES[1]},
-        0, 0);
-
-    scan = new Scan(ROW);
-    scan.addFamily(FAMILIES[0]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {STAMPS[1]},
-        new byte[][] {VALUES[1]},
-        0, 0);
+      // Insert limit + 1 on each family
+      Put put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILIES[0], QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILIES[1], QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[4], VALUES[4]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[5], VALUES[5]);
+      put.addColumn(FAMILIES[2], QUALIFIER, STAMPS[6], VALUES[6]);
+      ht.put(put);
 
-    // Family1
+      // Verify we only get the right number out of each
 
-    get = new Get(ROW);
-    get.addColumn(FAMILIES[1], QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
+      // Family0
 
-    get = new Get(ROW);
-    get.addFamily(FAMILIES[1]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
-
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILIES[1], QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
-
-    scan = new Scan(ROW);
-    scan.addFamily(FAMILIES[1]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
+      Get get = new Get(ROW);
+      get.addColumn(FAMILIES[0], QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      Result result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+          new long [] {STAMPS[1]},
+          new byte[][] {VALUES[1]},
+          0, 0);
 
-    // Family2
+      get = new Get(ROW);
+      get.addFamily(FAMILIES[0]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+          new long [] {STAMPS[1]},
+          new byte[][] {VALUES[1]},
+          0, 0);
+
+      Scan scan = new Scan(ROW);
+      scan.addColumn(FAMILIES[0], QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+              new long[]{STAMPS[1]},
+              new byte[][]{VALUES[1]},
+              0, 0);
+
+      scan = new Scan(ROW);
+      scan.addFamily(FAMILIES[0]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+              new long[]{STAMPS[1]},
+              new byte[][]{VALUES[1]},
+              0, 0);
 
-    get = new Get(ROW);
-    get.addColumn(FAMILIES[2], QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
-        0, 4);
+      // Family1
 
-    get = new Get(ROW);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
-        0, 4);
+      get = new Get(ROW);
+      get.addColumn(FAMILIES[1], QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+          new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+          0, 2);
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILIES[2], QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
-        0, 4);
+      get = new Get(ROW);
+      get.addFamily(FAMILIES[1]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+          new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+          0, 2);
 
-    scan = new Scan(ROW);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
-        0, 4);
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILIES[1], QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+              new long[]{STAMPS[1], STAMPS[2], STAMPS[3]},
+              new byte[][]{VALUES[1], VALUES[2], VALUES[3]},
+              0, 2);
+
+      scan = new Scan(ROW);
+      scan.addFamily(FAMILIES[1]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+              new long[]{STAMPS[1], STAMPS[2], STAMPS[3]},
+              new byte[][]{VALUES[1], VALUES[2], VALUES[3]},
+              0, 2);
 
-    // Try all families
+      // Family2
 
-    get = new Get(ROW);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 9 keys but received " + result.size(),
-        result.size() == 9);
+      get = new Get(ROW);
+      get.addColumn(FAMILIES[2], QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+          new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+          new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+          0, 4);
 
-    get = new Get(ROW);
-    get.addFamily(FAMILIES[0]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 9 keys but received " + result.size(),
-        result.size() == 9);
+      get = new Get(ROW);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+          new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+          new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+          0, 4);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILIES[2], QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+              new long[]{STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+              new byte[][]{VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+              0, 4);
+
+      scan = new Scan(ROW);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+              new long[]{STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+              new byte[][]{VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+              0, 4);
 
-    get = new Get(ROW);
-    get.addColumn(FAMILIES[0], QUALIFIER);
-    get.addColumn(FAMILIES[1], QUALIFIER);
-    get.addColumn(FAMILIES[2], QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 9 keys but received " + result.size(),
-        result.size() == 9);
+      // Try all families
 
-    scan = new Scan(ROW);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 9 keys but received " + result.size(),
-        result.size() == 9);
+      get = new Get(ROW);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertTrue("Expected 9 keys but received " + result.size(),
+          result.size() == 9);
 
-    scan = new Scan(ROW);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    scan.addFamily(FAMILIES[0]);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 9 keys but received " + result.size(),
-        result.size() == 9);
+      get = new Get(ROW);
+      get.addFamily(FAMILIES[0]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertTrue("Expected 9 keys but received " + result.size(),
+          result.size() == 9);
 
-    scan = new Scan(ROW);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    scan.addColumn(FAMILIES[0], QUALIFIER);
-    scan.addColumn(FAMILIES[1], QUALIFIER);
-    scan.addColumn(FAMILIES[2], QUALIFIER);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 9 keys but received " + result.size(),
-        result.size() == 9);
+      get = new Get(ROW);
+      get.addColumn(FAMILIES[0], QUALIFIER);
+      get.addColumn(FAMILIES[1], QUALIFIER);
+      get.addColumn(FAMILIES[2], QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertTrue("Expected 9 keys but received " + result.size(),
+          result.size() == 9);
 
+      scan = new Scan(ROW);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 9 keys but received " + result.size(),
+              result.size() == 9);
+
+      scan = new Scan(ROW);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      scan.addFamily(FAMILIES[0]);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 9 keys but received " + result.size(),
+              result.size() == 9);
+
+      scan = new Scan(ROW);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      scan.addColumn(FAMILIES[0], QUALIFIER);
+      scan.addColumn(FAMILIES[1], QUALIFIER);
+      scan.addColumn(FAMILIES[2], QUALIFIER);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 9 keys but received " + result.size(),
+              result.size() == 9);
+    }
   }
 
   @Test
   public void testDeleteFamilyVersion() throws Exception {
-    Admin admin = TEST_UTIL.getAdmin();
-    final TableName tableName = TableName.valueOf(name.getMethodName());
-
-    byte [][] QUALIFIERS = makeNAscii(QUALIFIER, 1);
-    byte [][] VALUES = makeN(VALUE, 5);
-    long [] ts = {1000, 2000, 3000, 4000, 5000};
-
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5);
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      final TableName tableName = TableName.valueOf(name.getMethodName());
 
-    Put put = new Put(ROW);
-    for (int q = 0; q < 1; q++)
-      for (int t = 0; t < 5; t++)
-        put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
-    ht.put(put);
-    admin.flush(tableName);
+      byte[][] QUALIFIERS = makeNAscii(QUALIFIER, 1);
+      byte[][] VALUES = makeN(VALUE, 5);
+      long[] ts = {1000, 2000, 3000, 4000, 5000};
 
-    Delete delete = new Delete(ROW);
-    delete.addFamilyVersion(FAMILY, ts[1]);  // delete version '2000'
-    delete.addFamilyVersion(FAMILY, ts[3]);  // delete version '4000'
-    ht.delete(delete);
-    admin.flush(tableName);
+      try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) {
 
-    for (int i = 0; i < 1; i++) {
-      Get get = new Get(ROW);
-      get.addColumn(FAMILY, QUALIFIERS[i]);
-      get.readVersions(Integer.MAX_VALUE);
-      Result result = ht.get(get);
-      // verify version '1000'/'3000'/'5000' remains for all columns
-      assertNResult(result, ROW, FAMILY, QUALIFIERS[i],
-          new long [] {ts[0], ts[2], ts[4]},
-          new byte[][] {VALUES[0], VALUES[2], VALUES[4]},
-          0, 2);
+        Put put = new Put(ROW);
+        for (int q = 0; q < 1; q++) {
+          for (int t = 0; t < 5; t++) {
+            put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
+          }
+        }
+        ht.put(put);
+        admin.flush(tableName);
+
+        Delete delete = new Delete(ROW);
+        delete.addFamilyVersion(FAMILY, ts[1]);  // delete version '2000'
+        delete.addFamilyVersion(FAMILY, ts[3]);  // delete version '4000'
+        ht.delete(delete);
+        admin.flush(tableName);
+
+        for (int i = 0; i < 1; i++) {
+          Get get = new Get(ROW);
+          get.addColumn(FAMILY, QUALIFIERS[i]);
+          get.readVersions(Integer.MAX_VALUE);
+          Result result = ht.get(get);
+          // verify version '1000'/'3000'/'5000' remains for all columns
+          assertNResult(result, ROW, FAMILY, QUALIFIERS[i],
+                  new long[]{ts[0], ts[2], ts[4]},
+                  new byte[][]{VALUES[0], VALUES[2], VALUES[4]},
+                  0, 2);
+        }
+      }
     }
-    ht.close();
-    admin.close();
   }
 
   @Test
@@ -1775,111 +1802,114 @@ public class TestFromClientSide {
     byte [][] VALUES = makeN(VALUE, 5);
     long [] ts = {1000, 2000, 3000, 4000, 5000};
 
-    Admin admin = TEST_UTIL.getAdmin();
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5);
-    Put put = null;
-    Result result = null;
-    Get get = null;
-    Delete delete = null;
-
-    // 1. put on ROW
-    put = new Put(ROW);
-    for (int q = 0; q < 5; q++)
-      for (int t = 0; t < 5; t++)
-        put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
-    ht.put(put);
-    admin.flush(tableName);
-
-    // 2. put on ROWS[0]
-    byte [] ROW2 = Bytes.toBytes("myRowForTest");
-    put = new Put(ROW2);
-    for (int q = 0; q < 5; q++)
-      for (int t = 0; t < 5; t++)
-        put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
-    ht.put(put);
-    admin.flush(tableName);
-
-    // 3. delete on ROW
-    delete = new Delete(ROW);
-    // delete version <= 2000 of all columns
-    // note: addFamily must be the first since it will mask
-    // the subsequent other type deletes!
-    delete.addFamily(FAMILY, ts[1]);
-    // delete version '4000' of all columns
-    delete.addFamilyVersion(FAMILY, ts[3]);
-   // delete version <= 3000 of column 0
-    delete.addColumns(FAMILY, QUALIFIERS[0], ts[2]);
-    // delete version <= 5000 of column 2
-    delete.addColumns(FAMILY, QUALIFIERS[2], ts[4]);
-    // delete version 5000 of column 4
-    delete.addColumn(FAMILY, QUALIFIERS[4], ts[4]);
-    ht.delete(delete);
-    admin.flush(tableName);
-
-     // 4. delete on ROWS[0]
-    delete = new Delete(ROW2);
-    delete.addFamilyVersion(FAMILY, ts[1]);  // delete version '2000'
-    delete.addFamilyVersion(FAMILY, ts[3]);  // delete version '4000'
-    ht.delete(delete);
-    admin.flush(tableName);
-
-    // 5. check ROW
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIERS[0]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIERS[0],
-        new long [] {ts[4]},
-        new byte[][] {VALUES[4]},
-        0, 0);
+    try (Admin admin = TEST_UTIL.getAdmin();
+        Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) {
+      Put put = null;
+      Result result = null;
+      Get get = null;
+      Delete delete = null;
 
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIERS[1]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIERS[1],
-        new long [] {ts[2], ts[4]},
-        new byte[][] {VALUES[2], VALUES[4]},
-        0, 1);
+      // 1. put on ROW
+      put = new Put(ROW);
+      for (int q = 0; q < 5; q++) {
+        for (int t = 0; t < 5; t++) {
+          put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
+        }
+      }
+      ht.put(put);
+      admin.flush(tableName);
+
+      // 2. put on ROWS[0]
+      byte[] ROW2 = Bytes.toBytes("myRowForTest");
+      put = new Put(ROW2);
+      for (int q = 0; q < 5; q++) {
+        for (int t = 0; t < 5; t++) {
+          put.addColumn(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
+        }
+      }
+      ht.put(put);
+      admin.flush(tableName);
+
+      // 3. delete on ROW
+      delete = new Delete(ROW);
+      // delete version <= 2000 of all columns
+      // note: addFamily must be the first since it will mask
+      // the subsequent other type deletes!
+      delete.addFamily(FAMILY, ts[1]);
+      // delete version '4000' of all columns
+      delete.addFamilyVersion(FAMILY, ts[3]);
+      // delete version <= 3000 of column 0
+      delete.addColumns(FAMILY, QUALIFIERS[0], ts[2]);
+      // delete version <= 5000 of column 2
+      delete.addColumns(FAMILY, QUALIFIERS[2], ts[4]);
+      // delete version 5000 of column 4
+      delete.addColumn(FAMILY, QUALIFIERS[4], ts[4]);
+      ht.delete(delete);
+      admin.flush(tableName);
 
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIERS[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertEquals(0, result.size());
+      // 4. delete on ROWS[0]
+      delete = new Delete(ROW2);
+      delete.addFamilyVersion(FAMILY, ts[1]);  // delete version '2000'
+      delete.addFamilyVersion(FAMILY, ts[3]);  // delete version '4000'
+      ht.delete(delete);
+      admin.flush(tableName);
 
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIERS[3]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIERS[3],
-        new long [] {ts[2], ts[4]},
-        new byte[][] {VALUES[2], VALUES[4]},
-        0, 1);
+      // 5. check ROW
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIERS[0]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIERS[0],
+              new long[]{ts[4]},
+              new byte[][]{VALUES[4]},
+              0, 0);
 
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIERS[4]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIERS[4],
-        new long [] {ts[2]},
-        new byte[][] {VALUES[2]},
-        0, 0);
-
-    // 6. check ROWS[0]
-    for (int i = 0; i < 5; i++) {
-      get = new Get(ROW2);
-      get.addColumn(FAMILY, QUALIFIERS[i]);
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIERS[1]);
       get.readVersions(Integer.MAX_VALUE);
       result = ht.get(get);
-      // verify version '1000'/'3000'/'5000' remains for all columns
-      assertNResult(result, ROW2, FAMILY, QUALIFIERS[i],
-          new long [] {ts[0], ts[2], ts[4]},
-          new byte[][] {VALUES[0], VALUES[2], VALUES[4]},
-          0, 2);
+      assertNResult(result, ROW, FAMILY, QUALIFIERS[1],
+              new long[]{ts[2], ts[4]},
+              new byte[][]{VALUES[2], VALUES[4]},
+              0, 1);
+
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIERS[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertEquals(0, result.size());
+
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIERS[3]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIERS[3],
+              new long[]{ts[2], ts[4]},
+              new byte[][]{VALUES[2], VALUES[4]},
+              0, 1);
+
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIERS[4]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIERS[4],
+              new long[]{ts[2]},
+              new byte[][]{VALUES[2]},
+              0, 0);
+
+      // 6. check ROWS[0]
+      for (int i = 0; i < 5; i++) {
+        get = new Get(ROW2);
+        get.addColumn(FAMILY, QUALIFIERS[i]);
+        get.readVersions(Integer.MAX_VALUE);
+        result = ht.get(get);
+        // verify version '1000'/'3000'/'5000' remains for all columns
+        assertNResult(result, ROW2, FAMILY, QUALIFIERS[i],
+                new long[]{ts[0], ts[2], ts[4]},
+                new byte[][]{VALUES[0], VALUES[2], VALUES[4]},
+                0, 2);
+      }
     }
-    ht.close();
-    admin.close();
   }
 
   @Test
@@ -1890,22 +1920,22 @@ public class TestFromClientSide {
     byte [][] VALUES = makeN(VALUE, 5);
     long [] ts = {1000, 2000, 3000, 4000, 5000};
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3);
-
-    Put put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
-    ht.put(put);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) {
+      Put put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
+      ht.put(put);
 
-    // delete wrong family
-    Delete delete = new Delete(ROW);
-    delete.addFamily(FAMILIES[1], ts[0]);
-    ht.delete(delete);
+      // delete wrong family
+      Delete delete = new Delete(ROW);
+      delete.addFamily(FAMILIES[1], ts[0]);
+      ht.delete(delete);
 
-    Get get = new Get(ROW);
-    get.addFamily(FAMILIES[0]);
-    get.readAllVersions();
-    Result result = ht.get(get);
-    assertTrue(Bytes.equals(result.getValue(FAMILIES[0], QUALIFIER), VALUES[0]));
+      Get get = new Get(ROW);
+      get.addFamily(FAMILIES[0]);
+      get.readAllVersions();
+      Result result = ht.get(get);
+      assertTrue(Bytes.equals(result.getValue(FAMILIES[0], QUALIFIER), VALUES[0]));
+    }
   }
 
   @Test
@@ -1917,296 +1947,297 @@ public class TestFromClientSide {
     byte [][] VALUES = makeN(VALUE, 5);
     long [] ts = {1000, 2000, 3000, 4000, 5000};
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) {
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[1], VALUES[1]);
-    ht.put(put);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[1], VALUES[1]);
+      ht.put(put);
 
-    Delete delete = new Delete(ROW);
-    delete.addFamily(FAMILIES[0], ts[0]);
-    ht.delete(delete);
+      Delete delete = new Delete(ROW);
+      delete.addFamily(FAMILIES[0], ts[0]);
+      ht.delete(delete);
 
-    Get get = new Get(ROW);
-    get.addFamily(FAMILIES[0]);
-    get.readVersions(Integer.MAX_VALUE);
-    Result result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {ts[1]},
-        new byte[][] {VALUES[1]},
-        0, 0);
+      Get get = new Get(ROW);
+      get.addFamily(FAMILIES[0]);
+      get.readVersions(Integer.MAX_VALUE);
+      Result result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+          new long [] {ts[1]},
+          new byte[][] {VALUES[1]},
+          0, 0);
+
+      Scan scan = new Scan(ROW);
+      scan.addFamily(FAMILIES[0]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+              new long[]{ts[1]},
+              new byte[][]{VALUES[1]},
+              0, 0);
 
-    Scan scan = new Scan(ROW);
-    scan.addFamily(FAMILIES[0]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {ts[1]},
-        new byte[][] {VALUES[1]},
-        0, 0);
-
-    // Test delete latest version
-    put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[3], VALUES[3]);
-    put.addColumn(FAMILIES[0], null, ts[4], VALUES[4]);
-    put.addColumn(FAMILIES[0], null, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[0], null, ts[3], VALUES[3]);
-    ht.put(put);
-
-    delete = new Delete(ROW);
-    delete.addColumn(FAMILIES[0], QUALIFIER); // ts[4]
-    ht.delete(delete);
-
-    get = new Get(ROW);
-    get.addColumn(FAMILIES[0], QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {ts[1], ts[2], ts[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
+      // Test delete latest version
+      put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[3], VALUES[3]);
+      put.addColumn(FAMILIES[0], null, ts[4], VALUES[4]);
+      put.addColumn(FAMILIES[0], null, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[0], null, ts[3], VALUES[3]);
+      ht.put(put);
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILIES[0], QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {ts[1], ts[2], ts[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
-
-    // Test for HBASE-1847
-    delete = new Delete(ROW);
-    delete.addColumn(FAMILIES[0], null);
-    ht.delete(delete);
-
-    // Cleanup null qualifier
-    delete = new Delete(ROW);
-    delete.addColumns(FAMILIES[0], null);
-    ht.delete(delete);
-
-    // Expected client behavior might be that you can re-put deleted values
-    // But alas, this is not to be.  We can't put them back in either case.
-
-    put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); // 1000
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]); // 5000
-    ht.put(put);
-
-
-    // It used to be due to the internal implementation of Get, that
-    // the Get() call would return ts[4] UNLIKE the Scan below. With
-    // the switch to using Scan for Get this is no longer the case.
-    get = new Get(ROW);
-    get.addFamily(FAMILIES[0]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {ts[1], ts[2], ts[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
+      delete = new Delete(ROW);
+      delete.addColumn(FAMILIES[0], QUALIFIER); // ts[4]
+      ht.delete(delete);
 
-    // The Scanner returns the previous values, the expected-naive-unexpected behavior
+      get = new Get(ROW);
+      get.addColumn(FAMILIES[0], QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+          new long [] {ts[1], ts[2], ts[3]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+          0, 2);
 
-    scan = new Scan(ROW);
-    scan.addFamily(FAMILIES[0]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
-        new long [] {ts[1], ts[2], ts[3]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
-        0, 2);
-
-    // Test deleting an entire family from one row but not the other various ways
-
-    put = new Put(ROWS[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
-    ht.put(put);
-
-    put = new Put(ROWS[1]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
-    ht.put(put);
-
-    put = new Put(ROWS[2]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
-    ht.put(put);
-
-    // Assert that above went in.
-    get = new Get(ROWS[2]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 4 key but received " + result.size() + ": " + result,
-        result.size() == 4);
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILIES[0], QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+              new long[]{ts[1], ts[2], ts[3]},
+              new byte[][]{VALUES[1], VALUES[2], VALUES[3]},
+              0, 2);
+
+      // Test for HBASE-1847
+      delete = new Delete(ROW);
+      delete.addColumn(FAMILIES[0], null);
+      ht.delete(delete);
 
-    delete = new Delete(ROWS[0]);
-    delete.addFamily(FAMILIES[2]);
-    ht.delete(delete);
+      // Cleanup null qualifier
+      delete = new Delete(ROW);
+      delete.addColumns(FAMILIES[0], null);
+      ht.delete(delete);
 
-    delete = new Delete(ROWS[1]);
-    delete.addColumns(FAMILIES[1], QUALIFIER);
-    ht.delete(delete);
+      // Expected client behavior might be that you can re-put deleted values
+      // But alas, this is not to be.  We can't put them back in either case.
 
-    delete = new Delete(ROWS[2]);
-    delete.addColumn(FAMILIES[1], QUALIFIER);
-    delete.addColumn(FAMILIES[1], QUALIFIER);
-    delete.addColumn(FAMILIES[2], QUALIFIER);
-    ht.delete(delete);
+      put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]); // 1000
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]); // 5000
+      ht.put(put);
 
-    get = new Get(ROWS[0]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
-    assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER,
-        new long [] {ts[0], ts[1]},
-        new byte[][] {VALUES[0], VALUES[1]},
-        0, 1);
 
-    scan = new Scan(ROWS[0]);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
-    assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER,
-        new long [] {ts[0], ts[1]},
-        new byte[][] {VALUES[0], VALUES[1]},
-        0, 1);
+      // It used to be due to the internal implementation of Get, that
+      // the Get() call would return ts[4] UNLIKE the Scan below. With
+      // the switch to using Scan for Get this is no longer the case.
+      get = new Get(ROW);
+      get.addFamily(FAMILIES[0]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+          new long [] {ts[1], ts[2], ts[3]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+          0, 2);
 
-    get = new Get(ROWS[1]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
+      // The Scanner returns the previous values, the expected-naive-unexpected behavior
 
-    scan = new Scan(ROWS[1]);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
+      scan = new Scan(ROW);
+      scan.addFamily(FAMILIES[0]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+              new long[]{ts[1], ts[2], ts[3]},
+              new byte[][]{VALUES[1], VALUES[2], VALUES[3]},
+              0, 2);
+
+      // Test deleting an entire family from one row but not the other various ways
+
+      put = new Put(ROWS[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
+      ht.put(put);
 
-    get = new Get(ROWS[2]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertEquals(1, result.size());
-    assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER,
-        new long [] {ts[2]},
-        new byte[][] {VALUES[2]},
-        0, 0);
-
-    scan = new Scan(ROWS[2]);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertEquals(1, result.size());
-    assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER,
-        new long [] {ts[2]},
-        new byte[][] {VALUES[2]},
-        0, 0);
+      put = new Put(ROWS[1]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
+      ht.put(put);
+
+      put = new Put(ROWS[2]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
+      ht.put(put);
+
+      // Assert that above went in.
+      get = new Get(ROWS[2]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertTrue("Expected 4 key but received " + result.size() + ": " + result,
+          result.size() == 4);
 
-    // Test if we delete the family first in one row (HBASE-1541)
+      delete = new Delete(ROWS[0]);
+      delete.addFamily(FAMILIES[2]);
+      ht.delete(delete);
 
-    delete = new Delete(ROWS[3]);
-    delete.addFamily(FAMILIES[1]);
-    ht.delete(delete);
+      delete = new Delete(ROWS[1]);
+      delete.addColumns(FAMILIES[1], QUALIFIER);
+      ht.delete(delete);
 
-    put = new Put(ROWS[3]);
-    put.addColumn(FAMILIES[2], QUALIFIER, VALUES[0]);
-    ht.put(put);
+      delete = new Delete(ROWS[2]);
+      delete.addColumn(FAMILIES[1], QUALIFIER);
+      delete.addColumn(FAMILIES[1], QUALIFIER);
+      delete.addColumn(FAMILIES[2], QUALIFIER);
+      ht.delete(delete);
 
-    put = new Put(ROWS[4]);
-    put.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, VALUES[2]);
-    ht.put(put);
+      get = new Get(ROWS[0]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertTrue("Expected 2 keys but received " + result.size(),
+          result.size() == 2);
+      assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER,
+          new long [] {ts[0], ts[1]},
+          new byte[][] {VALUES[0], VALUES[1]},
+          0, 1);
+
+      scan = new Scan(ROWS[0]);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 2 keys but received " + result.size(),
+              result.size() == 2);
+      assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER,
+              new long[]{ts[0], ts[1]},
+              new byte[][]{VALUES[0], VALUES[1]},
+              0, 1);
+
+      get = new Get(ROWS[1]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertTrue("Expected 2 keys but received " + result.size(),
+          result.size() == 2);
 
-    get = new Get(ROWS[3]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 1 key but received " + result.size(),
-        result.size() == 1);
+      scan = new Scan(ROWS[1]);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 2 keys but received " + result.size(),
+              result.size() == 2);
 
-    get = new Get(ROWS[4]);
-    get.addFamily(FAMILIES[1]);
-    get.addFamily(FAMILIES[2]);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
+      get = new Get(ROWS[2]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertEquals(1, result.size());
+      assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER,
+          new long [] {ts[2]},
+          new byte[][] {VALUES[2]},
+          0, 0);
+
+      scan = new Scan(ROWS[2]);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertEquals(1, result.size());
+      assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER,
+              new long[]{ts[2]},
+              new byte[][]{VALUES[2]},
+              0, 0);
 
-    scan = new Scan(ROWS[3]);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    ResultScanner scanner = ht.getScanner(scan);
-    result = scanner.next();
-    assertTrue("Expected 1 key but received " + result.size(),
-        result.size() == 1);
-    assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[3]));
-    assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[0]));
-    result = scanner.next();
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
-    assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[4]));
-    assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[1]), ROWS[4]));
-    assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[1]));
-    assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[1]), VALUES[2]));
-    scanner.close();
+      // Test if we delete the family first in one row (HBASE-1541)
 
-    // Add test of bulk deleting.
-    for (int i = 0; i < 10; i++) {
-      byte [] bytes = Bytes.toBytes(i);
-      put = new Put(bytes);
-      put.setDurability(Durability.SKIP_WAL);
-      put.addColumn(FAMILIES[0], QUALIFIER, bytes);
+      delete = new Delete(ROWS[3]);
+      delete.addFamily(FAMILIES[1]);
+      ht.delete(delete);
+
+      put = new Put(ROWS[3]);
+      put.addColumn(FAMILIES[2], QUALIFIER, VALUES[0]);
       ht.put(put);
-    }
-    for (int i = 0; i < 10; i++) {
-      byte [] bytes = Bytes.toBytes(i);
-      get = new Get(bytes);
-      get.addFamily(FAMILIES[0]);
+
+      put = new Put(ROWS[4]);
+      put.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, VALUES[2]);
+      ht.put(put);
+
+      get = new Get(ROWS[3]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
       result = ht.get(get);
-      assertTrue(result.size() == 1);
-    }
-    ArrayList<Delete> deletes = new ArrayList<>();
-    for (int i = 0; i < 10; i++) {
-      byte [] bytes = Bytes.toBytes(i);
-      delete = new Delete(bytes);
-      delete.addFamily(FAMILIES[0]);
-      deletes.add(delete);
-    }
-    ht.delete(deletes);
-    for (int i = 0; i < 10; i++) {
-      byte [] bytes = Bytes.toBytes(i);
-      get = new Get(bytes);
-      get.addFamily(FAMILIES[0]);
+      assertTrue("Expected 1 key but received " + result.size(),
+          result.size() == 1);
+
+      get = new Get(ROWS[4]);
+      get.addFamily(FAMILIES[1]);
+      get.addFamily(FAMILIES[2]);
+      get.readVersions(Integer.MAX_VALUE);
       result = ht.get(get);
-      assertTrue(result.isEmpty());
+      assertTrue("Expected 2 keys but received " + result.size(),
+          result.size() == 2);
+
+      scan = new Scan(ROWS[3]);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      ResultScanner scanner = ht.getScanner(scan);
+      result = scanner.next();
+      assertTrue("Expected 1 key but received " + result.size(),
+              result.size() == 1);
+      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[3]));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[0]));
+      result = scanner.next();
+      assertTrue("Expected 2 keys but received " + result.size(),
+              result.size() == 2);
+      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[4]));
+      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[1]), ROWS[4]));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[1]));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[1]), VALUES[2]));
+      scanner.close();
+
+      // Add test of bulk deleting.
+      for (int i = 0; i < 10; i++) {
+        byte[] bytes = Bytes.toBytes(i);
+        put = new Put(bytes);
+        put.setDurability(Durability.SKIP_WAL);
+        put.addColumn(FAMILIES[0], QUALIFIER, bytes);
+        ht.put(put);
+      }
+      for (int i = 0; i < 10; i++) {
+        byte[] bytes = Bytes.toBytes(i);
+        get = new Get(bytes);
+        get.addFamily(FAMILIES[0]);
+        result = ht.get(get);
+        assertTrue(result.size() == 1);
+      }
+      ArrayList<Delete> deletes = new ArrayList<>();
+      for (int i = 0; i < 10; i++) {
+        byte[] bytes = Bytes.toBytes(i);
+        delete = new Delete(bytes);
+        delete.addFamily(FAMILIES[0]);
+        deletes.add(delete);
+      }
+      ht.delete(deletes);
+      for (int i = 0; i < 10; i++) {
+        byte[] bytes = Bytes.toBytes(i);
+        get = new Get(bytes);
+        get.addFamily(FAMILIES[0]);
+        result = ht.get(get);
+        assertTrue(result.isEmpty());
+      }
     }
   }
 
@@ -2216,107 +2247,108 @@ public class TestFromClientSide {
   @Test
   public void testBatchOperationsWithErrors() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table foo = TEST_UTIL.createTable(tableName, new byte[][] {FAMILY}, 10);
+    try (Table foo = TEST_UTIL.createTable(tableName, new byte[][] {FAMILY}, 10)) {
 
-    int NUM_OPS = 100;
-    int FAILED_OPS = 50;
+      int NUM_OPS = 100;
+      int FAILED_OPS = 50;
 
-    RetriesExhaustedWithDetailsException expectedException = null;
-    IllegalArgumentException iae = null;
+      RetriesExhaustedWithDetailsException expectedException = null;
+      IllegalArgumentException iae = null;
 
-    // 1.1 Put with no column families (local validation, runtime exception)
-    List<Put> puts = new ArrayList<Put>(NUM_OPS);
-    for (int i = 0; i != NUM_OPS; i++) {
-      Put put = new Put(Bytes.toBytes(i));
-      puts.add(put);
-    }
+      // 1.1 Put with no column families (local validation, runtime exception)
+      List<Put> puts = new ArrayList<Put>(NUM_OPS);
+      for (int i = 0; i != NUM_OPS; i++) {
+        Put put = new Put(Bytes.toBytes(i));
+        puts.add(put);
+      }
 
-    try {
-      foo.put(puts);
-    } catch (IllegalArgumentException e) {
-      iae = e;
-    }
-    assertNotNull(iae);
-    assertEquals(NUM_OPS, puts.size());
-
-    // 1.2 Put with invalid column family
-    iae = null;
-    puts.clear();
-    for (int i = 0; i != NUM_OPS; i++) {
-      Put put = new Put(Bytes.toBytes(i));
-      put.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY, Bytes.toBytes(i));
-      puts.add(put);
-    }
+      try {
+        foo.put(puts);
+      } catch (IllegalArgumentException e) {
+        iae = e;
+      }
+      assertNotNull(iae);
+      assertEquals(NUM_OPS, puts.size());
+
+      // 1.2 Put with invalid column family
+      iae = null;
+      puts.clear();
+      for (int i = 0; i != NUM_OPS; i++) {
+        Put put = new Put(Bytes.toBytes(i));
+        put.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY, Bytes.toBytes(i));
+        puts.add(put);
+      }
 
-    try {
-      foo.put(puts);
-    } catch (RetriesExhaustedWithDetailsException e) {
-      expectedException = e;
-    }
-    assertNotNull(expectedException);
-    assertEquals(FAILED_OPS, expectedException.exceptions.size());
-    assertTrue(expectedException.actions.contains(puts.get(1)));
-
-    // 2.1 Get non-existent rows
-    List<Get> gets = new ArrayList<>(NUM_OPS);
-    for (int i = 0; i < NUM_OPS; i++) {
-      Get get = new Get(Bytes.toBytes(i));
-      // get.addColumn(FAMILY, FAMILY);
-      gets.add(get);
-    }
-    Result[] getsResult = foo.get(gets);
-
-    assertNotNull(getsResult);
-    assertEquals(NUM_OPS, getsResult.length);
-    assertNull(getsResult[1].getRow());
-
-    // 2.2 Get with invalid column family
-    gets.clear();
-    getsResult = null;
-    expectedException = null;
-    for (int i = 0; i < NUM_OPS; i++) {
-      Get get = new Get(Bytes.toBytes(i));
-      get.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY);
-      gets.add(get);
-    }
-    try {
-      getsResult = foo.get(gets);
-    } catch (RetriesExhaustedWithDetailsException e) {
-      expectedException = e;
-    }
-    assertNull(getsResult);
-    assertNotNull(expectedException);
-    assertEquals(FAILED_OPS, expectedException.exceptions.size());
-    assertTrue(expectedException.actions.contains(gets.get(1)));
-
-    // 3.1 Delete with invalid column family
-    expectedException = null;
-    List<Delete> deletes = new ArrayList<>(NUM_OPS);
-    for (int i = 0; i < NUM_OPS; i++) {
-      Delete delete = new Delete(Bytes.toBytes(i));
-      delete.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY);
-      deletes.add(delete);
-    }
-    try {
-      foo.delete(deletes);
-    } catch (RetriesExhaustedWithDetailsException e) {
-      expectedException = e;
-    }
-    assertEquals((NUM_OPS - FAILED_OPS), deletes.size());
-    assertNotNull(expectedException);
-    assertEquals(FAILED_OPS, expectedException.exceptions.size());
-    assertTrue(expectedException.actions.contains(deletes.get(1)));
+      try {
+        foo.put(puts);
+      } catch (RetriesExhaustedWithDetailsException e) {
+        expectedException = e;
+      }
+      assertNotNull(expectedException);
+      assertEquals(FAILED_OPS, expectedException.exceptions.size());
+      assertTrue(expectedException.actions.contains(puts.get(1)));
+
+      // 2.1 Get non-existent rows
+      List<Get> gets = new ArrayList<>(NUM_OPS);
+      for (int i = 0; i < NUM_OPS; i++) {
+        Get get = new Get(Bytes.toBytes(i));
+        // get.addColumn(FAMILY, FAMILY);
+        gets.add(get);
+      }
+      Result[] getsResult = foo.get(gets);
+
+      assertNotNull(getsResult);
+      assertEquals(NUM_OPS, getsResult.length);
+      assertNull(getsResult[1].getRow());
+
+      // 2.2 Get with invalid column family
+      gets.clear();
+      getsResult = null;
+      expectedException = null;
+      for (int i = 0; i < NUM_OPS; i++) {
+        Get get = new Get(Bytes.toBytes(i));
+        get.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY);
+        gets.add(get);
+      }
+      try {
+        getsResult = foo.get(gets);
+      } catch (RetriesExhaustedWithDetailsException e) {
+        expectedException = e;
+      }
+      assertNull(getsResult);
+      assertNotNull(expectedException);
+      assertEquals(FAILED_OPS, expectedException.exceptions.size());
+      assertTrue(expectedException.actions.contains(gets.get(1)));
+
+      // 3.1 Delete with invalid column family
+      expectedException = null;
+      List<Delete> deletes = new ArrayList<>(NUM_OPS);
+      for (int i = 0; i < NUM_OPS; i++) {
+        Delete delete = new Delete(Bytes.toBytes(i));
+        delete.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY);
+        deletes.add(delete);
+      }
+      try {
+        foo.delete(deletes);
+      } catch (RetriesExhaustedWithDetailsException e) {
+        expectedException = e;
+      }
+      assertEquals((NUM_OPS - FAILED_OPS), deletes.size());
+      assertNotNull(expectedException);
+      assertEquals(FAILED_OPS, expectedException.exceptions.size());
+      assertTrue(expectedException.actions.contains(deletes.get(1)));
 
 
-    // 3.2 Delete non-existent rows
-    deletes.clear();
-    for (int i = 0; i < NUM_OPS; i++) {
-      Delete delete = new Delete(Bytes.toBytes(i));
-      deletes.add(delete);
-    }
-    foo.delete(deletes);
+      // 3.2 Delete non-existent rows
+      deletes.clear();
+      for (int i = 0; i < NUM_OPS; i++) {
+        Delete delete = new Delete(Bytes.toBytes(i));
+        deletes.add(delete);
+      }
+      foo.delete(deletes);
 
-    assertTrue(deletes.isEmpty());
+      assertTrue(deletes.isEmpty());
+    }
   }
 
   /*
@@ -2393,75 +2425,75 @@ public class TestFromClientSide {
     byte [][] ROWS = makeN(ROW, numRows);
     byte [][] QUALIFIERS = makeN(QUALIFIER, numColsPerRow);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
 
-    // Insert rows
+      // Insert rows
 
-    for(int i=0;i<numRows;i++) {
-      Put put = new Put(ROWS[i]);
-      put.setDurability(Durability.SKIP_WAL);
-      for(int j=0;j<numColsPerRow;j++) {
-        put.addColumn(FAMILY, QUALIFIERS[j], QUALIFIERS[j]);
+      for (int i = 0; i < numRows; i++) {
+        Put put = new Put(ROWS[i]);
+        put.setDurability(Durability.SKIP_WAL);
+        for (int j = 0; j < numColsPerRow; j++) {
+          put.addColumn(FAMILY, QUALIFIERS[j], QUALIFIERS[j]);
+        }
+        assertTrue("Put expected to contain " + numColsPerRow + " columns but " +
+                "only contains " + put.size(), put.size() == numColsPerRow);
+        ht.put(put);
       }
-      assertTrue("Put expected to contain " + numColsPerRow + " columns but " +
-          "only contains " + put.size(), put.size() == numColsPerRow);
-      ht.put(put);
-    }
-
-    // Get a row
-    Get get = new Get(ROWS[numRows-1]);
-    Result result = ht.get(get);
-    assertNumKeys(result, numColsPerRow);
-    Cell [] keys = result.rawCells();
-    for(int i=0;i<result.size();i++) {
-      assertKey(keys[i], ROWS[numRows-1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
-    }
 
-    // Scan the rows
-    Scan scan = new Scan();
-    ResultScanner scanner = ht.getScanner(scan);
-    int rowCount = 0;
-    while((result = scanner.next()) != null) {
+      // Get a row
+      Get get = new Get(ROWS[numRows - 1]);
+      Result result = ht.get(get);
       assertNumKeys(result, numColsPerRow);
-      Cell [] kvs = result.rawCells();
-      for(int i=0;i<numColsPerRow;i++) {
-        assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+      Cell[] keys = result.rawCells();
+      for (int i = 0; i < result.size(); i++) {
+        assertKey(keys[i], ROWS[numRows - 1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
       }
-      rowCount++;
-    }
-    scanner.close();
-    assertTrue("Expected to scan " + numRows + " rows but actually scanned "
-        + rowCount + " rows", rowCount == numRows);
 
-    // flush and try again
+      // Scan the rows
+      Scan scan = new Scan();
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int rowCount = 0;
+        while ((result = scanner.next()) != null) {
+          assertNumKeys(result, numColsPerRow);
+          Cell[] kvs = result.rawCells();
+          for (int i = 0; i < numColsPerRow; i++) {
+            assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+          }
+          rowCount++;
+        }
+        assertTrue("Expected to scan " + numRows + " rows but actually scanned "
+                + rowCount + " rows", rowCount == numRows);
+      }
 
-    TEST_UTIL.flush();
+      // flush and try again
 
-    // Get a row
-    get = new Get(ROWS[numRows-1]);
-    result = ht.get(get);
-    assertNumKeys(result, numColsPerRow);
-    keys = result.rawCells();
-    for(int i=0;i<result.size();i++) {
-      assertKey(keys[i], ROWS[numRows-1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
-    }
+      TEST_UTIL.flush();
 
-    // Scan the rows
-    scan = new Scan();
-    scanner = ht.getScanner(scan);
-    rowCount = 0;
-    while((result = scanner.next()) != null) {
+      // Get a row
+      get = new Get(ROWS[numRows - 1]);
+      result = ht.get(get);
       assertNumKeys(result, numColsPerRow);
-      Cell [] kvs = result.rawCells();
-      for(int i=0;i<numColsPerRow;i++) {
-        assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+      keys = result.rawCells();
+      for (int i = 0; i < result.size(); i++) {
+        assertKey(keys[i], ROWS[numRows - 1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
       }
-      rowCount++;
-    }
-    scanner.close();
-    assertTrue("Expected to scan " + numRows + " rows but actually scanned "
-        + rowCount + " rows", rowCount == numRows);
 
+      // Scan the rows
+      scan = new Scan();
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int rowCount = 0;
+        while ((result = scanner.next()) != null) {
+          assertNumKeys(result, numColsPerRow);
+          Cell[] kvs = result.rawCells();
+          for (int i = 0; i < numColsPerRow; i++) {
+            assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+          }
+          rowCount++;
+        }
+        assertTrue("Expected to scan " + numRows + " rows but actually scanned "
+                + rowCount + " rows", rowCount == numRows);
+      }
+    }
   }
 
   /**
@@ -2475,56 +2507,56 @@ public class TestFromClientSide {
     byte [][] VALUES = makeNAscii(VALUE, 7);
     long [] STAMPS = makeStamps(7);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
-
-    // Insert three versions
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    ht.put(put);
+      // Insert three versions
 
-    // Get the middle value
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      ht.put(put);
 
-    // Try to get one version before (expect fail)
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+      // Get the middle value
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
 
-    // Try to get one version after (expect fail)
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+      // Try to get one version before (expect fail)
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
 
-    // Try same from storefile
-    TEST_UTIL.flush();
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+      // Try to get one version after (expect fail)
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
 
-    // Insert two more versions surrounding others, into memstore
-    put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
-    ht.put(put);
+      // Try same from storefile
+      TEST_UTIL.flush();
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
 
-    // Check we can get everything we should and can't get what we shouldn't
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+      // Insert two more versions surrounding others, into memstore
+      put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+      ht.put(put);
 
-    // Try same from two storefiles
-    TEST_UTIL.flush();
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+      // Check we can get everything we should and can't get what we shouldn't
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
 
+      // Try same from two storefiles
+      TEST_UTIL.flush();
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+    }
   }
 
   /**
@@ -2538,42 +2570,42 @@ public class TestFromClientSide {
     byte [][] VALUES = makeNAscii(VALUE, 7);
     long [] STAMPS = makeStamps(7);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
-
-    // Insert lots versions
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    ht.put(put);
+      // Insert lots versions
 
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      ht.put(put);
 
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
 
-    // Try same from storefile
-    TEST_UTIL.flush();
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
 
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
-    getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+      // Try same from storefile
+      TEST_UTIL.flush();
 
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
-    scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
 
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+    }
   }
 
   /**
@@ -2584,20 +2616,20 @@ public class TestFromClientSide {
   public void testJiraTest1014() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    long manualStamp = 12345;
+      long manualStamp = 12345;
 
-    // Insert lots versions
+      // Insert lots versions
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, manualStamp, VALUE);
-    ht.put(put);
-
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, manualStamp, VALUE);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp-1);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp+1);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, manualStamp, VALUE);
+      ht.put(put);
 
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, manualStamp, VALUE);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp - 1);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp + 1);
+    }
   }
 
   /**
@@ -2610,37 +2642,38 @@ public class TestFromClientSide {
     byte [][] VALUES = makeNAscii(VALUE, 7);
     long [] STAMPS = makeStamps(7);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    // Insert lots versions
+      // Insert lots versions
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    ht.put(put);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      ht.put(put);
 
-    getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
-    getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+      getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
 
-    scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
-    scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+      scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
 
-    // Try same from storefile
-    TEST_UTIL.flush();
+      // Try same from storefile
+      TEST_UTIL.flush();
 
-    getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
-    getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+      getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
 
-    scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
-    scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
-    scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+      scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+      scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+    }
   }
 
   /**
@@ -2653,29 +2686,30 @@ public class TestFromClientSide {
     byte [][] VALUES = makeNAscii(VALUE, 7);
     long [] STAMPS = makeStamps(7);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    // Insert lots versions
+      // Insert lots versions
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    ht.put(put);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      ht.put(put);
 
-    getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
 
-    scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
 
-    // Try same from storefile
-    TEST_UTIL.flush();
+      // Try same from storefile
+      TEST_UTIL.flush();
 
-    getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
 
-    scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+      scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+    }
   }
 
   //
@@ -3526,440 +3560,455 @@ public class TestFromClientSide {
     long [] STAMPS = makeStamps(20);
     byte [][] VALUES = makeNAscii(VALUE, 20);
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10);
-
-    // Insert 4 versions of same column
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    ht.put(put);
-
-    // Verify we can get each one properly
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-
-    // Verify we don't accidentally get others
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-
-    // Ensure maxVersions in query is respected
-    Get get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(2);
-    Result result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-    Scan scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(2);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-    // Flush and redo
-
-    TEST_UTIL.flush();
-
-    // Verify we can get each one properly
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
-
-    // Verify we don't accidentally get others
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
-
-    // Ensure maxVersions in query is respected
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(2);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(2);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[4], STAMPS[5]},
-        new byte[][] {VALUES[4], VALUES[5]},
-        0, 1);
-
-
-    // Add some memstore and retest
-
-    // Insert 4 more versions of same column and a dupe
-    put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]);
-    ht.put(put);
-
-    // Ensure maxVersions in query is respected
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(7);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
-        0, 6);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(7);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
-        0, 6);
+      // Insert 4 versions of same column
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      ht.put(put);
 
-    get = new Get(ROW);
-    get.readVersions(7);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+      // Verify we can get each one properly
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+      // Verify we don't accidentally get others
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+      // Ensure maxVersions in query is respected
+      Get get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(2);
+      Result result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[4], STAMPS[5]},
+          new byte[][] {VALUES[4], VALUES[5]},
+          0, 1);
+
+      Scan scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(2);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+              new long[]{STAMPS[4], STAMPS[5]},
+              new byte[][]{VALUES[4], VALUES[5]},
+              0, 1);
+
+      // Flush and redo
+
+      TEST_UTIL.flush();
+
+      // Verify we can get each one properly
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+      // Verify we don't accidentally get others
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+      // Ensure maxVersions in query is respected
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(2);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[4], STAMPS[5]},
+          new byte[][] {VALUES[4], VALUES[5]},
+          0, 1);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(2);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+              new long[]{STAMPS[4], STAMPS[5]},
+              new byte[][]{VALUES[4], VALUES[5]},
+              0, 1);
+
+
+      // Add some memstore and retest
+
+      // Insert 4 more versions of same column and a dupe
+      put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]);
+      ht.put(put);
+
+      // Ensure maxVersions in query is respected
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(7);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+          new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7],
+                  VALUES[8]},
+          0, 6);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(7);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+        new long[]{STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+        new byte[][]{VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
         0, 6);
 
-    scan = new Scan(ROW);
-    scan.setMaxVersions(7);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
-        new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+      get = new Get(ROW);
+      get.readVersions(7);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+          new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7],
+                  VALUES[8]},
+          0, 6);
+
+      scan = new Scan(ROW);
+      scan.setMaxVersions(7);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+        new long[]{STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+        new byte[][]{VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
         0, 6);
 
-    // Verify we can get each one properly
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
-    getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
-    scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
-
-    // Verify we don't accidentally get others
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
-    scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
-
-    // Ensure maxVersions of table is respected
-
-    TEST_UTIL.flush();
-
-    // Insert 4 more versions of same column and a dupe
-    put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]);
-    put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]);
-    ht.put(put);
-
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], STAMPS[11], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
-        0, 9);
+      // Verify we can get each one properly
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
+      getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
+      scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], STAMPS[11], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
-        0, 9);
-
-    // Delete a version in the memstore and a version in a storefile
-    Delete delete = new Delete(ROW);
-    delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]);
-    delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]);
-    ht.delete(delete);
-
-    // Test that it's gone
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], STAMPS[9], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
-        0, 9);
+      // Verify we don't accidentally get others
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+      scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
 
-    scan = new Scan(ROW);
-    scan.addColumn(FAMILY, QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILY, QUALIFIER,
-        new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], STAMPS[9], STAMPS[13], STAMPS[15]},
-        new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
-        0, 9);
+      // Ensure maxVersions of table is respected
+
+      TEST_UTIL.flush();
+
+      // Insert 4 more versions of same column and a dupe
+      put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]);
+      put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]);
+      ht.put(put);
+
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9],
+                  STAMPS[11], STAMPS[13], STAMPS[15]},
+          new byte[][] {VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8],
+                  VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
+          0, 9);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long[]{STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9],
+                  STAMPS[11], STAMPS[13], STAMPS[15]},
+          new byte[][]{VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9],
+                  VALUES[11], VALUES[13], VALUES[15]},0, 9);
+
+      // Delete a version in the memstore and a version in a storefile
+      Delete delete = new Delete(ROW);
+      delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]);
+      delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]);
+      ht.delete(delete);
+
+      // Test that it's gone
+      get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readVersions(Integer.MAX_VALUE);
+      result = ht.get(get);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8],
+                  STAMPS[9], STAMPS[13], STAMPS[15]},
+          new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6],
+                  VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
+          0, 9);
+
+      scan = new Scan(ROW);
+      scan.addColumn(FAMILY, QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILY, QUALIFIER,
+          new long[]{STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8],
+                  STAMPS[9], STAMPS[13], STAMPS[15]},
+          new byte[][]{VALUES[1], VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[8],
+                  VALUES[9], VALUES[13], VALUES[15]},0,9);
+    }
   }
 
   @Test
   public void testUpdates() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10);
+    try (Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10)) {
 
-    // Write a column with values at timestamp 1, 2 and 3
-    byte[] row = Bytes.toBytes("row1");
-    byte[] qualifier = Bytes.toBytes("myCol");
-    Put put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA"));
-    hTable.put(put);
+      // Write a column with values at timestamp 1, 2 and 3
+      byte[] row = Bytes.toBytes("row1");
+      byte[] qualifier = Bytes.toBytes("myCol");
+      Put put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA"));
+      hTable.put(put);
 
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB"));
-    hTable.put(put);
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB"));
+      hTable.put(put);
 
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE"));
-    hTable.put(put);
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE"));
+      hTable.put(put);
 
-    Get get = new Get(row);
-    get.addColumn(FAMILY, qualifier);
-    get.readAllVersions();
-
-    // Check that the column indeed has the right values at timestamps 1 and
-    // 2
-    Result result = hTable.get(get);
-    NavigableMap<Long, byte[]> navigableMap =
-        result.getMap().get(FAMILY).get(qualifier);
-    assertEquals("AAA", Bytes.toString(navigableMap.get(1L)));
-    assertEquals("BBB", Bytes.toString(navigableMap.get(2L)));
-
-    // Update the value at timestamp 1
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC"));
-    hTable.put(put);
-
-    // Update the value at timestamp 2
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD"));
-    hTable.put(put);
-
-    // Check that the values at timestamp 2 and 1 got updated
-    result = hTable.get(get);
-    navigableMap = result.getMap().get(FAMILY).get(qualifier);
-    assertEquals("CCC", Bytes.toString(navigableMap.get(1L)));
-    assertEquals("DDD", Bytes.toString(navigableMap.get(2L)));
+      Get get = new Get(row);
+      get.addColumn(FAMILY, qualifier);
+      get.readAllVersions();
+
+      // Check that the column indeed has the right values at timestamps 1 and
+      // 2
+      Result result = hTable.get(get);
+      NavigableMap<Long, byte[]> navigableMap =
+              result.getMap().get(FAMILY).get(qualifier);
+      assertEquals("AAA", Bytes.toString(navigableMap.get(1L)));
+      assertEquals("BBB", Bytes.toString(navigableMap.get(2L)));
+
+      // Update the value at timestamp 1
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC"));
+      hTable.put(put);
+
+      // Update the value at timestamp 2
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD"));
+      hTable.put(put);
+
+      // Check that the values at timestamp 2 and 1 got updated
+      result = hTable.get(get);
+      navigableMap = result.getMap().get(FAMILY).get(qualifier);
+      assertEquals("CCC", Bytes.toString(navigableMap.get(1L)));
+      assertEquals("DDD", Bytes.toString(navigableMap.get(2L)));
+    }
   }
 
   @Test
   public void testUpdatesWithMajorCompaction() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10);
-    Admin admin = TEST_UTIL.getAdmin();
+    try (Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10);
+        Admin admin = TEST_UTIL.getAdmin()) {
 
-    // Write a column with values at timestamp 1, 2 and 3
-    byte[] row = Bytes.toBytes("row2");
-    byte[] qualifier = Bytes.toBytes("myCol");
-    Put put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA"));
-    hTable.put(put);
+      // Write a column with values at timestamp 1, 2 and 3
+      byte[] row = Bytes.toBytes("row2");
+      byte[] qualifier = Bytes.toBytes("myCol");
+      Put put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA"));
+      hTable.put(put);
 
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB"));
-    hTable.put(put);
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB"));
+      hTable.put(put);
 
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE"));
-    hTable.put(put);
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE"));
+      hTable.put(put);
 
-    Get get = new Get(row);
-    get.addColumn(FAMILY, qualifier);
-    get.readAllVersions();
-
-    // Check that the column indeed has the right values at timestamps 1 and
-    // 2
-    Result result = hTable.get(get);
-    NavigableMap<Long, byte[]> navigableMap =
-        result.getMap().get(FAMILY).get(qualifier);
-    assertEquals("AAA", Bytes.toString(navigableMap.get(1L)));
-    assertEquals("BBB", Bytes.toString(navigableMap.get(2L)));
-
-    // Trigger a major compaction
-    admin.flush(tableName);
-    admin.majorCompact(tableName);
-    Thread.sleep(6000);
-
-    // Update the value at timestamp 1
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC"));
-    hTable.put(put);
-
-    // Update the value at timestamp 2
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD"));
-    hTable.put(put);
-
-    // Trigger a major compaction
-    admin.flush(tableName);
-    admin.majorCompact(tableName);
-    Thread.sleep(6000);
-
-    // Check that the values at timestamp 2 and 1 got updated
-    result = hTable.get(get);
-    navigableMap = result.getMap().get(FAMILY).get(qualifier);
-    assertEquals("CCC", Bytes.toString(navigableMap.get(1L)));
-    assertEquals("DDD", Bytes.toString(navigableMap.get(2L)));
+      Get get = new Get(row);
+      get.addColumn(FAMILY, qualifier);
+      get.readAllVersions();
+
+      // Check that the column indeed has the right values at timestamps 1 and
+      // 2
+      Result result = hTable.get(get);
+      NavigableMap<Long, byte[]> navigableMap =
+              result.getMap().get(FAMILY).get(qualifier);
+      assertEquals("AAA", Bytes.toString(navigableMap.get(1L)));
+      assertEquals("BBB", Bytes.toString(navigableMap.get(2L)));
+
+      // Trigger a major compaction
+      admin.flush(tableName);
+      admin.majorCompact(tableName);
+      Thread.sleep(6000);
+
+      // Update the value at timestamp 1
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC"));
+      hTable.put(put);
+
+      // Update the value at timestamp 2
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD"));
+      hTable.put(put);
+
+      // Trigger a major compaction
+      admin.flush(tableName);
+      admin.majorCompact(tableName);
+      Thread.sleep(6000);
+
+      // Check that the values at timestamp 2 and 1 got updated
+      result = hTable.get(get);
+      navigableMap = result.getMap().get(FAMILY).get(qualifier);
+      assertEquals("CCC", Bytes.toString(navigableMap.get(1L)));
+      assertEquals("DDD", Bytes.toString(navigableMap.get(2L)));
+    }
   }
 
   @Test
   public void testMajorCompactionBetweenTwoUpdates() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10);
-    Admin admin = TEST_UTIL.getAdmin();
+    try (Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10);
+        Admin admin = TEST_UTIL.getAdmin()) {
 
-    // Write a column with values at timestamp 1, 2 and 3
-    byte[] row = Bytes.toBytes("row3");
-    byte[] qualifier = Bytes.toBytes("myCol");
-    Put put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA"));
-    hTable.put(put);
+      // Write a column with values at timestamp 1, 2 and 3
+      byte[] row = Bytes.toBytes("row3");
+      byte[] qualifier = Bytes.toBytes("myCol");
+      Put put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA"));
+      hTable.put(put);
 
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB"));
-    hTable.put(put);
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB"));
+      hTable.put(put);
 
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE"));
-    hTable.put(put);
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE"));
+      hTable.put(put);
 
-    Get get = new Get(row);
-    get.addColumn(FAMILY, qualifier);
-    get.readAllVersions();
-
-    // Check that the column indeed has the right values at timestamps 1 and
-    // 2
-    Result result = hTable.get(get);
-    NavigableMap<Long, byte[]> navigableMap =
-        result.getMap().get(FAMILY).get(qualifier);
-    assertEquals("AAA", Bytes.toString(navigableMap.get(1L)));
-    assertEquals("BBB", Bytes.toString(navigableMap.get(2L)));
-
-    // Trigger a major compaction
-    admin.flush(tableName);
-    admin.majorCompact(tableName);
-    Thread.sleep(6000);
-
-    // Update the value at timestamp 1
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC"));
-    hTable.put(put);
-
-    // Trigger a major compaction
-    admin.flush(tableName);
-    admin.majorCompact(tableName);
-    Thread.sleep(6000);
-
-    // Update the value at timestamp 2
-    put = new Put(row);
-    put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD"));
-    hTable.put(put);
-
-    // Trigger a major compaction
-    admin.flush(tableName);
-    admin.majorCompact(tableName);
-    Thread.sleep(6000);
-
-    // Check that the values at timestamp 2 and 1 got updated
-    result = hTable.get(get);
-    navigableMap = result.getMap().get(FAMILY).get(qualifier);
-
-    assertEquals("CCC", Bytes.toString(navigableMap.get(1L)));
-    assertEquals("DDD", Bytes.toString(navigableMap.get(2L)));
+      Get get = new Get(row);
+      get.addColumn(FAMILY, qualifier);
+      get.readAllVersions();
+
+      // Check that the column indeed has the right values at timestamps 1 and
+      // 2
+      Result result = hTable.get(get);
+      NavigableMap<Long, byte[]> navigableMap =
+              result.getMap().get(FAMILY).get(qualifier);
+      assertEquals("AAA", Bytes.toString(navigableMap.get(1L)));
+      assertEquals("BBB", Bytes.toString(navigableMap.get(2L)));
+
+      // Trigger a major compaction
+      admin.flush(tableName);
+      admin.majorCompact(tableName);
+      Thread.sleep(6000);
+
+      // Update the value at timestamp 1
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC"));
+      hTable.put(put);
+
+      // Trigger a major compaction
+      admin.flush(tableName);
+      admin.majorCompact(tableName);
+      Thread.sleep(6000);
+
+      // Update the value at timestamp 2
+      put = new Put(row);
+      put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD"));
+      hTable.put(put);
+
+      // Trigger a major compaction
+      admin.flush(tableName);
+      admin.majorCompact(tableName);
+      Thread.sleep(6000);
+
+      // Check that the values at timestamp 2 and 1 got updated
+      result = hTable.get(get);
+      navigableMap = result.getMap().get(FAMILY).get(qualifier);
+
+      assertEquals("CCC", Bytes.toString(navigableMap.get(1L)));
+      assertEquals("DDD", Bytes.toString(navigableMap.get(2L)));
+    }
   }
 
   @Test
   public void testGet_EmptyTable() throws IOException {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-    Get get = new Get(ROW);
-    get.addFamily(FAMILY);
-    Result r = table.get(get);
-    assertTrue(r.isEmpty());
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      Get get = new Get(ROW);
+      get.addFamily(FAMILY);
+      Result r = table.get(get);
+      assertTrue(r.isEmpty());
+    }
   }
 
   @Test
   public void testGet_NullQualifier() throws IOException {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
 
-    put = new Put(ROW);
-    put.addColumn(FAMILY, null, VALUE);
-    table.put(put);
-    LOG.info("Row put");
+      put = new Put(ROW);
+      put.addColumn(FAMILY, null, VALUE);
+      table.put(put);
+      LOG.info("Row put");
 
-    Get get = new Get(ROW);
-    get.addColumn(FAMILY, null);
-    Result r = table.get(get);
-    assertEquals(1, r.size());
+      Get get = new Get(ROW);
+      get.addColumn(FAMILY, null);
+      Result r = table.get(get);
+      assertEquals(1, r.size());
 
-    get = new Get(ROW);
-    get.addFamily(FAMILY);
-    r = table.get(get);
-    assertEquals(2, r.size());
+      get = new Get(ROW);
+      get.addFamily(FAMILY);
+      r = table.get(get);
+      assertEquals(2, r.size());
+    }
   }
 
   @Test
   public void testGet_NonExistentRow() throws IOException {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
-    LOG.info("Row put");
-
-    Get get = new Get(ROW);
-    get.addFamily(FAMILY);
-    Result r = table.get(get);
-    assertFalse(r.isEmpty());
-    System.out.println("Row retrieved successfully");
-
-    byte [] missingrow = Bytes.toBytes("missingrow");
-    get = new Get(missingrow);
-    get.addFamily(FAMILY);
-    r = table.get(get);
-    assertTrue(r.isEmpty());
-    LOG.info("Row missing as it should be");
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
+      LOG.info("Row put");
+
+      Get get = new Get(ROW);
+      get.addFamily(FAMILY);
+      Result r = table.get(get);
+      assertFalse(r.isEmpty());
+      System.out.println("Row retrieved successfully");
+
+      byte[] missingrow = Bytes.toBytes("missingrow");
+      get = new Get(missingrow);
+      get.addFamily(FAMILY);
+      r = table.get(get);
+      assertTrue(r.isEmpty());
+      LOG.info("Row missing as it should be");
+    }
   }
 
   @Test
@@ -3969,35 +4018,37 @@ public class TestFromClientSide {
     final byte [] row1 = Bytes.toBytes("row1");
     final byte [] row2 = Bytes.toBytes("row2");
     final byte [] value = Bytes.toBytes("abcd");
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-        new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY });
-    Put put = new Put(row1);
-    put.addColumn(CONTENTS_FAMILY, null, value);
-    table.put(put);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
+        new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY })) {
+      Put put = new Put(row1);
+      put.addColumn(CONTENTS_FAMILY, null, value);
+      table.put(put);
 
-    put = new Put(row2);
-    put.addColumn(CONTENTS_FAMILY, null, value);
+      put = new Put(row2);
+      put.addColumn(CONTENTS_FAMILY, null, value);
 
-    assertEquals(1, put.size());
-    assertEquals(1, put.getFamilyCellMap().get(CONTENTS_FAMILY).size());
+      assertEquals(1, put.size());
+      assertEquals(1, put.getFamilyCellMap().get(CONTENTS_FAMILY).size());
 
-    // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
-    KeyValue kv = (KeyValue)put.getFamilyCellMap().get(CONTENTS_FAMILY).get(0);
+      // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
+      KeyValue kv = (KeyValue) put.getFamilyCellMap().get(CONTENTS_FAMILY).get(0);
 
-    assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), CONTENTS_FAMILY));
-    // will it return null or an empty byte array?
-    assertTrue(Bytes.equals(CellUtil.cloneQualifier(kv), new byte[0]));
+      assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), CONTENTS_FAMILY));
+      // will it return null or an empty byte array?
+      assertTrue(Bytes.equals(CellUtil.cloneQualifier(kv), new byte[0]));
 
-    assertTrue(Bytes.equals(CellUtil.cloneValue(kv), value));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(kv), value));
 
-    table.put(put);
+      table.put(put);
 
-    Scan scan = new Scan();
-    scan.addColumn(CONTENTS_FAMILY, null);
-    ResultScanner scanner = table.getScanner(scan);
-    for (Result r : scanner) {
-      for(Cell key : r.rawCells()) {
-        System.out.println(Bytes.toString(r.getRow()) + ": " + key.toString());
+      Scan scan = new Scan();
+      scan.addColumn(CONTENTS_FAMILY, null);
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        for (Result r : scanner) {
+          for (Cell key : r.rawCells()) {
+            System.out.println(Bytes.toString(r.getRow()) + ": " + key.toString());
+          }
+        }
       }
     }
   }
@@ -4006,19 +4057,18 @@ public class TestFromClientSide {
   public void testPutNoCF() throws IOException {
     final byte[] BAD_FAM = Bytes.toBytes("BAD_CF");
     final byte[] VAL = Bytes.toBytes(100);
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      boolean caughtNSCFE = false;
 
-    boolean caughtNSCFE = false;
-
-    try {
-      Put p = new Put(ROW);
-      p.addColumn(BAD_FAM, QUALIFIER, VAL);
-      table.put(p);
-    } catch (Exception e) {
-      caughtNSCFE = e instanceof NoSuchColumnFamilyException;
+      try {
+        Put p = new Put(ROW);
+        p.addColumn(BAD_FAM, QUALIFIER, VAL);
+        table.put(p);
+      } catch (Exception e) {
+        caughtNSCFE = e instanceof NoSuchColumnFamilyException;
+      }
+      assertTrue("Should throw NoSuchColumnFamilyException", caughtNSCFE);
     }
-    assertTrue("Should throw NoSuchColumnFamilyException", caughtNSCFE);
-
   }
 
   @Test
@@ -4027,25 +4077,28 @@ public class TestFromClientSide {
     final byte[] SMALL_FAMILY = Bytes.toBytes("smallfam");
     final int NB_BATCH_ROWS = 10;
     final byte[] value = Bytes.toBytes("abcd");
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-      new byte[][] {CONTENTS_FAMILY, SMALL_FAMILY });
-    ArrayList<Put> rowsUpdate = new ArrayList<Put>();
-    for (int i = 0; i < NB_BATCH_ROWS; i++) {
-      byte[] row = Bytes.toBytes("row" + i);
-      Put put = new Put(row);
-      put.setDurability(Durability.SKIP_WAL);
-      put.addColumn(CONTENTS_FAMILY, null, value);
-      rowsUpdate.add(put);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
+      new byte[][] {CONTENTS_FAMILY, SMALL_FAMILY })) {
+      ArrayList<Put> rowsUpdate = new ArrayList<Put>();
+      for (int i = 0; i < NB_BATCH_ROWS; i++) {
+        byte[] row = Bytes.toBytes("row" + i);
+        Put put = new Put(row);
+        put.setDurability(Durability.SKIP_WAL);
+        put.addColumn(CONTENTS_FAMILY, null, value);
+        rowsUpdate.add(put);
+      }
+      table.put(rowsUpdate);
+      Scan scan = new Scan();
+      scan.addFamily(CONTENTS_FAMILY);
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        int nbRows = 0;
+        for (@SuppressWarnings("unused")
+                Result row : scanner) {
+          nbRows++;
+        }
+        assertEquals(NB_BATCH_ROWS, nbRows);
+      }
     }
-    table.put(rowsUpdate);
-    Scan scan = new Scan();
-    scan.addFamily(CONTENTS_FAMILY);
-    ResultScanner scanner = table.getScanner(scan);
-    int nbRows = 0;
-    for (@SuppressWarnings("unused")
-    Result row : scanner)
-      nbRows++;
-    assertEquals(NB_BATCH_ROWS, nbRows);
   }
 
   @Test
@@ -4054,26 +4107,29 @@ public class TestFromClientSide {
     final byte[] SMALL_FAMILY = Bytes.toBytes("smallfam");
     final byte[] value = Bytes.toBytes("abcd");
     final int NB_BATCH_ROWS = 10;
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-        new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY });
-    ArrayList<Put> rowsUpdate = new ArrayList<Put>();
-    for (int i = 0; i < NB_BATCH_ROWS * 10; i++) {
-      byte[] row = Bytes.toBytes("row" + i);
-      Put put = new Put(row);
-      put.setDurability(Durability.SKIP_WAL);
-      put.addColumn(CONTENTS_FAMILY, null, value);
-      rowsUpdate.add(put);
-    }
-    table.put(rowsUpdate);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
+        new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY })) {
+      ArrayList<Put> rowsUpdate = new ArrayList<Put>();
+      for (int i = 0; i < NB_BATCH_ROWS * 10; i++) {
+        byte[] row = Bytes.toBytes("row" + i);
+        Put put = new Put(row);
+        put.setDurability(Durability.SKIP_WAL);
+        put.addColumn(CONTENTS_FAMILY, null, value);
+        rowsUpdate.add(put);
+      }
+      table.put(rowsUpdate);
 
-    Scan scan = new Scan();
-    scan.addFamily(CONTENTS_FAMILY);
-    ResultScanner scanner = table.getScanner(scan);
-    int nbRows = 0;
-    for (@SuppressWarnings("unused")
-    Result row : scanner)
-      nbRows++;
-    assertEquals(NB_BATCH_ROWS * 10, nbRows);
+      Scan scan = new Scan();
+      scan.addFamily(CONTENTS_FAMILY);
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        int nbRows = 0;
+        for (@SuppressWarnings("unused")
+                Result row : scanner) {
+          nbRows++;
+        }
+        assertEquals(NB_BATCH_ROWS * 10, nbRows);
+      }
+    }
   }
 
   @Test
@@ -4114,88 +4170,83 @@ public class TestFromClientSide {
     final byte [] FAM1 = Bytes.toBytes("fam1");
     final byte [] FAM2 = Bytes.toBytes("fam2");
     // Open table
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-      new byte [][] {FAM1, FAM2});
-    // Insert some values
-    Put put = new Put(ROW);
-    put.addColumn(FAM1, Bytes.toBytes("letters"), Bytes.toBytes("abcdefg"));
-    table.put(put);
-    try {
-      Thread.sleep(1000);
-    } catch (InterruptedException i) {
-      //ignore
-    }
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
+      new byte [][] {FAM1, FAM2})) {
+      // Insert some values
+      Put put = new Put(ROW);
+      put.addColumn(FAM1, Bytes.toBytes("letters"), Bytes.toBytes("abcdefg"));
+      table.put(put);
+      try {
+        Thread.sleep(1000);
+      } catch (InterruptedException i) {
+        //ignore
+      }
 
-    put = new Put(ROW);
-    put.addColumn(FAM1, Bytes.toBytes("numbers"), Bytes.toBytes("123456"));
-    table.put(put);
+      put = new Put(ROW);
+      put.addColumn(FAM1, Bytes.toBytes("numbers"), Bytes.toBytes("123456"));
+      table.put(put);
 
-    try {
-      Thread.sleep(1000);
-    } catch (InterruptedException i) {
-      //ignore
-    }
+      try {
+        Thread.sleep(1000);
+      } catch (InterruptedException i) {
+        //ignore
+      }
 
-    put = new Put(ROW);
-    put.addColumn(FAM2, Bytes.toBytes("letters"), Bytes.toBytes("hijklmnop"));
-    table.put(put);
+      put = new Put(ROW);
+      put.addColumn(FAM2, Bytes.toBytes("letters"), Bytes.toBytes("hijklmnop"));
+      table.put(put);
 
-    long times[] = new long[3];
+      long[] times = new long[3];
 
-    // First scan the memstore
+      // First scan the memstore
 
-    Scan scan = new Scan();
-    scan.addFamily(FAM1);
-    scan.addFamily(FAM2);
-    ResultScanner s = table.getScanner(scan);
-    try {
-      int index = 0;
-      Result r = null;
-      while ((r = s.next()) != null) {
-        for(Cell key : r.rawCells()) {
-          times[index++] = key.getTimestamp();
+      Scan scan = new Scan();
+      scan.addFamily(FAM1);
+      scan.addFamily(FAM2);
+      try (ResultScanner s = table.getScanner(scan)) {
+        int index = 0;
+        Result r = null;
+        while ((r = s.next()) != null) {
+          for (Cell key : r.rawCells()) {
+            times[index++] = key.getTimestamp();
+          }
         }
       }
-    } finally {
-      s.close();
-    }
-    for (int i = 0; i < times.length - 1; i++) {
-      for (int j = i + 1; j < times.length; j++) {
-        assertTrue(times[j] > times[i]);
+      for (int i = 0; i < times.length - 1; i++) {
+        for (int j = i + 1; j < times.length; j++) {
+          assertTrue(times[j] > times[i]);
+        }
       }
-    }
 
-    // Flush data to disk and try again
-    TEST_UTIL.flush();
+      // Flush data to disk and try again
+      TEST_UTIL.flush();
 
-    // Reset times
-    for(int i=0;i<times.length;i++) {
-      times[i] = 0;
-    }
+      // Reset times
+      for (int i = 0; i < times.length; i++) {
+        times[i] = 0;
+      }
 
-    try {
-      Thread.sleep(1000);
-    } catch (InterruptedException i) {
-      //ignore
-    }
-    scan = new Scan();
-    scan.addFamily(FAM1);
-    scan.addFamily(FAM2);
-    s = table.getScanner(scan);
-    try {
-      int index = 0;
-      Result r = null;
-      while ((r = s.next()) != null) {
-        for(Cell key : r.rawCells()) {
-          times[index++] = key.getTimestamp();
-        }
+      try {
+        Thread.sleep(1000);
+      } catch (InterruptedException i) {
+        //ignore
       }
-    } finally {
-      s.close();
-    }
-    for (int i = 0; i < times.length - 1; i++) {
-      for (int j = i + 1; j < times.length; j++) {
-        assertTrue(times[j] > times[i]);
+      scan = new Scan();
+      scan.addFamily(FAM1);
+      scan.addFamily(FAM2);
+      try (ResultScanner s = table.getScanner(scan)) {
+        int index = 0;
+        Result r = null;
+        while ((r = s.next()) != null) {
+          for (Cell key : r.rawCells()) {
+            times[index++] = key.getTimestamp();
+          }
+        }
+        for (int i = 0; i < times.length - 1; i++) {
+          for (int j = i + 1; j < times.length; j++) {
+            assertTrue(times[j] > times[i]);
+          }
+        }
       }
     }
   }
@@ -4209,20 +4260,21 @@ public class TestFromClientSide {
     for (int i = 0; i < tables.length; i++) {
       TEST_UTIL.createTable(tables[i], FAMILY);
     }
-    Admin admin = TEST_UTIL.getAdmin();
-    List<TableDescriptor> ts = admin.listTableDescriptors();
-    HashSet<TableDescriptor> result = new HashSet<>(ts);
-    int size = result.size();
-    assertTrue(size >= tables.length);
-    for (int i = 0; i < tables.length && i < size; i++) {
-      boolean found = false;
-      for (int j = 0; j < ts.size(); j++) {
-        if (ts.get(j).getTableName().equals(tables[i])) {
-          found = true;
-          break;
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      List<TableDescriptor> ts = admin.listTableDescriptors();
+      HashSet<TableDescriptor> result = new HashSet<>(ts);
+      int size = result.size();
+      assertTrue(size >= tables.length);
+      for (int i = 0; i < tables.length && i < size; i++) {
+        boolean found = false;
+        for (int j = 0; j < ts.size(); j++) {
+          if (ts.get(j).getTableName().equals(tables[i])) {
+            found = true;
+            break;
+          }
         }
+        assertTrue("Not found: " + tables[i], found);
       }
-      assertTrue("Not found: " + tables[i], found);
     }
   }
 
@@ -4234,12 +4286,12 @@ public class TestFromClientSide {
   public void testUnmanagedHConnection() throws IOException {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
-    Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
-    Table t = conn.getTable(tableName);
-    Admin admin = conn.getAdmin();
-    assertTrue(admin.tableExists(tableName));
-    assertTrue(t.get(new Get(ROW)).isEmpty());
-    admin.close();
+    try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
+        Table t = conn.getTable(tableName);
+        Admin admin = conn.getAdmin()) {
+      assertTrue(admin.tableExists(tableName));
+      assertTrue(t.get(new Get(ROW)).isEmpty());
+    }
   }
 
   /**
@@ -4250,29 +4302,30 @@ public class TestFromClientSide {
   public void testUnmanagedHConnectionReconnect() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
-    Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
-    Table t = conn.getTable(tableName);
-    try (Admin admin = conn.getAdmin()) {
-      assertTrue(admin.tableExists(tableName));
-      assertTrue(t.get(new Get(ROW)).isEmpty());
-    }
-
-    // stop the master
-    MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
-    cluster.stopMaster(0, false);
-    cluster.waitOnMaster(0);
-
-    // start up a new master
-    cluster.startMaster();
-    assertTrue(cluster.waitForActiveAndReadyMaster());
+    try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
+      try (Table t = conn.getTable(tableName);
+           Admin admin = conn.getAdmin()) {
+        assertTrue(admin.tableExists(tableName));
+        assertTrue(t.get(new Get(ROW)).isEmpty());
+      }
 
-    // test that the same unmanaged connection works with a new
-    // Admin and can connect to the new master;
-    boolean tablesOnMaster = LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration());
-    try (Admin admin = conn.getAdmin()) {
-      assertTrue(admin.tableExists(tableName));
-      assertTrue(admin.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
-          .getLiveServerMetrics().size() == SLAVES + (tablesOnMaster ? 1 : 0));
+      // stop the master
+      MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
+      cluster.stopMaster(0, false);
+      cluster.waitOnMaster(0);
+
+      // start up a new master
+      cluster.startMaster();
+      assertTrue(cluster.waitForActiveAndReadyMaster());
+
+      // test that the same unmanaged connection works with a new
+      // Admin and can connect to the new master;
+      boolean tablesOnMaster = LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration());
+      try (Admin admin = conn.getAdmin()) {
+        assertTrue(admin.tableExists(tableName));
+        assertTrue(admin.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
+                .getLiveServerMetrics().size() == SLAVES + (tablesOnMaster ? 1 : 0));
+      }
     }
   }
 
@@ -4284,72 +4337,74 @@ public class TestFromClientSide {
     final byte[] attrValue = Bytes.toBytes("somevalue");
     byte[] value = Bytes.toBytes("value");
 
-    Table a = TEST_UTIL.createTable(tableAname, HConstants.CATALOG_FAMILY);
-    Table b = TEST_UTIL.createTable(tableBname, HConstants.CATALOG_FAMILY);
-    Put put = new Put(ROW);
-    put.addColumn(HConstants.CATALOG_FAMILY, null, value);
-    a.put(put);
-
-    // open a new connection to A and a connection to b
-    Table newA = TEST_UTIL.getConnection().getTable(tableAname);
-
-    // copy data from A to B
-    Scan scan = new Scan();
-    scan.addFamily(HConstants.CATALOG_FAMILY);
-    ResultScanner s = newA.getScanner(scan);
-    try {
-      for (Result r : s) {
-        put = new Put(r.getRow());
-        put.setDurability(Durability.SKIP_WAL);
-        for (Cell kv : r.rawCells()) {
-          put.add(kv);
+    try (Table a = TEST_UTIL.createTable(tableAname, HConstants.CATALOG_FAMILY);
+        Table b = TEST_UTIL.createTable(tableBname, HConstants.CATALOG_FAMILY)) {
+      Put put = new Put(ROW);
+      put.addColumn(HConstants.CATALOG_FAMILY, null, value);
+      a.put(put);
+
+      // open a new connection to A and a connection to b
+      try (Table newA = TEST_UTIL.getConnection().getTable(tableAname)) {
+
+        // copy data from A to B
+        Scan scan = new Scan();
+        scan.addFamily(HConstants.CATALOG_FAMILY);
+        try (ResultScanner s = newA.getScanner(scan)) {
+          for (Result r : s) {
+            put = new Put(r.getRow());
+            put.setDurability(Durability.SKIP_WAL);
+            for (Cell kv : r.rawCells()) {
+              put.add(kv);
+            }
+            b.put(put);
+          }
         }
-        b.put(put);
       }
-    } finally {
-      s.close();
-    }
 
-    // Opening a new connection to A will cause the tables to be reloaded
-    Table anotherA = TEST_UTIL.getConnection().getTable(tableAname);
-    Get get = new Get(ROW);
-    get.addFamily(HConstants.CATALOG_FAMILY);
-    anotherA.get(get);
+      // Opening a new connection to A will cause the tables to be reloaded
+      try (Table anotherA = TEST_UTIL.getConnection().getTable(tableAname)) {
+        Get get = new Get(ROW);
+        get.addFamily(HConstants.CATALOG_FAMILY);
+        anotherA.get(get);
+      }
 
-    // We can still access A through newA because it has the table information
-    // cached. And if it needs to recalibrate, that will cause the information
-    // to be reloaded.
+      // We can still access A through newA because it has the table information
+      // cached. And if it needs to recalibrate, that will cause the information
+      // to be reloaded.
+
+      // Test user metadata
+      try (Admin admin = TEST_UTIL.getAdmin()) {
+        // make a modifiable descriptor
+        HTableDescriptor desc = new HTableDescriptor(a.getTableDescriptor());
+        // offline the table
+        admin.disableTable(tableAname);
+        // add a user attribute to HTD
+        desc.setValue(attrName, attrValue);
+        // add a user attribute to HCD
+        for (HColumnDescriptor c : desc.getFamilies()) {
+          c.setValue(attrName, attrValue);
+        }
+        // update metadata for all regions of this table
+        admin.modifyTable(desc);
+        // enable the table
+        admin.enableTable(tableAname);
+      }
 
-    // Test user metadata
-    Admin admin = TEST_UTIL.getAdmin();
-    // make a modifiable descriptor
-    HTableDescriptor desc = new HTableDescriptor(a.getTableDescriptor());
-    // offline the table
-    admin.disableTable(tableAname);
-    // add a user attribute to HTD
-    desc.setValue(attrName, attrValue);
-    // add a user attribute to HCD
-    for (HColumnDescriptor c : desc.getFamilies())
-      c.setValue(attrName, attrValue);
-    // update metadata for all regions of this table
-    admin.modifyTable(desc);
-    // enable the table
-    admin.enableTable(tableAname);
-
-    // Test that attribute changes were applied
-    desc = a.getTableDescriptor();
-    assertEquals("wrong table descriptor returned", desc.getTableName(), tableAname);
-    // check HTD attribute
-    value = desc.getValue(attrName);
-    assertFalse("missing HTD attribute value", value == null);
-    assertFalse("HTD attribute value is incorrect",
-      Bytes.compareTo(value, attrValue) != 0);
-    // check HCD attribute
-    for (HColumnDescriptor c : desc.getFamilies()) {
-      value = c.getValue(attrName);
-      assertFalse("missing HCD attribute value", value == null);
-      assertFalse("HCD attribute value is incorrect",
-        Bytes.compareTo(value, attrValue) != 0);
+      // Test that attribute changes were applied
+      HTableDescriptor desc = a.getTableDescriptor();
+      assertEquals("wrong table descriptor returned", desc.getTableName(), tableAname);
+      // check HTD attribute
+      value = desc.getValue(attrName);
+      assertFalse("missing HTD attribute value", value == null);
+      assertFalse("HTD attribute value is incorrect",
+              Bytes.compareTo(value, attrValue) != 0);
+      // check HCD attribute
+      for (HColumnDescriptor c : desc.getFamilies()) {
+        value = c.getValue(attrName);
+        assertFalse("missing HCD attribute value", value == null);
+        assertFalse("HCD attribute value is incorrect",
+                Bytes.compareTo(value, attrValue) != 0);
+      }
     }
   }
 
@@ -4485,77 +4540,79 @@ public class TestFromClientSide {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     final byte [] ROW1 = Bytes.toBytes("testRow1");
 
-    Table t = TEST_UTIL.createTable(tableName, FAMILY);
-    Put p = new Put(ROW);
-    p.addColumn(FAMILY, QUALIFIER, VALUE);
-    MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, p);
-
-    p = new Put(ROW1);
-    p.addColumn(FAMILY, QUALIFIER, VALUE);
-    MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, p);
-
-    MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder();
-    mrmBuilder.addMutationRequest(m1);
-    mrmBuilder.addMutationRequest(m2);
-    MutateRowsRequest mrm = mrmBuilder.build();
-    CoprocessorRpcChannel channel = t.coprocessorService(ROW);
-    MultiRowMutationService.BlockingInterface service =
-       MultiRowMutationService.newBlockingStub(channel);
-    service.mutateRows(null, mrm);
-    Get g = new Get(ROW);
-    Result r = t.get(g);
-    assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIER)));
-    g = new Get(ROW1);
-    r = t.get(g);
-    assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIER)));
+    try (Table t = TEST_UTIL.createTable(tableName, FAMILY)) {
+      Put p = new Put(ROW);
+      p.addColumn(FAMILY, QUALIFIER, VALUE);
+      MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, p);
+
+      p = new Put(ROW1);
+      p.addColumn(FAMILY, QUALIFIER, VALUE);
+      MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, p);
+
+      MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder();
+      mrmBuilder.addMutationRequest(m1);
+      mrmBuilder.addMutationRequest(m2);
+      MutateRowsRequest mrm = mrmBuilder.build();
+      CoprocessorRpcChannel channel = t.coprocessorService(ROW);
+      MultiRowMutationService.BlockingInterface service =
+              MultiRowMutationService.newBlockingStub(channel);
+      service.mutateRows(null, mrm);
+      Get g = new Get(ROW);
+      Result r = t.get(g);
+      assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIER)));
+      g = new Get(ROW1);
+      r = t.get(g);
+      assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIER)));
+    }
   }
 
   @Test
   public void testRowMutation() throws Exception {
     LOG.info("Starting testRowMutation");
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table t = TEST_UTIL.createTable(tableName, FAMILY);
-    byte [][] QUALIFIERS = new byte [][] {
-        Bytes.toBytes("a"), Bytes.toBytes("b")
-    };
-    RowMutations arm = new RowMutations(ROW);
-    Put p = new Put(ROW);
-    p.addColumn(FAMILY, QUALIFIERS[0], VALUE);
-    arm.add(p);
-    t.mutateRow(arm);
-
-    Get g = new Get(ROW);
-    Result r = t.get(g);
-    assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIERS[0])));
-
-    arm = new RowMutations(ROW);
-    p = new Put(ROW);
-    p.addColumn(FAMILY, QUALIFIERS[1], VALUE);
-    arm.add(p);
-    Delete d = new Delete(ROW);
-    d.addColumns(FAMILY, QUALIFIERS[0]);
-    arm.add(d);
-    // TODO: Trying mutateRow again.  The batch was failing with a one try only.
-    t.mutateRow(arm);
-    r = t.get(g);
-    assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIERS[1])));
-    assertNull(r.getValue(FAMILY, QUALIFIERS[0]));
-
-    //Test that we get a region level exception
-    try {
+    try (Table t = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] QUALIFIERS = new byte[][]{
+              Bytes.toBytes("a"), Bytes.toBytes("b")
+      };
+      RowMutations arm = new RowMutations(ROW);
+      Put p = new Put(ROW);
+      p.addColumn(FAMILY, QUALIFIERS[0], VALUE);
+      arm.add(p);
+      t.mutateRow(arm);
+
+      Get g = new Get(ROW);
+      Result r = t.get(g);
+      assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIERS[0])));
+
       arm = new RowMutations(ROW);
       p = new Put(ROW);
-      p.addColumn(new byte[]{'b', 'o', 'g', 'u', 's'}, QUALIFIERS[0], VALUE);
+      p.addColumn(FAMILY, QUALIFIERS[1], VALUE);
       arm.add(p);
+      Delete d = new Delete(ROW);
+      d.addColumns(FAMILY, QUALIFIERS[0]);
+      arm.add(d);
+      // TODO: Trying mutateRow again.  The batch was failing with a one try only.
       t.mutateRow(arm);
-      fail("Expected NoSuchColumnFamilyException");
-    } catch(RetriesExhaustedWithDetailsException e) {
-      for(Throwable rootCause: e.getCauses()){
-        if(rootCause instanceof NoSuchColumnFamilyException){
-          return;
+      r = t.get(g);
+      assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIERS[1])));
+      assertNull(r.getValue(FAMILY, QUALIFIERS[0]));
+
+      //Test that we get a region level exception
+      try {
+        arm = new RowMutations(ROW);
+        p = new Put(ROW);
+        p.addColumn(new byte[]{'b', 'o', 'g', 'u', 's'}, QUALIFIERS[0], VALUE);
+        arm.add(p);
+        t.mutateRow(arm);
+        fail("Expected NoSuchColumnFamilyException");
+      } catch (RetriesExhaustedWithDetailsException e) {
+        for (Throwable rootCause : e.getCauses()) {
+          if (rootCause instanceof NoSuchColumnFamilyException) {
+            return;
+          }
         }
+        throw e;
       }
-      throw e;
     }
   }
 
@@ -4563,93 +4620,96 @@ public class TestFromClientSide {
   public void testBatchAppendWithReturnResultFalse() throws Exception {
     LOG.info("Starting testBatchAppendWithReturnResultFalse");
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
-    Append append1 = new Append(Bytes.toBytes("row1"));
-    append1.setReturnResults(false);
-    append1.addColumn(FAMILY, Bytes.toBytes("f1"), Bytes.toBytes("value1"));
-    Append append2 = new Append(Bytes.toBytes("row1"));
-    append2.setReturnResults(false);
-    append2.addColumn(FAMILY, Bytes.toBytes("f1"), Bytes.toBytes("value2"));
-    List<Append> appends = new ArrayList<>();
-    appends.add(append1);
-    appends.add(append2);
-    Object[] results = new Object[2];
-    table.batch(appends, results);
-    assertTrue(results.length == 2);
-    for(Object r : results) {
-      Result result = (Result)r;
-      assertTrue(result.isEmpty());
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
+      Append append1 = new Append(Bytes.toBytes("row1"));
+      append1.setReturnResults(false);
+      append1.addColumn(FAMILY, Bytes.toBytes("f1"), Bytes.toBytes("value1"));
+      Append append2 = new Append(Bytes.toBytes("row1"));
+      append2.setReturnResults(false);
+      append2.addColumn(FAMILY, Bytes.toBytes("f1"), Bytes.toBytes("value2"));
+      List<Append> appends = new ArrayList<>();
+      appends.add(append1);
+      appends.add(append2);
+      Object[] results = new Object[2];
+      table.batch(appends, results);
+      assertTrue(results.length == 2);
+      for (Object r : results) {
+        Result result = (Result) r;
+        assertTrue(result.isEmpty());
+      }
     }
-    table.close();
   }
 
   @Test
   public void testAppend() throws Exception {
     LOG.info("Starting testAppend");
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table t = TEST_UTIL.createTable(tableName, FAMILY);
-    byte[] v1 = Bytes.toBytes("42");
-    byte[] v2 = Bytes.toBytes("23");
-    byte [][] QUALIFIERS = new byte [][] {
-        Bytes.toBytes("b"), Bytes.toBytes("a"), Bytes.toBytes("c")
-    };
-    Append a = new Append(ROW);
-    a.addColumn(FAMILY, QUALIFIERS[0], v1);
-    a.addColumn(FAMILY, QUALIFIERS[1], v2);
-    a.setReturnResults(false);
-    assertEmptyResult(t.append(a));
-
-    a = new Append(ROW);
-    a.addColumn(FAMILY, QUALIFIERS[0], v2);
-    a.addColumn(FAMILY, QUALIFIERS[1], v1);
-    a.addColumn(FAMILY, QUALIFIERS[2], v2);
-    Result r = t.append(a);
-    assertEquals(0, Bytes.compareTo(Bytes.add(v1, v2), r.getValue(FAMILY, QUALIFIERS[0])));
-    assertEquals(0, Bytes.compareTo(Bytes.add(v2, v1), r.getValue(FAMILY, QUALIFIERS[1])));
-    // QUALIFIERS[2] previously not exist, verify both value and timestamp are correct
-    assertEquals(0, Bytes.compareTo(v2, r.getValue(FAMILY, QUALIFIERS[2])));
-    assertEquals(r.getColumnLatestCell(FAMILY, QUALIFIERS[0]).getTimestamp(),
-        r.getColumnLatestCell(FAMILY, QUALIFIERS[2]).getTimestamp());
+    try (Table t = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[] v1 = Bytes.toBytes("42");
+      byte[] v2 = Bytes.toBytes("23");
+      byte[][] QUALIFIERS = new byte[][]{
+              Bytes.toBytes("b"), Bytes.toBytes("a"), Bytes.toBytes("c")
+      };
+      Append a = new Append(ROW);
+      a.addColumn(FAMILY, QUALIFIERS[0], v1);
+      a.addColumn(FAMILY, QUALIFIERS[1], v2);
+      a.setReturnResults(false);
+      assertEmptyResult(t.append(a));
+
+      a = new Append(ROW);
+      a.addColumn(FAMILY, QUALIFIERS[0], v2);
+      a.addColumn(FAMILY, QUALIFIERS[1], v1);
+      a.addColumn(FAMILY, QUALIFIERS[2], v2);
+      Result r = t.append(a);
+      assertEquals(0, Bytes.compareTo(Bytes.add(v1, v2), r.getValue(FAMILY, QUALIFIERS[0])));
+      assertEquals(0, Bytes.compareTo(Bytes.add(v2, v1), r.getValue(FAMILY, QUALIFIERS[1])));
+      // QUALIFIERS[2] previously not exist, verify both value and timestamp are correct
+      assertEquals(0, Bytes.compareTo(v2, r.getValue(FAMILY, QUALIFIERS[2])));
+      assertEquals(r.getColumnLatestCell(FAMILY, QUALIFIERS[0]).getTimestamp(),
+              r.getColumnLatestCell(FAMILY, QUALIFIERS[2]).getTimestamp());
+    }
   }
   private List<Result> doAppend(final boolean walUsed) throws IOException {
     LOG.info("Starting testAppend, walUsed is " + walUsed);
-    final TableName TABLENAME = TableName.valueOf(walUsed ? "testAppendWithWAL" : "testAppendWithoutWAL");
-    Table t = TEST_UTIL.createTable(TABLENAME, FAMILY);
-    final byte[] row1 = Bytes.toBytes("c");
-    final byte[] row2 = Bytes.toBytes("b");
-    final byte[] row3 = Bytes.toBytes("a");
-    final byte[] qual = Bytes.toBytes("qual");
-    Put put_0 = new Put(row2);
-    put_0.addColumn(FAMILY, qual, Bytes.toBytes("put"));
-    Put put_1 = new Put(row3);
-    put_1.addColumn(FAMILY, qual, Bytes.toBytes("put"));
-    Append append_0 = new Append(row1);
-    append_0.addColumn(FAMILY, qual, Bytes.toBytes("i"));
-    Append append_1 = new Append(row1);
-    append_1.addColumn(FAMILY, qual, Bytes.toBytes("k"));
-    Append append_2 = new Append(row1);
-    append_2.addColumn(FAMILY, qual, Bytes.toBytes("e"));
-    if (!walUsed) {
-      append_2.setDurability(Durability.SKIP_WAL);
-    }
-    Append append_3 = new Append(row1);
-    append_3.addColumn(FAMILY, qual, Bytes.toBytes("a"));
-    Scan s = new Scan();
-    s.setCaching(1);
-    t.append(append_0);
-    t.put(put_0);
-    t.put(put_1);
-    List<Result> results = new LinkedList<>();
-    try (ResultScanner scanner = t.getScanner(s)) {
-      t.append(append_1);
-      t.append(append_2);
-      t.append(append_3);
-      for (Result r : scanner) {
-        results.add(r);
+    final TableName TABLENAME =
+            TableName.valueOf(walUsed ? "testAppendWithWAL" : "testAppendWithoutWAL");
+    try (Table t = TEST_UTIL.createTable(TABLENAME, FAMILY)) {
+      final byte[] row1 = Bytes.toBytes("c");
+      final byte[] row2 = Bytes.toBytes("b");
+      final byte[] row3 = Bytes.toBytes("a");
+      final byte[] qual = Bytes.toBytes("qual");
+      Put put_0 = new Put(row2);
+      put_0.addColumn(FAMILY, qual, Bytes.toBytes("put"));
+      Put put_1 = new Put(row3);
+      put_1.addColumn(FAMILY, qual, Bytes.toBytes("put"));
+      Append append_0 = new Append(row1);
+      append_0.addColumn(FAMILY, qual, Bytes.toBytes("i"));
+      Append append_1 = new Append(row1);
+      append_1.addColumn(FAMILY, qual, Bytes.toBytes("k"));
+      Append append_2 = new Append(row1);
+      append_2.addColumn(FAMILY, qual, Bytes.toBytes("e"));
+      if (!walUsed) {
+        append_2.setDurability(Durability.SKIP_WAL);
+      }
+      Append append_3 = new Append(row1);
+      append_3.addColumn(FAMILY, qual, Bytes.toBytes("a"));
+      Scan s = new Scan();
+      s.setCaching(1);
+      t.append(append_0);
+      t.put(put_0);
+      t.put(put_1);
+      List<Result> results = new LinkedList<>();
+      try (ResultScanner scanner = t.getScanner(s)) {
+        t.append(append_1);
+        t.append(append_2);
+        t.append(append_3);
+        for (Result r : scanner) {
+          results.add(r);
+        }
       }
+      TEST_UTIL.deleteTable(TABLENAME);
+      return results;
     }
-    TEST_UTIL.deleteTable(TABLENAME);
-    return results;
   }
 
   @Test
@@ -4664,10 +4724,14 @@ public class TestFromClientSide {
       for (int j = 0; j != resultWithWal.rawCells().length; ++j) {
         Cell cellWithWal = resultWithWal.rawCells()[j];
         Cell cellWithoutWal = resultWithoutWal.rawCells()[j];
-        assertTrue(Bytes.equals(CellUtil.cloneRow(cellWithWal), CellUtil.cloneRow(cellWithoutWal)));
-        assertTrue(Bytes.equals(CellUtil.cloneFamily(cellWithWal), CellUtil.cloneFamily(cellWithoutWal)));
-        assertTrue(Bytes.equals(CellUtil.cloneQualifier(cellWithWal), CellUtil.cloneQualifier(cellWithoutWal)));
-        assertTrue(Bytes.equals(CellUtil.cloneValue(cellWithWal), CellUtil.cloneValue(cellWithoutWal)));
+        assertTrue(Bytes.equals(CellUtil.cloneRow(cellWithWal),
+                CellUtil.cloneRow(cellWithoutWal)));
+        assertTrue(Bytes.equals(CellUtil.cloneFamily(cellWithWal),
+                CellUtil.cloneFamily(cellWithoutWal)));
+        assertTrue(Bytes.equals(CellUtil.cloneQualifier(cellWithWal),
+                CellUtil.cloneQualifier(cellWithoutWal)));
+        assertTrue(Bytes.equals(CellUtil.cloneValue(cellWithWal),
+                CellUtil.cloneValue(cellWithoutWal)));
       }
     }
   }
@@ -4682,28 +4746,30 @@ public class TestFromClientSide {
     conf.set(HConstants.HBASE_CLIENT_IPC_POOL_TYPE, "round-robin");
     conf.setInt(HConstants.HBASE_CLIENT_IPC_POOL_SIZE, poolSize);
 
-    Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY }, Integer.MAX_VALUE);
-
-    final long ts = EnvironmentEdgeManager.currentTime();
-    Get get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readAllVersions();
-
-    for (int versions = 1; versions <= numVersions; versions++) {
-      Put put = new Put(ROW);
-      put.addColumn(FAMILY, QUALIFIER, ts + versions, VALUE);
-      table.put(put);
+    try (Table table =
+                 TEST_UTIL.createTable(tableName, new byte[][] { FAMILY }, Integer.MAX_VALUE)) {
 
-      Result result = table.get(get);
-      NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY)
-          .get(QUALIFIER);
-
-      assertEquals("The number of versions of '" + Bytes.toString(FAMILY) + ":"
-          + Bytes.toString(QUALIFIER) + " did not match", versions, navigableMap.size());
-      for (Map.Entry<Long, byte[]> entry : navigableMap.entrySet()) {
-        assertTrue("The value at time " + entry.getKey()
-            + " did not match what was put",
-            Bytes.equals(VALUE, entry.getValue()));
+      final long ts = EnvironmentEdgeManager.currentTime();
+      Get get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readAllVersions();
+
+      for (int versions = 1; versions <= numVersions; versions++) {
+        Put put = new Put(ROW);
+        put.addColumn(FAMILY, QUALIFIER, ts + versions, VALUE);
+        table.put(put);
+
+        Result result = table.get(get);
+        NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY)
+                .get(QUALIFIER);
+
+        assertEquals("The number of versions of '" + Bytes.toString(FAMILY) + ":"
+                + Bytes.toString(QUALIFIER) + " did not match", versions, navigableMap.size());
+        for (Map.Entry<Long, byte[]> entry : navigableMap.entrySet()) {
+          assertTrue("The value at time " + entry.getKey()
+                          + " did not match what was put",
+                  Bytes.equals(VALUE, entry.getValue()));
+        }
       }
     }
   }
@@ -4718,76 +4784,77 @@ public class TestFromClientSide {
     conf.set(HConstants.HBASE_CLIENT_IPC_POOL_TYPE, "thread-local");
     conf.setInt(HConstants.HBASE_CLIENT_IPC_POOL_SIZE, poolSize);
 
-    final Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY },  3);
-
-    final long ts = EnvironmentEdgeManager.currentTime();
-    final Get get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readAllVersions();
-
-    for (int versions = 1; versions <= numVersions; versions++) {
-      Put put = new Put(ROW);
-      put.addColumn(FAMILY, QUALIFIER, ts + versions, VALUE);
-      table.put(put);
+    try (final Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY },  3)) {
 
-      Result result = table.get(get);
-      NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY)
-          .get(QUALIFIER);
-
-      assertEquals("The number of versions of '" + Bytes.toString(FAMILY) + ":"
-          + Bytes.toString(QUALIFIER) + " did not match", versions, navigableMap.size());
-      for (Map.Entry<Long, byte[]> entry : navigableMap.entrySet()) {
-        assertTrue("The value at time " + entry.getKey()
-            + " did not match what was put",
-            Bytes.equals(VALUE, entry.getValue()));
+      final long ts = EnvironmentEdgeManager.currentTime();
+      final Get get = new Get(ROW);
+      get.addColumn(FAMILY, QUALIFIER);
+      get.readAllVersions();
+
+      for (int versions = 1; versions <= numVersions; versions++) {
+        Put put = new Put(ROW);
+        put.addColumn(FAMILY, QUALIFIER, ts + versions, VALUE);
+        table.put(put);
+
+        Result result = table.get(get);
+        NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY)
+                .get(QUALIFIER);
+
+        assertEquals("The number of versions of '" + Bytes.toString(FAMILY) + ":"
+                + Bytes.toString(QUALIFIER) + " did not match", versions, navigableMap.size());
+        for (Map.Entry<Long, byte[]> entry : navigableMap.entrySet()) {
+          assertTrue("The value at time " + entry.getKey()
+                          + " did not match what was put",
+                  Bytes.equals(VALUE, entry.getValue()));
+        }
       }
-    }
 
-    final Object waitLock = new Object();
-    ExecutorService executorService = Executors.newFixedThreadPool(numVersions);
-    final AtomicReference<AssertionError> error = new AtomicReference<>(null);
-    for (int versions = numVersions; versions < numVersions * 2; versions++) {
-      final int versionsCopy = versions;
-      executorService.submit(new Callable<Void>() {
-        @Override
-        public Void call() {
-          try {
-            Put put = new Put(ROW);
-            put.addColumn(FAMILY, QUALIFIER, ts + versionsCopy, VALUE);
-            table.put(put);
-
-            Result result = table.get(get);
-            NavigableMap<Long, byte[]> navigableMap = result.getMap()
-                .get(FAMILY).get(QUALIFIER);
-
-            assertEquals("The number of versions of '" + Bytes.toString(FAMILY) + ":"
-                + Bytes.toString(QUALIFIER) + " did not match " + versionsCopy, versionsCopy,
-                navigableMap.size());
-            for (Map.Entry<Long, byte[]> entry : navigableMap.entrySet()) {
-              assertTrue("The value at time " + entry.getKey()
-                  + " did not match what was put",
-                  Bytes.equals(VALUE, entry.getValue()));
-            }
-            synchronized (waitLock) {
-              waitLock.wait();
+      final Object waitLock = new Object();
+      ExecutorService executorService = Executors.newFixedThreadPool(numVersions);
+      final AtomicReference<AssertionError> error = new AtomicReference<>(null);
+      for (int versions = numVersions; versions < numVersions * 2; versions++) {
+        final int versionsCopy = versions;
+        executorService.submit(new Callable<Void>() {
+          @Override
+          public Void call() {
+            try {
+              Put put = new Put(ROW);
+              put.addColumn(FAMILY, QUALIFIER, ts + versionsCopy, VALUE);
+              table.put(put);
+
+              Result result = table.get(get);
+              NavigableMap<Long, byte[]> navigableMap = result.getMap()
+                      .get(FAMILY).get(QUALIFIER);
+
+              assertEquals("The number of versions of '" + Bytes.toString(FAMILY) + ":"
+                      + Bytes.toString(QUALIFIER) + " did not match " + versionsCopy, versionsCopy,
+                      navigableMap.size());
+              for (Map.Entry<Long, byte[]> entry : navigableMap.entrySet()) {
+                assertTrue("The value at time " + entry.getKey()
+                                + " did not match what was put",
+                        Bytes.equals(VALUE, entry.getValue()));
+              }
+              synchronized (waitLock) {
+                waitLock.wait();
+              }
+            } catch (Exception e) {
+            } catch (AssertionError e) {
+              // the error happens in a thread, it won't fail the test,
+              // need to pass it to the caller for proper handling.
+              error.set(e);
+              LOG.error(e.toString(), e);
             }
-          } catch (Exception e) {
-          } catch (AssertionError e) {
-            // the error happens in a thread, it won't fail the test,
-            // need to pass it to the caller for proper handling.
-            error.set(e);
-            LOG.error(e.toString(), e);
-          }
 
-          return null;
-        }
-      });
-    }
-    synchronized (waitLock) {
-      waitLock.notifyAll();
+            return null;
+          }
+        });
+      }
+      synchronized (waitLock) {
+        waitLock.notifyAll();
+      }
+      executorService.shutdownNow();
+      assertNull(error.get());
     }
-    executorService.shutdownNow();
-    assertNull(error.get());
   }
 
   @Test
@@ -4795,93 +4862,95 @@ public class TestFromClientSide {
     final byte [] anotherrow = Bytes.toBytes("anotherrow");
     final byte [] value2 = Bytes.toBytes("abcd");
 
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-    Put put1 = new Put(ROW);
-    put1.addColumn(FAMILY, QUALIFIER, VALUE);
-
-    // row doesn't exist, so using non-null value should be considered "not match".
-    boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifEquals(VALUE).thenPut(put1);
-    assertFalse(ok);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      Put put1 = new Put(ROW);
+      put1.addColumn(FAMILY, QUALIFIER, VALUE);
 
-    // row doesn't exist, so using "ifNotExists" should be considered "match".
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifNotExists().thenPut(put1);
-    assertTrue(ok);
+      // row doesn't exist, so using non-null value should be considered "not match".
+      boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifEquals(VALUE).thenPut(put1);
+      assertFalse(ok);
 
-    // row now exists, so using "ifNotExists" should be considered "not match".
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifNotExists().thenPut(put1);
-    assertFalse(ok);
+      // row doesn't exist, so using "ifNotExists" should be considered "match".
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifNotExists().thenPut(put1);
+      assertTrue(ok);
 
-    Put put2 = new Put(ROW);
-    put2.addColumn(FAMILY, QUALIFIER, value2);
+      // row now exists, so using "ifNotExists" should be considered "not match".
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifNotExists().thenPut(put1);
+      assertFalse(ok);
 
-    // row now exists, use the matching value to check
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifEquals(VALUE).thenPut(put2);
-    assertTrue(ok);
+      Put put2 = new Put(ROW);
+      put2.addColumn(FAMILY, QUALIFIER, value2);
 
-    Put put3 = new Put(anotherrow);
-    put3.addColumn(FAMILY, QUALIFIER, VALUE);
+      // row now exists, use the matching value to check
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifEquals(VALUE).thenPut(put2);
+      assertTrue(ok);
 
-    // try to do CheckAndPut on different rows
-    try {
-      table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifEquals(value2).thenPut(put3);
-      fail("trying to check and modify different rows should have failed.");
-    } catch(Exception e) {}
+      Put put3 = new Put(anotherrow);
+      put3.addColumn(FAMILY, QUALIFIER, VALUE);
 
+      // try to do CheckAndPut on different rows
+      try {
+        table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifEquals(value2).thenPut(put3);
+        fail("trying to check and modify different rows should have failed.");
+      } catch (Exception e) {
+      }
+    }
   }
 
   @Test
   public void testCheckAndMutateWithTimeRange() throws IOException {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-    final long ts = System.currentTimeMillis() / 2;
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, ts, VALUE);
-
-    boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .ifNotExists()
-      .thenPut(put);
-    assertTrue(ok);
-
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .timeRange(TimeRange.at(ts + 10000))
-      .ifEquals(VALUE)
-      .thenPut(put);
-    assertFalse(ok);
-
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .timeRange(TimeRange.at(ts))
-      .ifEquals(VALUE)
-      .thenPut(put);
-    assertTrue(ok);
-
-    RowMutations rm = new RowMutations(ROW)
-      .add((Mutation) put);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .timeRange(TimeRange.at(ts + 10000))
-      .ifEquals(VALUE)
-      .thenMutate(rm);
-    assertFalse(ok);
-
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .timeRange(TimeRange.at(ts))
-      .ifEquals(VALUE)
-      .thenMutate(rm);
-    assertTrue(ok);
-
-    Delete delete = new Delete(ROW)
-      .addColumn(FAMILY, QUALIFIER);
-
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .timeRange(TimeRange.at(ts + 10000))
-      .ifEquals(VALUE)
-      .thenDelete(delete);
-    assertFalse(ok);
-
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-      .timeRange(TimeRange.at(ts))
-      .ifEquals(VALUE)
-      .thenDelete(delete);
-    assertTrue(ok);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      final long ts = System.currentTimeMillis() / 2;
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, ts, VALUE);
+
+      boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifNotExists()
+              .thenPut(put);
+      assertTrue(ok);
+
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .timeRange(TimeRange.at(ts + 10000))
+              .ifEquals(VALUE)
+              .thenPut(put);
+      assertFalse(ok);
+
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .timeRange(TimeRange.at(ts))
+              .ifEquals(VALUE)
+              .thenPut(put);
+      assertTrue(ok);
+
+      RowMutations rm = new RowMutations(ROW)
+              .add((Mutation) put);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .timeRange(TimeRange.at(ts + 10000))
+              .ifEquals(VALUE)
+              .thenMutate(rm);
+      assertFalse(ok);
+
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .timeRange(TimeRange.at(ts))
+              .ifEquals(VALUE)
+              .thenMutate(rm);
+      assertTrue(ok);
+
+      Delete delete = new Delete(ROW)
+              .addColumn(FAMILY, QUALIFIER);
+
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .timeRange(TimeRange.at(ts + 10000))
+              .ifEquals(VALUE)
+              .thenDelete(delete);
+      assertFalse(ok);
+
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .timeRange(TimeRange.at(ts))
+              .ifEquals(VALUE)
+              .thenDelete(delete);
+      assertTrue(ok);
+    }
   }
 
   @Test
@@ -4891,99 +4960,102 @@ public class TestFromClientSide {
     final byte [] value3 = Bytes.toBytes("cccc");
     final byte [] value4 = Bytes.toBytes("dddd");
 
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-
-    Put put2 = new Put(ROW);
-    put2.addColumn(FAMILY, QUALIFIER, value2);
-
-    Put put3 = new Put(ROW);
-    put3.addColumn(FAMILY, QUALIFIER, value3);
-
-    // row doesn't exist, so using "ifNotExists" should be considered "match".
-    boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifNotExists().thenPut(put2);
-    assertTrue(ok);
-
-    // cell = "bbbb", using "aaaa" to compare only LESS/LESS_OR_EQUAL/NOT_EQUAL
-    // turns out "match"
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER, value1).thenPut(put2);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.EQUAL, value1).thenPut(put2);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER_OR_EQUAL, value1).thenPut(put2);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS, value1).thenPut(put2);
-    assertTrue(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS_OR_EQUAL, value1).thenPut(put2);
-    assertTrue(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.NOT_EQUAL, value1).thenPut(put3);
-    assertTrue(ok);
-
-    // cell = "cccc", using "dddd" to compare only LARGER/LARGER_OR_EQUAL/NOT_EQUAL
-    // turns out "match"
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS, value4).thenPut(put3);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS_OR_EQUAL, value4).thenPut(put3);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.EQUAL, value4).thenPut(put3);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER, value4).thenPut(put3);
-    assertTrue(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER_OR_EQUAL, value4).thenPut(put3);
-    assertTrue(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.NOT_EQUAL, value4).thenPut(put2);
-    assertTrue(ok);
-
-    // cell = "bbbb", using "bbbb" to compare only GREATER_OR_EQUAL/LESS_OR_EQUAL/EQUAL
-    // turns out "match"
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER, value2).thenPut(put2);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.NOT_EQUAL, value2).thenPut(put2);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS, value2).thenPut(put2);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER_OR_EQUAL, value2).thenPut(put2);
-    assertTrue(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS_OR_EQUAL, value2).thenPut(put2);
-    assertTrue(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.EQUAL, value2).thenPut(put3);
-    assertTrue(ok);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+
+      Put put2 = new Put(ROW);
+      put2.addColumn(FAMILY, QUALIFIER, value2);
+
+      Put put3 = new Put(ROW);
+      put3.addColumn(FAMILY, QUALIFIER, value3);
+
+      // row doesn't exist, so using "ifNotExists" should be considered "match".
+      boolean ok =
+              table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER).ifNotExists().thenPut(put2);
+      assertTrue(ok);
+
+      // cell = "bbbb", using "aaaa" to compare only LESS/LESS_OR_EQUAL/NOT_EQUAL
+      // turns out "match"
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER, value1).thenPut(put2);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.EQUAL, value1).thenPut(put2);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER_OR_EQUAL, value1).thenPut(put2);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS, value1).thenPut(put2);
+      assertTrue(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS_OR_EQUAL, value1).thenPut(put2);
+      assertTrue(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.NOT_EQUAL, value1).thenPut(put3);
+      assertTrue(ok);
+
+      // cell = "cccc", using "dddd" to compare only LARGER/LARGER_OR_EQUAL/NOT_EQUAL
+      // turns out "match"
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS, value4).thenPut(put3);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS_OR_EQUAL, value4).thenPut(put3);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.EQUAL, value4).thenPut(put3);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER, value4).thenPut(put3);
+      assertTrue(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER_OR_EQUAL, value4).thenPut(put3);
+      assertTrue(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.NOT_EQUAL, value4).thenPut(put2);
+      assertTrue(ok);
+
+      // cell = "bbbb", using "bbbb" to compare only GREATER_OR_EQUAL/LESS_OR_EQUAL/EQUAL
+      // turns out "match"
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER, value2).thenPut(put2);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.NOT_EQUAL, value2).thenPut(put2);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS, value2).thenPut(put2);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER_OR_EQUAL, value2).thenPut(put2);
+      assertTrue(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS_OR_EQUAL, value2).thenPut(put2);
+      assertTrue(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.EQUAL, value2).thenPut(put3);
+      assertTrue(ok);
+    }
   }
 
   @Test
   public void testCheckAndDelete() throws IOException {
     final byte [] value1 = Bytes.toBytes("aaaa");
 
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-        FAMILY);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
+        FAMILY)) {
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, value1);
-    table.put(put);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, value1);
+      table.put(put);
 
-    Delete delete = new Delete(ROW);
-    delete.addColumns(FAMILY, QUALIFIER);
+      Delete delete = new Delete(ROW);
+      delete.addColumns(FAMILY, QUALIFIER);
 
-    boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifEquals(value1).thenDelete(delete);
-    assertTrue(ok);
+      boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifEquals(value1).thenDelete(delete);
+      assertTrue(ok);
+    }
   }
 
   @Test
@@ -4993,89 +5065,90 @@ public class TestFromClientSide {
     final byte [] value3 = Bytes.toBytes("cccc");
     final byte [] value4 = Bytes.toBytes("dddd");
 
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-        FAMILY);
-
-    Put put2 = new Put(ROW);
-    put2.addColumn(FAMILY, QUALIFIER, value2);
-    table.put(put2);
-
-    Put put3 = new Put(ROW);
-    put3.addColumn(FAMILY, QUALIFIER, value3);
-
-    Delete delete = new Delete(ROW);
-    delete.addColumns(FAMILY, QUALIFIER);
-
-    // cell = "bbbb", using "aaaa" to compare only LESS/LESS_OR_EQUAL/NOT_EQUAL
-    // turns out "match"
-    boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER, value1).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.EQUAL, value1).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER_OR_EQUAL, value1).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS, value1).thenDelete(delete);
-    assertTrue(ok);
-    table.put(put2);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS_OR_EQUAL, value1).thenDelete(delete);
-    assertTrue(ok);
-    table.put(put2);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.NOT_EQUAL, value1).thenDelete(delete);
-    assertTrue(ok);
-
-    // cell = "cccc", using "dddd" to compare only LARGER/LARGER_OR_EQUAL/NOT_EQUAL
-    // turns out "match"
-    table.put(put3);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS, value4).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS_OR_EQUAL, value4).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.EQUAL, value4).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER, value4).thenDelete(delete);
-    assertTrue(ok);
-    table.put(put3);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER_OR_EQUAL, value4).thenDelete(delete);
-    assertTrue(ok);
-    table.put(put3);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.NOT_EQUAL, value4).thenDelete(delete);
-    assertTrue(ok);
-
-    // cell = "bbbb", using "bbbb" to compare only GREATER_OR_EQUAL/LESS_OR_EQUAL/EQUAL
-    // turns out "match"
-    table.put(put2);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER, value2).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.NOT_EQUAL, value2).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS, value2).thenDelete(delete);
-    assertFalse(ok);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.GREATER_OR_EQUAL, value2).thenDelete(delete);
-    assertTrue(ok);
-    table.put(put2);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.LESS_OR_EQUAL, value2).thenDelete(delete);
-    assertTrue(ok);
-    table.put(put2);
-    ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
-        .ifMatches(CompareOperator.EQUAL, value2).thenDelete(delete);
-    assertTrue(ok);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
+        FAMILY)) {
+
+      Put put2 = new Put(ROW);
+      put2.addColumn(FAMILY, QUALIFIER, value2);
+      table.put(put2);
+
+      Put put3 = new Put(ROW);
+      put3.addColumn(FAMILY, QUALIFIER, value3);
+
+      Delete delete = new Delete(ROW);
+      delete.addColumns(FAMILY, QUALIFIER);
+
+      // cell = "bbbb", using "aaaa" to compare only LESS/LESS_OR_EQUAL/NOT_EQUAL
+      // turns out "match"
+      boolean ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER, value1).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.EQUAL, value1).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER_OR_EQUAL, value1).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS, value1).thenDelete(delete);
+      assertTrue(ok);
+      table.put(put2);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS_OR_EQUAL, value1).thenDelete(delete);
+      assertTrue(ok);
+      table.put(put2);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.NOT_EQUAL, value1).thenDelete(delete);
+      assertTrue(ok);
+
+      // cell = "cccc", using "dddd" to compare only LARGER/LARGER_OR_EQUAL/NOT_EQUAL
+      // turns out "match"
+      table.put(put3);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS, value4).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS_OR_EQUAL, value4).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.EQUAL, value4).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER, value4).thenDelete(delete);
+      assertTrue(ok);
+      table.put(put3);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER_OR_EQUAL, value4).thenDelete(delete);
+      assertTrue(ok);
+      table.put(put3);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.NOT_EQUAL, value4).thenDelete(delete);
+      assertTrue(ok);
+
+      // cell = "bbbb", using "bbbb" to compare only GREATER_OR_EQUAL/LESS_OR_EQUAL/EQUAL
+      // turns out "match"
+      table.put(put2);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER, value2).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.NOT_EQUAL, value2).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS, value2).thenDelete(delete);
+      assertFalse(ok);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.GREATER_OR_EQUAL, value2).thenDelete(delete);
+      assertTrue(ok);
+      table.put(put2);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.LESS_OR_EQUAL, value2).thenDelete(delete);
+      assertTrue(ok);
+      table.put(put2);
+      ok = table.checkAndMutate(ROW, FAMILY).qualifier(QUALIFIER)
+              .ifMatches(CompareOperator.EQUAL, value2).thenDelete(delete);
+      assertTrue(ok);
+    }
   }
 
   /**
@@ -5088,119 +5161,126 @@ public class TestFromClientSide {
 
     // Set up test table:
     // Create table:
-    Table ht = TEST_UTIL.createMultiRegionTable(tableName, FAMILY);
-    int numOfRegions = -1;
-    try (RegionLocator r = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
-      numOfRegions = r.getStartKeys().length;
-    }
-    // Create 3 rows in the table, with rowkeys starting with "zzz*" so that
-    // scan are forced to hit all the regions.
-    Put put1 = new Put(Bytes.toBytes("zzz1"));
-    put1.addColumn(FAMILY, QUALIFIER, VALUE);
-    Put put2 = new Put(Bytes.toBytes("zzz2"));
-    put2.addColumn(FAMILY, QUALIFIER, VALUE);
-    Put put3 = new Put(Bytes.toBytes("zzz3"));
-    put3.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(Arrays.asList(put1, put2, put3));
-
-    Scan scan1 = new Scan();
-    int numRecords = 0;
-    ResultScanner scanner = ht.getScanner(scan1);
-    for(Result result : scanner) {
-      numRecords++;
-    }
-    scanner.close();
-    LOG.info("test data has " + numRecords + " records.");
+    try (Table ht = TEST_UTIL.createMultiRegionTable(tableName, FAMILY)) {
+      int numOfRegions = -1;
+      try (RegionLocator r = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
+        numOfRegions = r.getStartKeys().length;
+      }
+      // Create 3 rows in the table, with rowkeys starting with "zzz*" so that
+      // scan are forced to hit all the regions.
+      Put put1 = new Put(Bytes.toBytes("zzz1"));
+      put1.addColumn(FAMILY, QUALIFIER, VALUE);
+      Put put2 = new Put(Bytes.toBytes("zzz2"));
+      put2.addColumn(FAMILY, QUALIFIER, VALUE);
+      Put put3 = new Put(Bytes.toBytes("zzz3"));
+      put3.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(Arrays.asList(put1, put2, put3));
+
+      Scan scan1 = new Scan();
+      int numRecords = 0;
+      try (ResultScanner scanner = ht.getScanner(scan1)) {
+        for (Result result : scanner) {
+          numRecords++;
+        }
 
-    // by default, scan metrics collection is turned off
-    assertEquals(null, scanner.getScanMetrics());
+        LOG.info("test data has " + numRecords + " records.");
 
-    // turn on scan metrics
-    Scan scan2 = new Scan();
-    scan2.setScanMetricsEnabled(true);
-    scan2.setCaching(numRecords+1);
-    scanner = ht.getScanner(scan2);
-    for (Result result : scanner.next(numRecords - 1)) {
-    }
-    scanner.close();
-    // closing the scanner will set the metrics.
-    assertNotNull(scanner.getScanMetrics());
-
-    // set caching to 1, because metrics are collected in each roundtrip only
-    scan2 = new Scan();
-    scan2.setScanMetricsEnabled(true);
-    scan2.setCaching(1);
-    scanner = ht.getScanner(scan2);
-    // per HBASE-5717, this should still collect even if you don't run all the way to
-    // the end of the scanner. So this is asking for 2 of the 3 rows we inserted.
-    for (Result result : scanner.next(numRecords - 1)) {
-    }
-    scanner.close();
+        // by default, scan metrics collection is turned off
+        assertEquals(null, scanner.getScanMetrics());
+      }
 
-    ScanMetrics scanMetrics = scanner.getScanMetrics();
-    assertEquals("Did not access all the regions in the table", numOfRegions,
-        scanMetrics.countOfRegions.get());
-
-    // check byte counters
-    scan2 = new Scan();
-    scan2.setScanMetricsEnabled(true);
-    scan2.setCaching(1);
-    scanner = ht.getScanner(scan2);
-    int numBytes = 0;
-    for (Result result : scanner.next(1)) {
-      for (Cell cell: result.listCells()) {
-        numBytes += PrivateCellUtil.estimatedSerializedSizeOf(cell);
+      // turn on scan metrics
+      Scan scan2 = new Scan();
+      scan2.setScanMetricsEnabled(true);
+      scan2.setCaching(numRecords + 1);
+      try (ResultScanner scanner = ht.getScanner(scan2)) {
+        for (Result result : scanner.next(numRecords - 1)) {
+        }
+        scanner.close();
+        // closing the scanner will set the metrics.
+        assertNotNull(scanner.getScanMetrics());
       }
-    }
-    scanner.close();
-    scanMetrics = scanner.getScanMetrics();
-    assertEquals("Did not count the result bytes", numBytes,
-      scanMetrics.countOfBytesInResults.get());
-
-    // check byte counters on a small scan
-    scan2 = new Scan();
-    scan2.setScanMetricsEnabled(true);
-    scan2.setCaching(1);
-    scan2.setSmall(true);
-    scanner = ht.getScanner(scan2);
-    numBytes = 0;
-    for (Result result : scanner.next(1)) {
-      for (Cell cell: result.listCells()) {
-        numBytes += PrivateCellUtil.estimatedSerializedSizeOf(cell);
+
+      // set caching to 1, because metrics are collected in each roundtrip only
+      scan2 = new Scan();
+      scan2.setScanMetricsEnabled(true);
+      scan2.setCaching(1);
+      try (ResultScanner scanner = ht.getScanner(scan2)) {
+        // per HBASE-5717, this should still collect even if you don't run all the way to
+        // the end of the scanner. So this is asking for 2 of the 3 rows we inserted.
+        for (Result result : scanner.next(numRecords - 1)) {
+        }
+
+        ScanMetrics scanMetrics = scanner.getScanMetrics();
+        assertEquals("Did not access all the regions in the table", numOfRegions,
+                scanMetrics.countOfRegions.get());
+      }
+
+      // check byte counters
+      scan2 = new Scan();
+      scan2.setScanMetricsEnabled(true);
+      scan2.setCaching(1);
+      try (ResultScanner scanner = ht.getScanner(scan2)) {
+        int numBytes = 0;
+        for (Result result : scanner.next(1)) {
+          for (Cell cell : result.listCells()) {
+            numBytes += PrivateCellUtil.estimatedSerializedSizeOf(cell);
+          }
+        }
+        scanner.close();
+        ScanMetrics scanMetrics = scanner.getScanMetrics();
+        assertEquals("Did not count the result bytes", numBytes,
+                scanMetrics.countOfBytesInResults.get());
+      }
+
+      // check byte counters on a small scan
+      scan2 = new Scan();
+      scan2.setScanMetricsEnabled(true);
+      scan2.setCaching(1);
+      scan2.setSmall(true);
+      try (ResultScanner scanner = ht.getScanner(scan2)) {
+        int numBytes = 0;
+        for (Result result : scanner.next(1)) {
+          for (Cell cell : result.listCells()) {
+            numBytes += PrivateCellUtil.estimatedSerializedSizeOf(cell);
+          }
+        }
+        scanner.close();
+        ScanMetrics scanMetrics = scanner.getScanMetrics();
+        assertEquals("Did not count the result bytes", numBytes,
+                scanMetrics.countOfBytesInResults.get());
+      }
+
+      // now, test that the metrics are still collected even if you don't call close, but do
+      // run past the end of all the records
+      /** There seems to be a timing issue here.  Comment out for now. Fix when time.
+       Scan scanWithoutClose = new Scan();
+       scanWithoutClose.setCaching(1);
+       scanWithoutClose.setScanMetricsEnabled(true);
+       ResultScanner scannerWithoutClose = ht.getScanner(scanWithoutClose);
+       for (Result result : scannerWithoutClose.next(numRecords + 1)) {
+       }
+       ScanMetrics scanMetricsWithoutClose = getScanMetrics(scanWithoutClose);
+       assertEquals("Did not access all the regions in the table", numOfRegions,
+       scanMetricsWithoutClose.countOfRegions.get());
+       */
+
+      // finally,
+      // test that the metrics are collected correctly if you both run past all the records,
+      // AND close the scanner
+      Scan scanWithClose = new Scan();
+      // make sure we can set caching up to the number of a scanned values
+      scanWithClose.setCaching(numRecords);
+      scanWithClose.setScanMetricsEnabled(true);
+      try (ResultScanner scannerWithClose = ht.getScanner(scanWithClose)) {
+        for (Result result : scannerWithClose.next(numRecords + 1)) {
+        }
+        scannerWithClose.close();
+        ScanMetrics scanMetricsWithClose = scannerWithClose.getScanMetrics();
+        assertEquals("Did not access all the regions in the table", numOfRegions,
+                scanMetricsWithClose.countOfRegions.get());
       }
     }
-    scanner.close();
-    scanMetrics = scanner.getScanMetrics();
-    assertEquals("Did not count the result bytes", numBytes,
-      scanMetrics.countOfBytesInResults.get());
-
-    // now, test that the metrics are still collected even if you don't call close, but do
-    // run past the end of all the records
-    /** There seems to be a timing issue here.  Comment out for now. Fix when time.
-    Scan scanWithoutClose = new Scan();
-    scanWithoutClose.setCaching(1);
-    scanWithoutClose.setScanMetricsEnabled(true);
-    ResultScanner scannerWithoutClose = ht.getScanner(scanWithoutClose);
-    for (Result result : scannerWithoutClose.next(numRecords + 1)) {
-    }
-    ScanMetrics scanMetricsWithoutClose = getScanMetrics(scanWithoutClose);
-    assertEquals("Did not access all the regions in the table", numOfRegions,
-        scanMetricsWithoutClose.countOfRegions.get());
-    */
-
-    // finally, test that the metrics are collected correctly if you both run past all the records,
-    // AND close the scanner
-    Scan scanWithClose = new Scan();
-    // make sure we can set caching up to the number of a scanned values
-    scanWithClose.setCaching(numRecords);
-    scanWithClose.setScanMetricsEnabled(true);
-    ResultScanner scannerWithClose = ht.getScanner(scanWithClose);
-    for (Result result : scannerWithClose.next(numRecords + 1)) {
-    }
-    scannerWithClose.close();
-    ScanMetrics scanMetricsWithClose = scannerWithClose.getScanMetrics();
-    assertEquals("Did not access all the regions in the table", numOfRegions,
-        scanMetricsWithClose.countOfRegions.get());
   }
 
   /**
@@ -5213,101 +5293,102 @@ public class TestFromClientSide {
   public void testCacheOnWriteEvictOnClose() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     byte [] data = Bytes.toBytes("data");
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
-    try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
-      // get the block cache and region
-      String regionName = locator.getAllRegionLocations().get(0).getRegionInfo().getEncodedName();
-
-      HRegion region = TEST_UTIL.getRSForFirstRegionInTable(tableName)
-          .getRegion(regionName);
-      HStore store = region.getStores().iterator().next();
-      CacheConfig cacheConf = store.getCacheConfig();
-      cacheConf.setCacheDataOnWrite(true);
-      cacheConf.setEvictOnClose(true);
-      BlockCache cache = cacheConf.getBlockCache().get();
-
-      // establish baseline stats
-      long startBlockCount = cache.getBlockCount();
-      long startBlockHits = cache.getStats().getHitCount();
-      long startBlockMiss = cache.getStats().getMissCount();
-
-      // wait till baseline is stable, (minimal 500 ms)
-      for (int i = 0; i < 5; i++) {
-        Thread.sleep(100);
-        if (startBlockCount != cache.getBlockCount()
-            || startBlockHits != cache.getStats().getHitCount()
-            || startBlockMiss != cache.getStats().getMissCount()) {
-          startBlockCount = cache.getBlockCount();
-          startBlockHits = cache.getStats().getHitCount();
-          startBlockMiss = cache.getStats().getMissCount();
-          i = -1;
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
+      try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
+        // get the block cache and region
+        String regionName = locator.getAllRegionLocations().get(0).getRegionInfo().getEncodedName();
+
+        HRegion region = TEST_UTIL.getRSForFirstRegionInTable(tableName)
+                .getRegion(regionName);
+        HStore store = region.getStores().iterator().next();
+        CacheConfig cacheConf = store.getCacheConfig();
+        cacheConf.setCacheDataOnWrite(true);
+        cacheConf.setEvictOnClose(true);
+        BlockCache cache = cacheConf.getBlockCache().get();
+
+        // establish baseline stats
+        long startBlockCount = cache.getBlockCount();
+        long startBlockHits = cache.getStats().getHitCount();
+        long startBlockMiss = cache.getStats().getMissCount();
+
+        // wait till baseline is stable, (minimal 500 ms)
+        for (int i = 0; i < 5; i++) {
+          Thread.sleep(100);
+          if (startBlockCount != cache.getBlockCount()
+                  || startBlockHits != cache.getStats().getHitCount()
+                  || startBlockMiss != cache.getStats().getMissCount()) {
+            startBlockCount = cache.getBlockCount();
+            startBlockHits = cache.getStats().getHitCount();
+            startBlockMiss = cache.getStats().getMissCount();
+            i = -1;
+          }
         }
-      }
 
-      // insert data
-      Put put = new Put(ROW);
-      put.addColumn(FAMILY, QUALIFIER, data);
-      table.put(put);
-      assertTrue(Bytes.equals(table.get(new Get(ROW)).value(), data));
-      // data was in memstore so don't expect any changes
-      assertEquals(startBlockCount, cache.getBlockCount());
-      assertEquals(startBlockHits, cache.getStats().getHitCount());
-      assertEquals(startBlockMiss, cache.getStats().getMissCount());
-      // flush the data
-      System.out.println("Flushing cache");
-      region.flush(true);
-      // expect one more block in cache, no change in hits/misses
-      long expectedBlockCount = startBlockCount + 1;
-      long expectedBlockHits = startBlockHits;
-      long expectedBlockMiss = startBlockMiss;
-      assertEquals(expectedBlockCount, cache.getBlockCount());
-      assertEquals(expectedBlockHits, cache.getStats().getHitCount());
-      assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
-      // read the data and expect same blocks, one new hit, no misses
-      assertTrue(Bytes.equals(table.get(new Get(ROW)).value(), data));
-      assertEquals(expectedBlockCount, cache.getBlockCount());
-      assertEquals(++expectedBlockHits, cache.getStats().getHitCount());
-      assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
-      // insert a second column, read the row, no new blocks, one new hit
-      byte [] QUALIFIER2 = Bytes.add(QUALIFIER, QUALIFIER);
-      byte [] data2 = Bytes.add(data, data);
-      put = new Put(ROW);
-      put.addColumn(FAMILY, QUALIFIER2, data2);
-      table.put(put);
-      Result r = table.get(new Get(ROW));
-      assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER), data));
-      assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER2), data2));
-      assertEquals(expectedBlockCount, cache.getBlockCount());
-      assertEquals(++expectedBlockHits, cache.getStats().getHitCount());
-      assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
-      // flush, one new block
-      System.out.println("Flushing cache");
-      region.flush(true);
-      assertEquals(++expectedBlockCount, cache.getBlockCount());
-      assertEquals(expectedBlockHits, cache.getStats().getHitCount());
-      assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
-      // compact, net minus two blocks, two hits, no misses
-      System.out.println("Compacting");
-      assertEquals(2, store.getStorefilesCount());
-      store.triggerMajorCompaction();
-      region.compact(true);
-      store.closeAndArchiveCompactedFiles();
-      waitForStoreFileCount(store, 1, 10000); // wait 10 seconds max
-      assertEquals(1, store.getStorefilesCount());
-      expectedBlockCount -= 2; // evicted two blocks, cached none
-      assertEquals(expectedBlockCount, cache.getBlockCount());
-      expectedBlockHits += 2;
-      assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
-      assertEquals(expectedBlockHits, cache.getStats().getHitCount());
-      // read the row, this should be a cache miss because we don't cache data
-      // blocks on compaction
-      r = table.get(new Get(ROW));
-      assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER), data));
-      assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER2), data2));
-      expectedBlockCount += 1; // cached one data block
-      assertEquals(expectedBlockCount, cache.getBlockCount());
-      assertEquals(expectedBlockHits, cache.getStats().getHitCount());
-      assertEquals(++expectedBlockMiss, cache.getStats().getMissCount());
+        // insert data
+        Put put = new Put(ROW);
+        put.addColumn(FAMILY, QUALIFIER, data);
+        table.put(put);
+        assertTrue(Bytes.equals(table.get(new Get(ROW)).value(), data));
+        // data was in memstore so don't expect any changes
+        assertEquals(startBlockCount, cache.getBlockCount());
+        assertEquals(startBlockHits, cache.getStats().getHitCount());
+        assertEquals(startBlockMiss, cache.getStats().getMissCount());
+        // flush the data
+        System.out.println("Flushing cache");
+        region.flush(true);
+        // expect one more block in cache, no change in hits/misses
+        long expectedBlockCount = startBlockCount + 1;
+        long expectedBlockHits = startBlockHits;
+        long expectedBlockMiss = startBlockMiss;
+        assertEquals(expectedBlockCount, cache.getBlockCount());
+        assertEquals(expectedBlockHits, cache.getStats().getHitCount());
+        assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
+        // read the data and expect same blocks, one new hit, no misses
+        assertTrue(Bytes.equals(table.get(new Get(ROW)).value(), data));
+        assertEquals(expectedBlockCount, cache.getBlockCount());
+        assertEquals(++expectedBlockHits, cache.getStats().getHitCount());
+        assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
+        // insert a second column, read the row, no new blocks, one new hit
+        byte[] QUALIFIER2 = Bytes.add(QUALIFIER, QUALIFIER);
+        byte[] data2 = Bytes.add(data, data);
+        put = new Put(ROW);
+        put.addColumn(FAMILY, QUALIFIER2, data2);
+        table.put(put);
+        Result r = table.get(new Get(ROW));
+        assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER), data));
+        assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER2), data2));
+        assertEquals(expectedBlockCount, cache.getBlockCount());
+        assertEquals(++expectedBlockHits, cache.getStats().getHitCount());
+        assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
+        // flush, one new block
+        System.out.println("Flushing cache");
+        region.flush(true);
+        assertEquals(++expectedBlockCount, cache.getBlockCount());
+        assertEquals(expectedBlockHits, cache.getStats().getHitCount());
+        assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
+        // compact, net minus two blocks, two hits, no misses
+        System.out.println("Compacting");
+        assertEquals(2, store.getStorefilesCount());
+        store.triggerMajorCompaction();
+        region.compact(true);
+        store.closeAndArchiveCompactedFiles();
+        waitForStoreFileCount(store, 1, 10000); // wait 10 seconds max
+        assertEquals(1, store.getStorefilesCount());
+        expectedBlockCount -= 2; // evicted two blocks, cached none
+        assertEquals(expectedBlockCount, cache.getBlockCount());
+        expectedBlockHits += 2;
+        assertEquals(expectedBlockMiss, cache.getStats().getMissCount());
+        assertEquals(expectedBlockHits, cache.getStats().getHitCount());
+        // read the row, this should be a cache miss because we don't cache data
+        // blocks on compaction
+        r = table.get(new Get(ROW));
+        assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER), data));
+        assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER2), data2));
+        expectedBlockCount += 1; // cached one data block
+        assertEquals(expectedBlockCount, cache.getBlockCount());
+        assertEquals(expectedBlockHits, cache.getStats().getHitCount());
+        assertEquals(++expectedBlockMiss, cache.getStats().getMissCount());
+      }
     }
   }
 
@@ -5448,186 +5529,193 @@ public class TestFromClientSide {
   @Test
   public void testJira6912() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table foo = TEST_UTIL.createTable(tableName, new byte[][] {FAMILY}, 10);
-
-    List<Put> puts = new ArrayList<Put>();
-    for (int i=0;i !=100; i++){
-      Put put = new Put(Bytes.toBytes(i));
-      put.addColumn(FAMILY, FAMILY, Bytes.toBytes(i));
-      puts.add(put);
-    }
-    foo.put(puts);
-    // If i comment this out it works
-    TEST_UTIL.flush();
+    try (Table foo = TEST_UTIL.createTable(tableName, new byte[][] {FAMILY}, 10)) {
 
-    Scan scan = new Scan();
-    scan.setStartRow(Bytes.toBytes(1));
-    scan.setStopRow(Bytes.toBytes(3));
-    scan.addColumn(FAMILY, FAMILY);
-    scan.setFilter(new RowFilter(CompareOperator.NOT_EQUAL,
-        new BinaryComparator(Bytes.toBytes(1))));
+      List<Put> puts = new ArrayList<Put>();
+      for (int i = 0; i != 100; i++) {
+        Put put = new Put(Bytes.toBytes(i));
+        put.addColumn(FAMILY, FAMILY, Bytes.toBytes(i));
+        puts.add(put);
+      }
+      foo.put(puts);
+      // If i comment this out it works
+      TEST_UTIL.flush();
 
-    ResultScanner scanner = foo.getScanner(scan);
-    Result[] bar = scanner.next(100);
-    assertEquals(1, bar.length);
+      Scan scan = new Scan();
+      scan.setStartRow(Bytes.toBytes(1));
+      scan.setStopRow(Bytes.toBytes(3));
+      scan.addColumn(FAMILY, FAMILY);
+      scan.setFilter(new RowFilter(CompareOperator.NOT_EQUAL,
+              new BinaryComparator(Bytes.toBytes(1))));
+
+      try (ResultScanner scanner = foo.getScanner(scan)) {
+        Result[] bar = scanner.next(100);
+        assertEquals(1, bar.length);
+      }
+    }
   }
 
   @Test
   public void testScan_NullQualifier() throws IOException {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
 
-    put = new Put(ROW);
-    put.addColumn(FAMILY, null, VALUE);
-    table.put(put);
-    LOG.info("Row put");
+      put = new Put(ROW);
+      put.addColumn(FAMILY, null, VALUE);
+      table.put(put);
+      LOG.info("Row put");
 
-    Scan scan = new Scan();
-    scan.addColumn(FAMILY, null);
+      Scan scan = new Scan();
+      scan.addColumn(FAMILY, null);
 
-    ResultScanner scanner = table.getScanner(scan);
-    Result[] bar = scanner.next(100);
-    assertEquals(1, bar.length);
-    assertEquals(1, bar[0].size());
+      ResultScanner scanner = table.getScanner(scan);
+      Result[] bar = scanner.next(100);
+      assertEquals(1, bar.length);
+      assertEquals(1, bar[0].size());
 
-    scan = new Scan();
-    scan.addFamily(FAMILY);
+      scan = new Scan();
+      scan.addFamily(FAMILY);
 
-    scanner = table.getScanner(scan);
-    bar = scanner.next(100);
-    assertEquals(1, bar.length);
-    assertEquals(2, bar[0].size());
+      scanner = table.getScanner(scan);
+      bar = scanner.next(100);
+      assertEquals(1, bar.length);
+      assertEquals(2, bar[0].size());
+    }
   }
 
   @Test
   public void testNegativeTimestamp() throws IOException {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY);
+    try (Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()), FAMILY)) {
 
-    try {
-      Put put = new Put(ROW, -1);
-      put.addColumn(FAMILY, QUALIFIER, VALUE);
-      table.put(put);
-      fail("Negative timestamps should not have been allowed");
-    } catch (IllegalArgumentException ex) {
-      assertTrue(ex.getMessage().contains("negative"));
-    }
+      try {
+        Put put = new Put(ROW, -1);
+        put.addColumn(FAMILY, QUALIFIER, VALUE);
+        table.put(put);
+        fail("Negative timestamps should not have been allowed");
+      } catch (IllegalArgumentException ex) {
+        assertTrue(ex.getMessage().contains("negative"));
+      }
 
-    try {
-      Put put = new Put(ROW);
-      long ts = -1;
-      put.addColumn(FAMILY, QUALIFIER, ts, VALUE);
-      table.put(put);
-      fail("Negative timestamps should not have been allowed");
-    } catch (IllegalArgumentException ex) {
-      assertTrue(ex.getMessage().contains("negative"));
-    }
+      try {
+        Put put = new Put(ROW);
+        long ts = -1;
+        put.addColumn(FAMILY, QUALIFIER, ts, VALUE);
+        table.put(put);
+        fail("Negative timestamps should not have been allowed");
+      } catch (IllegalArgumentException ex) {
+        assertTrue(ex.getMessage().contains("negative"));
+      }
 
-    try {
-      Delete delete = new Delete(ROW, -1);
-      table.delete(delete);
-      fail("Negative timestamps should not have been allowed");
-    } catch (IllegalArgumentException ex) {
-      assertTrue(ex.getMessage().contains("negative"));
-    }
+      try {
+        Delete delete = new Delete(ROW, -1);
+        table.delete(delete);
+        fail("Negative timestamps should not have been allowed");
+      } catch (IllegalArgumentException ex) {
+        assertTrue(ex.getMessage().contains("negative"));
+      }
 
-    try {
-      Delete delete = new Delete(ROW);
-      delete.addFamily(FAMILY, -1);
-      table.delete(delete);
-      fail("Negative timestamps should not have been allowed");
-    } catch (IllegalArgumentException ex) {
-      assertTrue(ex.getMessage().contains("negative"));
-    }
+      try {
+        Delete delete = new Delete(ROW);
+        delete.addFamily(FAMILY, -1);
+        table.delete(delete);
+        fail("Negative timestamps should not have been allowed");
+      } catch (IllegalArgumentException ex) {
+        assertTrue(ex.getMessage().contains("negative"));
+      }
 
-    try {
-      Scan scan = new Scan();
-      scan.setTimeRange(-1, 1);
-      table.getScanner(scan);
-      fail("Negative timestamps should not have been allowed");
-    } catch (IllegalArgumentException ex) {
-      assertTrue(ex.getMessage().contains("negative"));
-    }
+      try {
+        Scan scan = new Scan();
+        scan.setTimeRange(-1, 1);
+        table.getScanner(scan);
+        fail("Negative timestamps should not have been allowed");
+      } catch (IllegalArgumentException ex) {
+        assertTrue(ex.getMessage().contains("negative"));
+      }
 
-    // KeyValue should allow negative timestamps for backwards compat. Otherwise, if the user
-    // already has negative timestamps in cluster data, HBase won't be able to handle that
-    try {
-      new KeyValue(Bytes.toBytes(42), Bytes.toBytes(42), Bytes.toBytes(42), -1, Bytes.toBytes(42));
-    } catch (IllegalArgumentException ex) {
-      fail("KeyValue SHOULD allow negative timestamps");
-    }
+      // KeyValue should allow negative timestamps for backwards compat. Otherwise, if the user
+      // already has negative timestamps in cluster data, HBase won't be able to handle that
+      try {
+        new KeyValue(Bytes.toBytes(42), Bytes.toBytes(42), Bytes.toBytes(42), -1,
+                Bytes.toBytes(42));
+      } catch (IllegalArgumentException ex) {
+        fail("KeyValue SHOULD allow negative timestamps");
+      }
 
-    table.close();
+    }
   }
 
   @Test
   public void testRawScanRespectsVersions() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
-    byte[] row = Bytes.toBytes("row");
-
-    // put the same row 4 times, with different values
-    Put p = new Put(row);
-    p.addColumn(FAMILY, QUALIFIER, 10, VALUE);
-    table.put(p);
-    p = new Put(row);
-    p.addColumn(FAMILY, QUALIFIER, 11, ArrayUtils.add(VALUE, (byte) 2));
-    table.put(p);
-
-    p = new Put(row);
-    p.addColumn(FAMILY, QUALIFIER, 12, ArrayUtils.add(VALUE, (byte) 3));
-    table.put(p);
-
-    p = new Put(row);
-    p.addColumn(FAMILY, QUALIFIER, 13, ArrayUtils.add(VALUE, (byte) 4));
-    table.put(p);
-
-    int versions = 4;
-    Scan s = new Scan(row);
-    // get all the possible versions
-    s.setMaxVersions();
-    s.setRaw(true);
-
-    ResultScanner scanner = table.getScanner(s);
-    int count = 0;
-    for (Result r : scanner) {
-      assertEquals("Found an unexpected number of results for the row!", versions, r.listCells().size());
-      count++;
-    }
-    assertEquals("Found more than a single row when raw scanning the table with a single row!", 1,
-      count);
-    scanner.close();
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[] row = Bytes.toBytes("row");
 
-    // then if we decrease the number of versions, but keep the scan raw, we should see exactly that
-    // number of versions
-    versions = 2;
-    s.setMaxVersions(versions);
-    scanner = table.getScanner(s);
-    count = 0;
-    for (Result r : scanner) {
-      assertEquals("Found an unexpected number of results for the row!", versions, r.listCells().size());
-      count++;
-    }
-    assertEquals("Found more than a single row when raw scanning the table with a single row!", 1,
-      count);
-    scanner.close();
+      // put the same row 4 times, with different values
+      Put p = new Put(row);
+      p.addColumn(FAMILY, QUALIFIER, 10, VALUE);
+      table.put(p);
+      p = new Put(row);
+      p.addColumn(FAMILY, QUALIFIER, 11, ArrayUtils.add(VALUE, (byte) 2));
+      table.put(p);
 
-    // finally, if we turn off raw scanning, but max out the number of versions, we should go back
-    // to seeing just three
-    versions = 3;
-    s.setMaxVersions(versions);
-    scanner = table.getScanner(s);
-    count = 0;
-    for (Result r : scanner) {
-      assertEquals("Found an unexpected number of results for the row!", versions, r.listCells().size());
-      count++;
-    }
-    assertEquals("Found more than a single row when raw scanning the table with a single row!", 1,
-      count);
-    scanner.close();
+      p = new Put(row);
+      p.addColumn(FAMILY, QUALIFIER, 12, ArrayUtils.add(VALUE, (byte) 3));
+      table.put(p);
+
+      p = new Put(row);
+      p.addColumn(FAMILY, QUALIFIER, 13, ArrayUtils.add(VALUE, (byte) 4));
+      table.put(p);
+
+      int versions = 4;
+      Scan s = new Scan(row);
+      // get all the possible versions
+      s.setMaxVersions();
+      s.setRaw(true);
+
+      try (ResultScanner scanner = table.getScanner(s)) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertEquals("Found an unexpected number of results for the row!", versions,
+                  r.listCells().size());
+          count++;
+        }
+        assertEquals("Found more than a single row when raw scanning the table with a single row!",
+                1, count);
+      }
+
+      // then if we decrease the number of versions, but keep the scan raw, we should see exactly
+      // that number of versions
+      versions = 2;
+      s.setMaxVersions(versions);
+      try (ResultScanner scanner = table.getScanner(s)) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertEquals("Found an unexpected number of results for the row!", versions,
+                  r.listCells().size());
+          count++;
+        }
+        assertEquals("Found more than a single row when raw scanning the table with a single row!",
+                1, count);
+      }
+
+      // finally, if we turn off raw scanning, but max out the number of versions, we should go back
+      // to seeing just three
+      versions = 3;
+      s.setMaxVersions(versions);
+      try (ResultScanner scanner = table.getScanner(s)) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertEquals("Found an unexpected number of results for the row!", versions,
+                  r.listCells().size());
+          count++;
+        }
+        assertEquals("Found more than a single row when raw scanning the table with a single row!",
+                1, count);
+      }
 
-    table.close();
+    }
     TEST_UTIL.deleteTable(tableName);
   }
 
@@ -5635,34 +5723,39 @@ public class TestFromClientSide {
   public void testEmptyFilterList() throws Exception {
     // Test Initialization.
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
 
-    // Insert one row each region
-    Put put = new Put(Bytes.toBytes("row"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
+      // Insert one row each region
+      Put put = new Put(Bytes.toBytes("row"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
 
-    List<Result> scanResults = new LinkedList<>();
-    Scan scan = new Scan();
-    scan.setFilter(new FilterList());
-    try (ResultScanner scanner = table.getScanner(scan)) {
-      for (Result r : scanner) {
-        scanResults.add(r);
+      List<Result> scanResults = new LinkedList<>();
+      Scan scan = new Scan();
+      scan.setFilter(new FilterList());
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        for (Result r : scanner) {
+          scanResults.add(r);
+        }
+      }
+      assertEquals(1, scanResults.size());
+      Get g = new Get(Bytes.toBytes("row"));
+      g.setFilter(new FilterList());
+      Result getResult = table.get(g);
+      Result scanResult = scanResults.get(0);
+      assertEquals(scanResult.rawCells().length, getResult.rawCells().length);
+      for (int i = 0; i != scanResult.rawCells().length; ++i) {
+        Cell scanCell = scanResult.rawCells()[i];
+        Cell getCell = getResult.rawCells()[i];
+        assertEquals(0, Bytes.compareTo(CellUtil.cloneRow(scanCell),
+                CellUtil.cloneRow(getCell)));
+        assertEquals(0, Bytes.compareTo(CellUtil.cloneFamily(scanCell),
+                CellUtil.cloneFamily(getCell)));
+        assertEquals(0, Bytes.compareTo(CellUtil.cloneQualifier(scanCell),
+                CellUtil.cloneQualifier(getCell)));
+        assertEquals(0, Bytes.compareTo(CellUtil.cloneValue(scanCell),
+                CellUtil.cloneValue(getCell)));
       }
-    }
-    assertEquals(1, scanResults.size());
-    Get g = new Get(Bytes.toBytes("row"));
-    g.setFilter(new FilterList());
-    Result getResult = table.get(g);
-    Result scanResult = scanResults.get(0);
-    assertEquals(scanResult.rawCells().length, getResult.rawCells().length);
-    for (int i = 0; i != scanResult.rawCells().length; ++i) {
-      Cell scanCell = scanResult.rawCells()[i];
-      Cell getCell = getResult.rawCells()[i];
-      assertEquals(0, Bytes.compareTo(CellUtil.cloneRow(scanCell), CellUtil.cloneRow(getCell)));
-      assertEquals(0, Bytes.compareTo(CellUtil.cloneFamily(scanCell), CellUtil.cloneFamily(getCell)));
-      assertEquals(0, Bytes.compareTo(CellUtil.cloneQualifier(scanCell), CellUtil.cloneQualifier(getCell)));
-      assertEquals(0, Bytes.compareTo(CellUtil.cloneValue(scanCell), CellUtil.cloneValue(getCell)));
     }
   }
 
@@ -5670,162 +5763,165 @@ public class TestFromClientSide {
   public void testSmallScan() throws Exception {
     // Test Initialization.
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
-
-    // Insert one row each region
-    int insertNum = 10;
-    for (int i = 0; i < 10; i++) {
-      Put put = new Put(Bytes.toBytes("row" + String.format("%03d", i)));
-      put.addColumn(FAMILY, QUALIFIER, VALUE);
-      table.put(put);
-    }
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
+
+      // Insert one row each region
+      int insertNum = 10;
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(Bytes.toBytes("row" + String.format("%03d", i)));
+        put.addColumn(FAMILY, QUALIFIER, VALUE);
+        table.put(put);
+      }
 
-    // normal scan
-    ResultScanner scanner = table.getScanner(new Scan());
-    int count = 0;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-    }
-    assertEquals(insertNum, count);
+      // normal scan
+      try (ResultScanner scanner = table.getScanner(new Scan())) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertTrue(!r.isEmpty());
+          count++;
+        }
+        assertEquals(insertNum, count);
+      }
 
-    // small scan
-    Scan scan = new Scan(HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW);
-    scan.setSmall(true);
-    scan.setCaching(2);
-    scanner = table.getScanner(scan);
-    count = 0;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
+      // small scan
+      Scan scan = new Scan(HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW);
+      scan.setSmall(true);
+      scan.setCaching(2);
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertTrue(!r.isEmpty());
+          count++;
+        }
+        assertEquals(insertNum, count);
+      }
     }
-    assertEquals(insertNum, count);
-
   }
 
   @Test
   public void testSuperSimpleWithReverseScan() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    Put put = new Put(Bytes.toBytes("0-b11111-0000000000000000000"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b11111-0000000000000000002"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b11111-0000000000000000004"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b11111-0000000000000000006"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b11111-0000000000000000008"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b22222-0000000000000000001"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b22222-0000000000000000003"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b22222-0000000000000000005"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b22222-0000000000000000007"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    put = new Put(Bytes.toBytes("0-b22222-0000000000000000009"));
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
-    Scan scan = new Scan(Bytes.toBytes("0-b11111-9223372036854775807"),
-        Bytes.toBytes("0-b11111-0000000000000000000"));
-    scan.setReversed(true);
-    ResultScanner scanner = ht.getScanner(scan);
-    Result result = scanner.next();
-    assertTrue(Bytes.equals(result.getRow(),
-        Bytes.toBytes("0-b11111-0000000000000000008")));
-    scanner.close();
-    ht.close();
-  }
-
-  @Test
-  public void testFiltersWithReverseScan() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte[][] ROWS = makeN(ROW, 10);
-    byte[][] QUALIFIERS = { Bytes.toBytes("col0-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col1-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col2-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col3-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col4-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col5-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col6-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col7-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col8-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col9-<d2v1>-<d3v2>") };
-    for (int i = 0; i < 10; i++) {
-      Put put = new Put(ROWS[i]);
-      put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      Put put = new Put(Bytes.toBytes("0-b11111-0000000000000000000"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
       ht.put(put);
+      put = new Put(Bytes.toBytes("0-b11111-0000000000000000002"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b11111-0000000000000000004"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b11111-0000000000000000006"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b11111-0000000000000000008"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b22222-0000000000000000001"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b22222-0000000000000000003"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b22222-0000000000000000005"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b22222-0000000000000000007"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      put = new Put(Bytes.toBytes("0-b22222-0000000000000000009"));
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
+      Scan scan = new Scan(Bytes.toBytes("0-b11111-9223372036854775807"),
+              Bytes.toBytes("0-b11111-0000000000000000000"));
+      scan.setReversed(true);
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        Result result = scanner.next();
+        assertTrue(Bytes.equals(result.getRow(),
+                Bytes.toBytes("0-b11111-0000000000000000008")));
+      }
     }
-    Scan scan = new Scan();
-    scan.setReversed(true);
-    scan.addFamily(FAMILY);
-    Filter filter = new QualifierFilter(CompareOperator.EQUAL,
-        new RegexStringComparator("col[1-5]"));
-    scan.setFilter(filter);
-    ResultScanner scanner = ht.getScanner(scan);
-    int expectedIndex = 5;
-    for (Result result : scanner) {
-      assertEquals(1, result.size());
-      Cell c = result.rawCells()[0];
-      assertTrue(Bytes.equals(c.getRowArray(), c.getRowOffset(), c.getRowLength(),
-        ROWS[expectedIndex], 0, ROWS[expectedIndex].length));
-      assertTrue(Bytes.equals(c.getQualifierArray(), c.getQualifierOffset(),
-        c.getQualifierLength(), QUALIFIERS[expectedIndex], 0, QUALIFIERS[expectedIndex].length));
-      expectedIndex--;
-    }
-    assertEquals(0, expectedIndex);
-    scanner.close();
-    ht.close();
   }
 
   @Test
-  public void testKeyOnlyFilterWithReverseScan() throws Exception {
+  public void testFiltersWithReverseScan() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte[][] ROWS = makeN(ROW, 10);
-    byte[][] QUALIFIERS = { Bytes.toBytes("col0-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col1-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col2-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col3-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col4-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col5-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col6-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col7-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col8-<d2v1>-<d3v2>"),
-        Bytes.toBytes("col9-<d2v1>-<d3v2>") };
-    for (int i = 0; i < 10; i++) {
-      Put put = new Put(ROWS[i]);
-      put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
-      ht.put(put);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 10);
+      byte[][] QUALIFIERS = {Bytes.toBytes("col0-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col1-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col2-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col3-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col4-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col5-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col6-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col7-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col8-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col9-<d2v1>-<d3v2>")};
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(ROWS[i]);
+        put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
+        ht.put(put);
+      }
+      Scan scan = new Scan();
+      scan.setReversed(true);
+      scan.addFamily(FAMILY);
+      Filter filter = new QualifierFilter(CompareOperator.EQUAL,
+              new RegexStringComparator("col[1-5]"));
+      scan.setFilter(filter);
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int expectedIndex = 5;
+        for (Result result : scanner) {
+          assertEquals(1, result.size());
+          Cell c = result.rawCells()[0];
+          assertTrue(Bytes.equals(c.getRowArray(), c.getRowOffset(), c.getRowLength(),
+                  ROWS[expectedIndex], 0, ROWS[expectedIndex].length));
+          assertTrue(Bytes.equals(c.getQualifierArray(), c.getQualifierOffset(),
+                  c.getQualifierLength(), QUALIFIERS[expectedIndex], 0,
+                  QUALIFIERS[expectedIndex].length));
+          expectedIndex--;
+        }
+        assertEquals(0, expectedIndex);
+      }
     }
-    Scan scan = new Scan();
-    scan.setReversed(true);
-    scan.addFamily(FAMILY);
-    Filter filter = new KeyOnlyFilter(true);
-    scan.setFilter(filter);
-    ResultScanner scanner = ht.getScanner(scan);
-    int count = 0;
-    for (Result result : ht.getScanner(scan)) {
-      assertEquals(1, result.size());
-      assertEquals(Bytes.SIZEOF_INT, result.rawCells()[0].getValueLength());
-      assertEquals(VALUE.length, Bytes.toInt(CellUtil.cloneValue(result.rawCells()[0])));
-      count++;
+  }
+
+  @Test
+  public void testKeyOnlyFilterWithReverseScan() throws Exception {
+    final TableName tableName = TableName.valueOf(name.getMethodName());
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 10);
+      byte[][] QUALIFIERS = {Bytes.toBytes("col0-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col1-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col2-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col3-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col4-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col5-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col6-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col7-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col8-<d2v1>-<d3v2>"),
+              Bytes.toBytes("col9-<d2v1>-<d3v2>")};
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(ROWS[i]);
+        put.addColumn(FAMILY, QUALIFIERS[i], VALUE);
+        ht.put(put);
+      }
+      Scan scan = new Scan();
+      scan.setReversed(true);
+      scan.addFamily(FAMILY);
+      Filter filter = new KeyOnlyFilter(true);
+      scan.setFilter(filter);
+      try (ResultScanner scanner = ht.getScanner(scan)) {
+        int count = 0;
+        for (Result result : ht.getScanner(scan)) {
+          assertEquals(1, result.size());
+          assertEquals(Bytes.SIZEOF_INT, result.rawCells()[0].getValueLength());
+          assertEquals(VALUE.length, Bytes.toInt(CellUtil.cloneValue(result.rawCells()[0])));
+          count++;
+        }
+        assertEquals(10, count);
+      }
     }
-    assertEquals(10, count);
-    scanner.close();
-    ht.close();
   }
 
   /**
@@ -5834,102 +5930,104 @@ public class TestFromClientSide {
   @Test
   public void testSimpleMissingWithReverseScan() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    byte[][] ROWS = makeN(ROW, 4);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      byte[][] ROWS = makeN(ROW, 4);
 
-    // Try to get a row on an empty table
-    Scan scan = new Scan();
-    scan.setReversed(true);
-    Result result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      // Try to get a row on an empty table
+      Scan scan = new Scan();
+      scan.setReversed(true);
+      Result result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan(ROWS[0]);
-    scan.setReversed(true);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan(ROWS[0]);
+      scan.setReversed(true);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan(ROWS[0], ROWS[1]);
-    scan.setReversed(true);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan(ROWS[0], ROWS[1]);
+      scan.setReversed(true);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan();
-    scan.setReversed(true);
-    scan.addFamily(FAMILY);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan();
+      scan.setReversed(true);
+      scan.addFamily(FAMILY);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    scan = new Scan();
-    scan.setReversed(true);
-    scan.addColumn(FAMILY, QUALIFIER);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
+      scan = new Scan();
+      scan.setReversed(true);
+      scan.addColumn(FAMILY, QUALIFIER);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
 
-    // Insert a row
+      // Insert a row
 
-    Put put = new Put(ROWS[2]);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    ht.put(put);
+      Put put = new Put(ROWS[2]);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      ht.put(put);
 
-    // Make sure we can scan the row
-    scan = new Scan();
-    scan.setReversed(true);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      // Make sure we can scan the row
+      scan = new Scan();
+      scan.setReversed(true);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    scan = new Scan(ROWS[3], ROWS[0]);
-    scan.setReversed(true);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      scan = new Scan(ROWS[3], ROWS[0]);
+      scan.setReversed(true);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    scan = new Scan(ROWS[2], ROWS[1]);
-    scan.setReversed(true);
-    result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+      scan = new Scan(ROWS[2], ROWS[1]);
+      scan.setReversed(true);
+      result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
 
-    // Try to scan empty rows around it
-    // Introduced MemStore#shouldSeekForReverseScan to fix the following
-    scan = new Scan(ROWS[1]);
-    scan.setReversed(true);
-    result = getSingleScanResult(ht, scan);
-    assertNullResult(result);
-    ht.close();
+      // Try to scan empty rows around it
+      // Introduced MemStore#shouldSeekForReverseScan to fix the following
+      scan = new Scan(ROWS[1]);
+      scan.setReversed(true);
+      result = getSingleScanResult(ht, scan);
+      assertNullResult(result);
+    }
   }
 
   @Test
   public void testNullWithReverseScan() throws Exception {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-    // Null qualifier (should work)
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, null, VALUE);
-    ht.put(put);
-    scanTestNull(ht, ROW, FAMILY, VALUE, true);
-    Delete delete = new Delete(ROW);
-    delete.addColumns(FAMILY, null);
-    ht.delete(delete);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) {
+      // Null qualifier (should work)
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, null, VALUE);
+      ht.put(put);
+      scanTestNull(ht, ROW, FAMILY, VALUE, true);
+      Delete delete = new Delete(ROW);
+      delete.addColumns(FAMILY, null);
+      ht.delete(delete);
+    }
+
     // Use a new table
-    ht = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName() + "2"), FAMILY);
-    // Empty qualifier, byte[0] instead of null (should work)
-    put = new Put(ROW);
-    put.addColumn(FAMILY, HConstants.EMPTY_BYTE_ARRAY, VALUE);
-    ht.put(put);
-    scanTestNull(ht, ROW, FAMILY, VALUE, true);
-    TEST_UTIL.flush();
-    scanTestNull(ht, ROW, FAMILY, VALUE, true);
-    delete = new Delete(ROW);
-    delete.addColumns(FAMILY, HConstants.EMPTY_BYTE_ARRAY);
-    ht.delete(delete);
-    // Null value
-    put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, null);
-    ht.put(put);
-    Scan scan = new Scan();
-    scan.setReversed(true);
-    scan.addColumn(FAMILY, QUALIFIER);
-    Result result = getSingleScanResult(ht, scan);
-    assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
-    ht.close();
+    try (Table ht = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName() + "2"), FAMILY)) {
+      // Empty qualifier, byte[0] instead of null (should work)
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, HConstants.EMPTY_BYTE_ARRAY, VALUE);
+      ht.put(put);
+      scanTestNull(ht, ROW, FAMILY, VALUE, true);
+      TEST_UTIL.flush();
+      scanTestNull(ht, ROW, FAMILY, VALUE, true);
+      Delete delete = new Delete(ROW);
+      delete.addColumns(FAMILY, HConstants.EMPTY_BYTE_ARRAY);
+      ht.delete(delete);
+      // Null value
+      put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, null);
+      ht.put(put);
+      Scan scan = new Scan();
+      scan.setReversed(true);
+      scan.addColumn(FAMILY, QUALIFIER);
+      Result result = getSingleScanResult(ht, scan);
+      assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+    }
   }
 
   @Test
@@ -5939,179 +6037,179 @@ public class TestFromClientSide {
     byte[][] FAMILIES = makeNAscii(FAMILY, 3);
     byte[][] VALUES = makeN(VALUE, 5);
     long[] ts = { 1000, 2000, 3000, 4000, 5000 };
-    Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3);
+    try (Table ht = TEST_UTIL.createTable(tableName, FAMILIES, 3)) {
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[1], VALUES[1]);
-    ht.put(put);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[1], VALUES[1]);
+      ht.put(put);
 
-    Delete delete = new Delete(ROW);
-    delete.addFamily(FAMILIES[0], ts[0]);
-    ht.delete(delete);
+      Delete delete = new Delete(ROW);
+      delete.addFamily(FAMILIES[0], ts[0]);
+      ht.delete(delete);
 
-    Scan scan = new Scan(ROW);
-    scan.setReversed(true);
-    scan.addFamily(FAMILIES[0]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    Result result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1] },
-        new byte[][] { VALUES[1] }, 0, 0);
-
-    // Test delete latest version
-    put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[3], VALUES[3]);
-    put.addColumn(FAMILIES[0], null, ts[4], VALUES[4]);
-    put.addColumn(FAMILIES[0], null, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[0], null, ts[3], VALUES[3]);
-    ht.put(put);
-
-    delete = new Delete(ROW);
-    delete.addColumn(FAMILIES[0], QUALIFIER); // ts[4]
-    ht.delete(delete);
-
-    scan = new Scan(ROW);
-    scan.setReversed(true);
-    scan.addColumn(FAMILIES[0], QUALIFIER);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1],
-        ts[2], ts[3] }, new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2);
+      Scan scan = new Scan(ROW);
+      scan.setReversed(true);
+      scan.addFamily(FAMILIES[0]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      Result result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[]{ts[1]},
+              new byte[][]{VALUES[1]}, 0, 0);
 
-    // Test for HBASE-1847
-    delete = new Delete(ROW);
-    delete.addColumn(FAMILIES[0], null);
-    ht.delete(delete);
+      // Test delete latest version
+      put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[3], VALUES[3]);
+      put.addColumn(FAMILIES[0], null, ts[4], VALUES[4]);
+      put.addColumn(FAMILIES[0], null, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[0], null, ts[3], VALUES[3]);
+      ht.put(put);
 
-    // Cleanup null qualifier
-    delete = new Delete(ROW);
-    delete.addColumns(FAMILIES[0], null);
-    ht.delete(delete);
+      delete = new Delete(ROW);
+      delete.addColumn(FAMILIES[0], QUALIFIER); // ts[4]
+      ht.delete(delete);
 
-    // Expected client behavior might be that you can re-put deleted values
-    // But alas, this is not to be. We can't put them back in either case.
+      scan = new Scan(ROW);
+      scan.setReversed(true);
+      scan.addColumn(FAMILIES[0], QUALIFIER);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[]{ts[1],
+              ts[2], ts[3]}, new byte[][]{VALUES[1], VALUES[2], VALUES[3]}, 0, 2);
 
-    put = new Put(ROW);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]);
-    ht.put(put);
+      // Test for HBASE-1847
+      delete = new Delete(ROW);
+      delete.addColumn(FAMILIES[0], null);
+      ht.delete(delete);
 
-    // The Scanner returns the previous values, the expected-naive-unexpected
-    // behavior
+      // Cleanup null qualifier
+      delete = new Delete(ROW);
+      delete.addColumns(FAMILIES[0], null);
+      ht.delete(delete);
 
-    scan = new Scan(ROW);
-    scan.setReversed(true);
-    scan.addFamily(FAMILIES[0]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[] { ts[1],
-        ts[2], ts[3] }, new byte[][] { VALUES[1], VALUES[2], VALUES[3] }, 0, 2);
-
-    // Test deleting an entire family from one row but not the other various
-    // ways
-
-    put = new Put(ROWS[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
-    ht.put(put);
-
-    put = new Put(ROWS[1]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
-    ht.put(put);
-
-    put = new Put(ROWS[2]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
-    put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
-    put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
-    ht.put(put);
-
-    delete = new Delete(ROWS[0]);
-    delete.addFamily(FAMILIES[2]);
-    ht.delete(delete);
-
-    delete = new Delete(ROWS[1]);
-    delete.addColumns(FAMILIES[1], QUALIFIER);
-    ht.delete(delete);
-
-    delete = new Delete(ROWS[2]);
-    delete.addColumn(FAMILIES[1], QUALIFIER);
-    delete.addColumn(FAMILIES[1], QUALIFIER);
-    delete.addColumn(FAMILIES[2], QUALIFIER);
-    ht.delete(delete);
-
-    scan = new Scan(ROWS[0]);
-    scan.setReversed(true);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
-    assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER, new long[] { ts[0],
-        ts[1] }, new byte[][] { VALUES[0], VALUES[1] }, 0, 1);
+      // Expected client behavior might be that you can re-put deleted values
+      // But alas, this is not to be. We can't put them back in either case.
 
-    scan = new Scan(ROWS[1]);
-    scan.setReversed(true);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
+      put = new Put(ROW);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[0], QUALIFIER, ts[4], VALUES[4]);
+      ht.put(put);
 
-    scan = new Scan(ROWS[2]);
-    scan.setReversed(true);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    result = getSingleScanResult(ht, scan);
-    assertEquals(1, result.size());
-    assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER,
-        new long[] { ts[2] }, new byte[][] { VALUES[2] }, 0, 0);
+      // The Scanner returns the previous values, the expected-naive-unexpected
+      // behavior
 
-    // Test if we delete the family first in one row (HBASE-1541)
+      scan = new Scan(ROW);
+      scan.setReversed(true);
+      scan.addFamily(FAMILIES[0]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertNResult(result, ROW, FAMILIES[0], QUALIFIER, new long[]{ts[1],
+              ts[2], ts[3]}, new byte[][]{VALUES[1], VALUES[2], VALUES[3]}, 0, 2);
 
-    delete = new Delete(ROWS[3]);
-    delete.addFamily(FAMILIES[1]);
-    ht.delete(delete);
+      // Test deleting an entire family from one row but not the other various
+      // ways
 
-    put = new Put(ROWS[3]);
-    put.addColumn(FAMILIES[2], QUALIFIER, VALUES[0]);
-    ht.put(put);
+      put = new Put(ROWS[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
+      ht.put(put);
 
-    put = new Put(ROWS[4]);
-    put.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]);
-    put.addColumn(FAMILIES[2], QUALIFIER, VALUES[2]);
-    ht.put(put);
+      put = new Put(ROWS[1]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
+      ht.put(put);
 
-    scan = new Scan(ROWS[4]);
-    scan.setReversed(true);
-    scan.addFamily(FAMILIES[1]);
-    scan.addFamily(FAMILIES[2]);
-    scan.setMaxVersions(Integer.MAX_VALUE);
-    ResultScanner scanner = ht.getScanner(scan);
-    result = scanner.next();
-    assertTrue("Expected 2 keys but received " + result.size(),
-        result.size() == 2);
-    assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[4]));
-    assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[1]), ROWS[4]));
-    assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[1]));
-    assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[1]), VALUES[2]));
-    result = scanner.next();
-    assertTrue("Expected 1 key but received " + result.size(),
-        result.size() == 1);
-    assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[3]));
-    assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[0]));
-    scanner.close();
-    ht.close();
+      put = new Put(ROWS[2]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[0], VALUES[0]);
+      put.addColumn(FAMILIES[1], QUALIFIER, ts[1], VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[2], VALUES[2]);
+      put.addColumn(FAMILIES[2], QUALIFIER, ts[3], VALUES[3]);
+      ht.put(put);
+
+      delete = new Delete(ROWS[0]);
+      delete.addFamily(FAMILIES[2]);
+      ht.delete(delete);
+
+      delete = new Delete(ROWS[1]);
+      delete.addColumns(FAMILIES[1], QUALIFIER);
+      ht.delete(delete);
+
+      delete = new Delete(ROWS[2]);
+      delete.addColumn(FAMILIES[1], QUALIFIER);
+      delete.addColumn(FAMILIES[1], QUALIFIER);
+      delete.addColumn(FAMILIES[2], QUALIFIER);
+      ht.delete(delete);
+
+      scan = new Scan(ROWS[0]);
+      scan.setReversed(true);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 2 keys but received " + result.size(),
+              result.size() == 2);
+      assertNResult(result, ROWS[0], FAMILIES[1], QUALIFIER, new long[]{ts[0],
+              ts[1]}, new byte[][]{VALUES[0], VALUES[1]}, 0, 1);
+
+      scan = new Scan(ROWS[1]);
+      scan.setReversed(true);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertTrue("Expected 2 keys but received " + result.size(),
+              result.size() == 2);
+
+      scan = new Scan(ROWS[2]);
+      scan.setReversed(true);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      result = getSingleScanResult(ht, scan);
+      assertEquals(1, result.size());
+      assertNResult(result, ROWS[2], FAMILIES[2], QUALIFIER,
+              new long[]{ts[2]}, new byte[][]{VALUES[2]}, 0, 0);
+
+      // Test if we delete the family first in one row (HBASE-1541)
+
+      delete = new Delete(ROWS[3]);
+      delete.addFamily(FAMILIES[1]);
+      ht.delete(delete);
+
+      put = new Put(ROWS[3]);
+      put.addColumn(FAMILIES[2], QUALIFIER, VALUES[0]);
+      ht.put(put);
+
+      put = new Put(ROWS[4]);
+      put.addColumn(FAMILIES[1], QUALIFIER, VALUES[1]);
+      put.addColumn(FAMILIES[2], QUALIFIER, VALUES[2]);
+      ht.put(put);
+
+      scan = new Scan(ROWS[4]);
+      scan.setReversed(true);
+      scan.addFamily(FAMILIES[1]);
+      scan.addFamily(FAMILIES[2]);
+      scan.setMaxVersions(Integer.MAX_VALUE);
+      ResultScanner scanner = ht.getScanner(scan);
+      result = scanner.next();
+      assertTrue("Expected 2 keys but received " + result.size(),
+              result.size() == 2);
+      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[4]));
+      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[1]), ROWS[4]));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[1]));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[1]), VALUES[2]));
+      result = scanner.next();
+      assertTrue("Expected 1 key but received " + result.size(),
+              result.size() == 1);
+      assertTrue(Bytes.equals(CellUtil.cloneRow(result.rawCells()[0]), ROWS[3]));
+      assertTrue(Bytes.equals(CellUtil.cloneValue(result.rawCells()[0]), VALUES[0]));
+      scanner.close();
+    }
   }
 
   /**
@@ -6129,48 +6227,50 @@ public class TestFromClientSide {
         Bytes.toBytes("007"),
         Bytes.add(Bytes.toBytes("007"), Bytes.multiple(maxByteArray, 4)),
         Bytes.toBytes("008"), Bytes.multiple(maxByteArray, 2) };
-    Table table = TEST_UTIL.createTable(tableName, FAMILY, splitRows);
-    TEST_UTIL.waitUntilAllRegionsAssigned(table.getName());
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY, splitRows)) {
+      TEST_UTIL.waitUntilAllRegionsAssigned(table.getName());
 
-    try(RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
-      assertEquals(splitRows.length + 1, l.getAllRegionLocations().size());
-    }
-    // Insert one row each region
-    int insertNum = splitRows.length;
-    for (int i = 0; i < insertNum; i++) {
-      Put put = new Put(splitRows[i]);
-      put.addColumn(FAMILY, QUALIFIER, VALUE);
-      table.put(put);
-    }
+      try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
+        assertEquals(splitRows.length + 1, l.getAllRegionLocations().size());
+      }
+      // Insert one row each region
+      int insertNum = splitRows.length;
+      for (int i = 0; i < insertNum; i++) {
+        Put put = new Put(splitRows[i]);
+        put.addColumn(FAMILY, QUALIFIER, VALUE);
+        table.put(put);
+      }
 
-    // scan forward
-    ResultScanner scanner = table.getScanner(new Scan());
-    int count = 0;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-    }
-    assertEquals(insertNum, count);
+      // scan forward
+      try (ResultScanner scanner = table.getScanner(new Scan())) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertTrue(!r.isEmpty());
+          count++;
+        }
+        assertEquals(insertNum, count);
+      }
 
-    // scan backward
-    Scan scan = new Scan();
-    scan.setReversed(true);
-    scanner = table.getScanner(scan);
-    count = 0;
-    byte[] lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+      // scan backward
+      Scan scan = new Scan();
+      scan.setReversed(true);
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        int count = 0;
+        byte[] lastRow = null;
+        for (Result r : scanner) {
+          assertTrue(!r.isEmpty());
+          count++;
+          byte[] thisRow = r.getRow();
+          if (lastRow != null) {
+            assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                            + ",this row=" + Bytes.toString(thisRow),
+                    Bytes.compareTo(thisRow, lastRow) < 0);
+          }
+          lastRow = thisRow;
+        }
+        assertEquals(insertNum, count);
       }
-      lastRow = thisRow;
     }
-    assertEquals(insertNum, count);
-    table.close();
   }
 
   /**
@@ -6183,161 +6283,167 @@ public class TestFromClientSide {
     byte[][] splitRows = new byte[][]{
         Bytes.toBytes("000"), Bytes.toBytes("002"), Bytes.toBytes("004"),
         Bytes.toBytes("006"), Bytes.toBytes("008"), Bytes.toBytes("010")};
-    Table table = TEST_UTIL.createTable(tableName, FAMILY, splitRows);
-    TEST_UTIL.waitUntilAllRegionsAssigned(table.getName());
-
-    try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
-      assertEquals(splitRows.length + 1, l.getAllRegionLocations().size());
-    }
-    for (byte[] splitRow : splitRows) {
-      Put put = new Put(splitRow);
-      put.addColumn(FAMILY, QUALIFIER, VALUE);
-      table.put(put);
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY, splitRows)) {
+      TEST_UTIL.waitUntilAllRegionsAssigned(table.getName());
 
-      byte[] nextRow = Bytes.copy(splitRow);
-      nextRow[nextRow.length - 1]++;
+      try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
+        assertEquals(splitRows.length + 1, l.getAllRegionLocations().size());
+      }
+      for (byte[] splitRow : splitRows) {
+        Put put = new Put(splitRow);
+        put.addColumn(FAMILY, QUALIFIER, VALUE);
+        table.put(put);
 
-      put = new Put(nextRow);
-      put.addColumn(FAMILY, QUALIFIER, VALUE);
-      table.put(put);
-    }
+        byte[] nextRow = Bytes.copy(splitRow);
+        nextRow[nextRow.length - 1]++;
 
-    // scan forward
-    ResultScanner scanner = table.getScanner(new Scan());
-    int count = 0;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-    }
-    assertEquals(12, count);
+        put = new Put(nextRow);
+        put.addColumn(FAMILY, QUALIFIER, VALUE);
+        table.put(put);
+      }
 
-    reverseScanTest(table, false);
-    reverseScanTest(table, true);
+      // scan forward
+      try (ResultScanner scanner = table.getScanner(new Scan())) {
+        int count = 0;
+        for (Result r : scanner) {
+          assertTrue(!r.isEmpty());
+          count++;
+        }
+        assertEquals(12, count);
+      }
 
-    table.close();
+      reverseScanTest(table, false);
+      reverseScanTest(table, true);
+    }
   }
 
   private void reverseScanTest(Table table, boolean small) throws IOException {
     // scan backward
     Scan scan = new Scan();
     scan.setReversed(true);
-    ResultScanner scanner = table.getScanner(scan);
-    int count = 0;
-    byte[] lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+    try (ResultScanner scanner = table.getScanner(scan)) {
+      int count = 0;
+      byte[] lastRow = null;
+      for (Result r : scanner) {
+        assertTrue(!r.isEmpty());
+        count++;
+        byte[] thisRow = r.getRow();
+        if (lastRow != null) {
+          assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                          + ",this row=" + Bytes.toString(thisRow),
+                  Bytes.compareTo(thisRow, lastRow) < 0);
+        }
+        lastRow = thisRow;
       }
-      lastRow = thisRow;
+      assertEquals(12, count);
     }
-    assertEquals(12, count);
 
     scan = new Scan();
     scan.setSmall(small);
     scan.setReversed(true);
     scan.setStartRow(Bytes.toBytes("002"));
-    scanner = table.getScanner(scan);
-    count = 0;
-    lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+    try (ResultScanner scanner = table.getScanner(scan)) {
+      int count = 0;
+      byte[] lastRow = null;
+      for (Result r : scanner) {
+        assertTrue(!r.isEmpty());
+        count++;
+        byte[] thisRow = r.getRow();
+        if (lastRow != null) {
+          assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                          + ",this row=" + Bytes.toString(thisRow),
+                  Bytes.compareTo(thisRow, lastRow) < 0);
+        }
+        lastRow = thisRow;
       }
-      lastRow = thisRow;
+      assertEquals(3, count); // 000 001 002
     }
-    assertEquals(3, count); // 000 001 002
 
     scan = new Scan();
     scan.setSmall(small);
     scan.setReversed(true);
     scan.setStartRow(Bytes.toBytes("002"));
     scan.setStopRow(Bytes.toBytes("000"));
-    scanner = table.getScanner(scan);
-    count = 0;
-    lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+    try (ResultScanner scanner = table.getScanner(scan)) {
+      int count = 0;
+      byte[] lastRow = null;
+      for (Result r : scanner) {
+        assertTrue(!r.isEmpty());
+        count++;
+        byte[] thisRow = r.getRow();
+        if (lastRow != null) {
+          assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                          + ",this row=" + Bytes.toString(thisRow),
+                  Bytes.compareTo(thisRow, lastRow) < 0);
+        }
+        lastRow = thisRow;
       }
-      lastRow = thisRow;
+      assertEquals(2, count); // 001 002
     }
-    assertEquals(2, count); // 001 002
 
     scan = new Scan();
     scan.setSmall(small);
     scan.setReversed(true);
     scan.setStartRow(Bytes.toBytes("001"));
-    scanner = table.getScanner(scan);
-    count = 0;
-    lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+    try (ResultScanner scanner = table.getScanner(scan)) {
+      int count = 0;
+      byte[] lastRow = null;
+      for (Result r : scanner) {
+        assertTrue(!r.isEmpty());
+        count++;
+        byte[] thisRow = r.getRow();
+        if (lastRow != null) {
+          assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                          + ",this row=" + Bytes.toString(thisRow),
+                  Bytes.compareTo(thisRow, lastRow) < 0);
+        }
+        lastRow = thisRow;
       }
-      lastRow = thisRow;
+      assertEquals(2, count); // 000 001
     }
-    assertEquals(2, count); // 000 001
 
     scan = new Scan();
     scan.setSmall(small);
     scan.setReversed(true);
     scan.setStartRow(Bytes.toBytes("000"));
-    scanner = table.getScanner(scan);
-    count = 0;
-    lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+    try (ResultScanner scanner = table.getScanner(scan)) {
+      int count = 0;
+      byte[] lastRow = null;
+      for (Result r : scanner) {
+        assertTrue(!r.isEmpty());
+        count++;
+        byte[] thisRow = r.getRow();
+        if (lastRow != null) {
+          assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                          + ",this row=" + Bytes.toString(thisRow),
+                  Bytes.compareTo(thisRow, lastRow) < 0);
+        }
+        lastRow = thisRow;
       }
-      lastRow = thisRow;
+      assertEquals(1, count); // 000
     }
-    assertEquals(1, count); // 000
 
     scan = new Scan();
     scan.setSmall(small);
     scan.setReversed(true);
     scan.setStartRow(Bytes.toBytes("006"));
     scan.setStopRow(Bytes.toBytes("002"));
-    scanner = table.getScanner(scan);
-    count = 0;
-    lastRow = null;
-    for (Result r : scanner) {
-      assertTrue(!r.isEmpty());
-      count++;
-      byte[] thisRow = r.getRow();
-      if (lastRow != null) {
-        assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
-            + ",this row=" + Bytes.toString(thisRow),
-            Bytes.compareTo(thisRow, lastRow) < 0);
+    try (ResultScanner scanner = table.getScanner(scan)) {
+      int count = 0;
+      byte[] lastRow = null;
+      for (Result r : scanner) {
+        assertTrue(!r.isEmpty());
+        count++;
+        byte[] thisRow = r.getRow();
+        if (lastRow != null) {
+          assertTrue("Error scan order, last row= " + Bytes.toString(lastRow)
+                          + ",this row=" + Bytes.toString(thisRow),
+                  Bytes.compareTo(thisRow, lastRow) < 0);
+        }
+        lastRow = thisRow;
       }
-      lastRow = thisRow;
+      assertEquals(4, count); // 003 004 005 006
     }
-    assertEquals(4, count); // 003 004 005 006
   }
 
   private static Pair<byte[][], byte[][]> getStartEndKeys(List<RegionLocations> regions) {
@@ -6373,20 +6479,21 @@ public class TestFromClientSide {
     HColumnDescriptor fam = new HColumnDescriptor(FAMILY);
     htd.addFamily(fam);
     byte[][] KEYS = HBaseTestingUtility.KEYS_FOR_HBA_CREATE_TABLE;
-    Admin admin = TEST_UTIL.getAdmin();
-    admin.createTable(htd, KEYS);
-    HRegionLocator locator =
-      (HRegionLocator) admin.getConnection().getRegionLocator(htd.getTableName());
-    List<HRegionLocation> results = locator.getAllRegionLocations();
-    int number = ((ConnectionImplementation)admin.getConnection())
-      .getNumberOfCachedRegionLocations(htd.getTableName());
-    assertEquals(results.size(), number);
-    ConnectionImplementation conn = ((ConnectionImplementation)admin.getConnection());
-    assertNotNull("Can't get cached location for row aaa",
-        conn.getCachedLocation(htd.getTableName(),Bytes.toBytes("aaa")));
-    for(byte[] startKey:HBaseTestingUtility.KEYS_FOR_HBA_CREATE_TABLE){
-      assertNotNull("Can't get cached location for row "+
-        Bytes.toString(startKey),(conn.getCachedLocation(htd.getTableName(),startKey)));
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      admin.createTable(htd, KEYS);
+      HRegionLocator locator =
+              (HRegionLocator) admin.getConnection().getRegionLocator(htd.getTableName());
+      List<HRegionLocation> results = locator.getAllRegionLocations();
+      int number = ((ConnectionImplementation) admin.getConnection())
+              .getNumberOfCachedRegionLocations(htd.getTableName());
+      assertEquals(results.size(), number);
+      ConnectionImplementation conn = ((ConnectionImplementation) admin.getConnection());
+      assertNotNull("Can't get cached location for row aaa",
+              conn.getCachedLocation(htd.getTableName(), Bytes.toBytes("aaa")));
+      for (byte[] startKey : HBaseTestingUtility.KEYS_FOR_HBA_CREATE_TABLE) {
+        assertNotNull("Can't get cached location for row " +
+                Bytes.toString(startKey), (conn.getCachedLocation(htd.getTableName(), startKey)));
+      }
     }
   }
 
@@ -6397,8 +6504,9 @@ public class TestFromClientSide {
     htd.setConfiguration(HRegion.HBASE_MAX_CELL_SIZE_KEY, Integer.toString(10 * 1024)); // 10K
     HColumnDescriptor fam = new HColumnDescriptor(FAMILY);
     htd.addFamily(fam);
-    Admin admin = TEST_UTIL.getAdmin();
-    admin.createTable(htd);
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      admin.createTable(htd);
+    }
     // Will succeed
     try (Table t = TEST_UTIL.getConnection().getTable(tableName)) {
       t.put(new Put(ROW).addColumn(FAMILY, QUALIFIER, Bytes.toBytes(0L)));
@@ -6427,110 +6535,108 @@ public class TestFromClientSide {
 
   @Test
   public void testDeleteSpecifiedVersionOfSpecifiedColumn() throws Exception {
-    Admin admin = TEST_UTIL.getAdmin();
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      final TableName tableName = TableName.valueOf(name.getMethodName());
 
-    byte[][] VALUES = makeN(VALUE, 5);
-    long[] ts = { 1000, 2000, 3000, 4000, 5000 };
+      byte[][] VALUES = makeN(VALUE, 5);
+      long[] ts = {1000, 2000, 3000, 4000, 5000};
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5);
+      try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) {
 
-    Put put = new Put(ROW);
-    // Put version 1000,2000,3000,4000 of column FAMILY:QUALIFIER
-    for (int t = 0; t < 4; t++) {
-      put.addColumn(FAMILY, QUALIFIER, ts[t], VALUES[t]);
+        Put put = new Put(ROW);
+        // Put version 1000,2000,3000,4000 of column FAMILY:QUALIFIER
+        for (int t = 0; t < 4; t++) {
+          put.addColumn(FAMILY, QUALIFIER, ts[t], VALUES[t]);
+        }
+        ht.put(put);
+
+        Delete delete = new Delete(ROW);
+        // Delete version 3000 of column FAMILY:QUALIFIER
+        delete.addColumn(FAMILY, QUALIFIER, ts[2]);
+        ht.delete(delete);
+
+        Get get = new Get(ROW);
+        get.addColumn(FAMILY, QUALIFIER);
+        get.readVersions(Integer.MAX_VALUE);
+        Result result = ht.get(get);
+        // verify version 1000,2000,4000 remains for column FAMILY:QUALIFIER
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[0], ts[1], ts[3]}, new byte[][]{
+                VALUES[0], VALUES[1], VALUES[3]}, 0, 2);
+
+        delete = new Delete(ROW);
+        // Delete a version 5000 of column FAMILY:QUALIFIER which didn't exist
+        delete.addColumn(FAMILY, QUALIFIER, ts[4]);
+        ht.delete(delete);
+
+        get = new Get(ROW);
+        get.addColumn(FAMILY, QUALIFIER);
+        get.readVersions(Integer.MAX_VALUE);
+        result = ht.get(get);
+        // verify version 1000,2000,4000 remains for column FAMILY:QUALIFIER
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[0], ts[1], ts[3]}, new byte[][]{
+                VALUES[0], VALUES[1], VALUES[3]}, 0, 2);
+      }
     }
-    ht.put(put);
-
-    Delete delete = new Delete(ROW);
-    // Delete version 3000 of column FAMILY:QUALIFIER
-    delete.addColumn(FAMILY, QUALIFIER, ts[2]);
-    ht.delete(delete);
-
-    Get get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    Result result = ht.get(get);
-    // verify version 1000,2000,4000 remains for column FAMILY:QUALIFIER
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[0], ts[1], ts[3] }, new byte[][] {
-        VALUES[0], VALUES[1], VALUES[3] }, 0, 2);
-
-    delete = new Delete(ROW);
-    // Delete a version 5000 of column FAMILY:QUALIFIER which didn't exist
-    delete.addColumn(FAMILY, QUALIFIER, ts[4]);
-    ht.delete(delete);
-
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    // verify version 1000,2000,4000 remains for column FAMILY:QUALIFIER
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[0], ts[1], ts[3] }, new byte[][] {
-        VALUES[0], VALUES[1], VALUES[3] }, 0, 2);
-
-    ht.close();
-    admin.close();
   }
 
   @Test
   public void testDeleteLatestVersionOfSpecifiedColumn() throws Exception {
-    Admin admin = TEST_UTIL.getAdmin();
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      final TableName tableName = TableName.valueOf(name.getMethodName());
 
-    byte[][] VALUES = makeN(VALUE, 5);
-    long[] ts = { 1000, 2000, 3000, 4000, 5000 };
+      byte[][] VALUES = makeN(VALUE, 5);
+      long[] ts = {1000, 2000, 3000, 4000, 5000};
 
-    Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5);
+      try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 5)) {
 
-    Put put = new Put(ROW);
-    // Put version 1000,2000,3000,4000 of column FAMILY:QUALIFIER
-    for (int t = 0; t < 4; t++) {
-      put.addColumn(FAMILY, QUALIFIER, ts[t], VALUES[t]);
+        Put put = new Put(ROW);
+        // Put version 1000,2000,3000,4000 of column FAMILY:QUALIFIER
+        for (int t = 0; t < 4; t++) {
+          put.addColumn(FAMILY, QUALIFIER, ts[t], VALUES[t]);
+        }
+        ht.put(put);
+
+        Delete delete = new Delete(ROW);
+        // Delete latest version of column FAMILY:QUALIFIER
+        delete.addColumn(FAMILY, QUALIFIER);
+        ht.delete(delete);
+
+        Get get = new Get(ROW);
+        get.addColumn(FAMILY, QUALIFIER);
+        get.readVersions(Integer.MAX_VALUE);
+        Result result = ht.get(get);
+        // verify version 1000,2000,3000 remains for column FAMILY:QUALIFIER
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[0], ts[1], ts[2]}, new byte[][]{
+                VALUES[0], VALUES[1], VALUES[2]}, 0, 2);
+
+        delete = new Delete(ROW);
+        // Delete two latest version of column FAMILY:QUALIFIER
+        delete.addColumn(FAMILY, QUALIFIER);
+        delete.addColumn(FAMILY, QUALIFIER);
+        ht.delete(delete);
+
+        get = new Get(ROW);
+        get.addColumn(FAMILY, QUALIFIER);
+        get.readVersions(Integer.MAX_VALUE);
+        result = ht.get(get);
+        // verify version 1000 remains for column FAMILY:QUALIFIER
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[0]}, new byte[][]{VALUES[0]},
+                0, 0);
+
+        put = new Put(ROW);
+        // Put a version 5000 of column FAMILY:QUALIFIER
+        put.addColumn(FAMILY, QUALIFIER, ts[4], VALUES[4]);
+        ht.put(put);
+
+        get = new Get(ROW);
+        get.addColumn(FAMILY, QUALIFIER);
+        get.readVersions(Integer.MAX_VALUE);
+        result = ht.get(get);
+        // verify version 1000,5000 remains for column FAMILY:QUALIFIER
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[0], ts[4]}, new byte[][]{
+                VALUES[0], VALUES[4]}, 0, 1);
+      }
     }
-    ht.put(put);
-
-    Delete delete = new Delete(ROW);
-    // Delete latest version of column FAMILY:QUALIFIER
-    delete.addColumn(FAMILY, QUALIFIER);
-    ht.delete(delete);
-
-    Get get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    Result result = ht.get(get);
-    // verify version 1000,2000,3000 remains for column FAMILY:QUALIFIER
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[0], ts[1], ts[2] }, new byte[][] {
-        VALUES[0], VALUES[1], VALUES[2] }, 0, 2);
-
-    delete = new Delete(ROW);
-    // Delete two latest version of column FAMILY:QUALIFIER
-    delete.addColumn(FAMILY, QUALIFIER);
-    delete.addColumn(FAMILY, QUALIFIER);
-    ht.delete(delete);
-
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    // verify version 1000 remains for column FAMILY:QUALIFIER
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[0] }, new byte[][] { VALUES[0] },
-      0, 0);
-
-    put = new Put(ROW);
-    // Put a version 5000 of column FAMILY:QUALIFIER
-    put.addColumn(FAMILY, QUALIFIER, ts[4], VALUES[4]);
-    ht.put(put);
-
-    get = new Get(ROW);
-    get.addColumn(FAMILY, QUALIFIER);
-    get.readVersions(Integer.MAX_VALUE);
-    result = ht.get(get);
-    // verify version 1000,5000 remains for column FAMILY:QUALIFIER
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[0], ts[4] }, new byte[][] {
-        VALUES[0], VALUES[4] }, 0, 1);
-
-    ht.close();
-    admin.close();
   }
 
   /**
@@ -6538,137 +6644,143 @@ public class TestFromClientSide {
    */
   @Test
   public void testReadWithFilter() throws Exception {
-    Admin admin = TEST_UTIL.getAdmin();
-    final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY, 3);
-
-    byte[] VALUEA = Bytes.toBytes("value-a");
-    byte[] VALUEB = Bytes.toBytes("value-b");
-    long[] ts = { 1000, 2000, 3000, 4000 };
-
-    Put put = new Put(ROW);
-    // Put version 1000,2000,3000,4000 of column FAMILY:QUALIFIER
-    for (int t = 0; t <= 3; t++) {
-      if (t <= 1) {
-        put.addColumn(FAMILY, QUALIFIER, ts[t], VALUEA);
-      } else {
-        put.addColumn(FAMILY, QUALIFIER, ts[t], VALUEB);
+    try (Admin admin = TEST_UTIL.getAdmin()) {
+      final TableName tableName = TableName.valueOf(name.getMethodName());
+      try (Table table = TEST_UTIL.createTable(tableName, FAMILY, 3)) {
+
+        byte[] VALUEA = Bytes.toBytes("value-a");
+        byte[] VALUEB = Bytes.toBytes("value-b");
+        long[] ts = {1000, 2000, 3000, 4000};
+
+        Put put = new Put(ROW);
+        // Put version 1000,2000,3000,4000 of column FAMILY:QUALIFIER
+        for (int t = 0; t <= 3; t++) {
+          if (t <= 1) {
+            put.addColumn(FAMILY, QUALIFIER, ts[t], VALUEA);
+          } else {
+            put.addColumn(FAMILY, QUALIFIER, ts[t], VALUEB);
+          }
+        }
+        table.put(put);
+
+        Scan scan =
+                new Scan().setFilter(new ValueFilter(CompareOperator.EQUAL,
+                        new SubstringComparator("value-a")))
+                        .setMaxVersions(3);
+        ResultScanner scanner = table.getScanner(scan);
+        Result result = scanner.next();
+        // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[1]}, new byte[][]{VALUEA}, 0,
+                0);
+
+        Get get =
+                new Get(ROW)
+                        .setFilter(new ValueFilter(CompareOperator.EQUAL,
+                                new SubstringComparator("value-a")))
+                        .readVersions(3);
+        result = table.get(get);
+        // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[1]}, new byte[][]{VALUEA}, 0,
+                0);
+
+        // Test with max versions 1, it should still read ts[1]
+        scan =
+                new Scan().setFilter(new ValueFilter(CompareOperator.EQUAL,
+                        new SubstringComparator("value-a")))
+                        .setMaxVersions(1);
+        scanner = table.getScanner(scan);
+        result = scanner.next();
+        // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[1]}, new byte[][]{VALUEA}, 0,
+                0);
+
+        // Test with max versions 1, it should still read ts[1]
+        get =
+                new Get(ROW)
+                        .setFilter(new ValueFilter(CompareOperator.EQUAL,
+                                new SubstringComparator("value-a")))
+                        .readVersions(1);
+        result = table.get(get);
+        // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[1]}, new byte[][]{VALUEA}, 0,
+                0);
+
+        // Test with max versions 5, it should still read ts[1]
+        scan =
+                new Scan().setFilter(new ValueFilter(CompareOperator.EQUAL,
+                        new SubstringComparator("value-a")))
+                        .setMaxVersions(5);
+        scanner = table.getScanner(scan);
+        result = scanner.next();
+        // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[1]}, new byte[][]{VALUEA}, 0,
+                0);
+
+        // Test with max versions 5, it should still read ts[1]
+        get =
+                new Get(ROW)
+                        .setFilter(new ValueFilter(CompareOperator.EQUAL,
+                                new SubstringComparator("value-a")))
+                        .readVersions(5);
+        result = table.get(get);
+        // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
+        assertNResult(result, ROW, FAMILY, QUALIFIER, new long[]{ts[1]}, new byte[][]{VALUEA}, 0,
+                0);
       }
     }
-    table.put(put);
-
-    Scan scan =
-        new Scan().setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value-a")))
-            .setMaxVersions(3);
-    ResultScanner scanner = table.getScanner(scan);
-    Result result = scanner.next();
-    // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[1] }, new byte[][] { VALUEA }, 0,
-      0);
-
-    Get get =
-        new Get(ROW)
-            .setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value-a")))
-            .readVersions(3);
-    result = table.get(get);
-    // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[1] }, new byte[][] { VALUEA }, 0,
-      0);
-
-    // Test with max versions 1, it should still read ts[1]
-    scan =
-        new Scan().setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value-a")))
-            .setMaxVersions(1);
-    scanner = table.getScanner(scan);
-    result = scanner.next();
-    // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[1] }, new byte[][] { VALUEA }, 0,
-      0);
-
-    // Test with max versions 1, it should still read ts[1]
-    get =
-        new Get(ROW)
-            .setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value-a")))
-            .readVersions(1);
-    result = table.get(get);
-    // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[1] }, new byte[][] { VALUEA }, 0,
-      0);
-
-    // Test with max versions 5, it should still read ts[1]
-    scan =
-        new Scan().setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value-a")))
-            .setMaxVersions(5);
-    scanner = table.getScanner(scan);
-    result = scanner.next();
-    // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[1] }, new byte[][] { VALUEA }, 0,
-      0);
-
-    // Test with max versions 5, it should still read ts[1]
-    get =
-        new Get(ROW)
-            .setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value-a")))
-            .readVersions(5);
-    result = table.get(get);
-    // ts[0] has gone from user view. Only read ts[2] which value is less or equal to 3
-    assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { ts[1] }, new byte[][] { VALUEA }, 0,
-      0);
-
-    table.close();
-    admin.close();
   }
 
   @Test
   public void testCellUtilTypeMethods() throws IOException {
     final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table table = TEST_UTIL.createTable(tableName, FAMILY);
+    try (Table table = TEST_UTIL.createTable(tableName, FAMILY)) {
 
-    final byte[] row = Bytes.toBytes("p");
-    Put p = new Put(row);
-    p.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(p);
+      final byte[] row = Bytes.toBytes("p");
+      Put p = new Put(row);
+      p.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(p);
 
-    try (ResultScanner scanner = table.getScanner(new Scan())) {
-      Result result = scanner.next();
-      assertNotNull(result);
-      CellScanner cs = result.cellScanner();
-      assertTrue(cs.advance());
-      Cell c = cs.current();
-      assertTrue(CellUtil.isPut(c));
-      assertFalse(CellUtil.isDelete(c));
-      assertFalse(cs.advance());
-      assertNull(scanner.next());
-    }
+      try (ResultScanner scanner = table.getScanner(new Scan())) {
+        Result result = scanner.next();
+        assertNotNull(result);
+        CellScanner cs = result.cellScanner();
+        assertTrue(cs.advance());
+        Cell c = cs.current();
+        assertTrue(CellUtil.isPut(c));
+        assertFalse(CellUtil.isDelete(c));
+        assertFalse(cs.advance());
+        assertNull(scanner.next());
+      }
 
-    Delete d = new Delete(row);
-    d.addColumn(FAMILY, QUALIFIER);
-    table.delete(d);
+      Delete d = new Delete(row);
+      d.addColumn(FAMILY, QUALIFIER);
+      table.delete(d);
 
-    Scan scan = new Scan();
-    scan.setRaw(true);
-    try (ResultScanner scanner = table.getScanner(scan)) {
-      Result result = scanner.next();
-      assertNotNull(result);
-      CellScanner cs = result.cellScanner();
-      assertTrue(cs.advance());
-
-      // First cell should be the delete (masking the Put)
-      Cell c = cs.current();
-      assertTrue("Cell should be a Delete: " + c, CellUtil.isDelete(c));
-      assertFalse("Cell should not be a Put: " + c, CellUtil.isPut(c));
-
-      // Second cell should be the original Put
-      assertTrue(cs.advance());
-      c = cs.current();
-      assertFalse("Cell should not be a Delete: " + c, CellUtil.isDelete(c));
-      assertTrue("Cell should be a Put: " + c, CellUtil.isPut(c));
-
-      // No more cells in this row
-      assertFalse(cs.advance());
-
-      // No more results in this scan
-      assertNull(scanner.next());
+      Scan scan = new Scan();
+      scan.setRaw(true);
+      try (ResultScanner scanner = table.getScanner(scan)) {
+        Result result = scanner.next();
+        assertNotNull(result);
+        CellScanner cs = result.cellScanner();
+        assertTrue(cs.advance());
+
+        // First cell should be the delete (masking the Put)
+        Cell c = cs.current();
+        assertTrue("Cell should be a Delete: " + c, CellUtil.isDelete(c));
+        assertFalse("Cell should not be a Put: " + c, CellUtil.isPut(c));
+
+        // Second cell should be the original Put
+        assertTrue(cs.advance());
+        c = cs.current();
+        assertFalse("Cell should not be a Delete: " + c, CellUtil.isDelete(c));
+        assertTrue("Cell should be a Put: " + c, CellUtil.isPut(c));
+
+        // No more cells in this row
+        assertFalse(cs.advance());
+
+        // No more results in this scan
+        assertNull(scanner.next());
+      }
     }
   }
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
index 2d021bb..9ec7b96 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
@@ -90,6 +90,7 @@ public class TestFromClientSide3 {
   private static final Logger LOG = LoggerFactory.getLogger(TestFromClientSide3.class);
   private final static HBaseTestingUtility TEST_UTIL
     = new HBaseTestingUtility();
+  private static final int WAITTABLE_MILLIS = 10000;
   private static byte[] FAMILY = Bytes.toBytes("testFamily");
   private static Random random = new Random();
   private static int SLAVES = 3;
@@ -103,6 +104,7 @@ public class TestFromClientSide3 {
 
   @Rule
   public TestName name = new TestName();
+  private TableName tableName;
 
   /**
    * @throws java.lang.Exception
@@ -122,7 +124,7 @@ public class TestFromClientSide3 {
 
   @Before
   public void setUp() throws Exception {
-    // Nothing to do.
+    tableName = TableName.valueOf(name.getMethodName());
   }
 
   @After
@@ -178,86 +180,78 @@ public class TestFromClientSide3 {
   }
 
   @Test
-  public void testScanAfterDeletingSpecifiedRow() throws IOException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
-    TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
-            .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY))
-            .build();
-    TEST_UTIL.getAdmin().createTable(desc);
-    byte[] row = Bytes.toBytes("SpecifiedRow");
-    byte[] value0 = Bytes.toBytes("value_0");
-    byte[] value1 = Bytes.toBytes("value_1");
-    try (Table t = TEST_UTIL.getConnection().getTable(tableName)) {
+  public void testScanAfterDeletingSpecifiedRow() throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+      byte[] row = Bytes.toBytes("SpecifiedRow");
+      byte[] value0 = Bytes.toBytes("value_0");
+      byte[] value1 = Bytes.toBytes("value_1");
       Put put = new Put(row);
       put.addColumn(FAMILY, QUALIFIER, VALUE);
-      t.put(put);
+      table.put(put);
       Delete d = new Delete(row);
-      t.delete(d);
+      table.delete(d);
       put = new Put(row);
       put.addColumn(FAMILY, null, value0);
-      t.put(put);
+      table.put(put);
       put = new Put(row);
       put.addColumn(FAMILY, null, value1);
-      t.put(put);
-      List<Cell> cells = toList(t.getScanner(new Scan()));
+      table.put(put);
+      List<Cell> cells = toList(table.getScanner(new Scan()));
       assertEquals(1, cells.size());
       assertEquals("value_1", Bytes.toString(CellUtil.cloneValue(cells.get(0))));
 
-      cells = toList(t.getScanner(new Scan().addFamily(FAMILY)));
+      cells = toList(table.getScanner(new Scan().addFamily(FAMILY)));
       assertEquals(1, cells.size());
       assertEquals("value_1", Bytes.toString(CellUtil.cloneValue(cells.get(0))));
 
-      cells = toList(t.getScanner(new Scan().addColumn(FAMILY, QUALIFIER)));
+      cells = toList(table.getScanner(new Scan().addColumn(FAMILY, QUALIFIER)));
       assertEquals(0, cells.size());
 
       TEST_UTIL.getAdmin().flush(tableName);
-      cells = toList(t.getScanner(new Scan()));
+      cells = toList(table.getScanner(new Scan()));
       assertEquals(1, cells.size());
       assertEquals("value_1", Bytes.toString(CellUtil.cloneValue(cells.get(0))));
 
-      cells = toList(t.getScanner(new Scan().addFamily(FAMILY)));
+      cells = toList(table.getScanner(new Scan().addFamily(FAMILY)));
       assertEquals(1, cells.size());
       assertEquals("value_1", Bytes.toString(CellUtil.cloneValue(cells.get(0))));
 
-      cells = toList(t.getScanner(new Scan().addColumn(FAMILY, QUALIFIER)));
+      cells = toList(table.getScanner(new Scan().addColumn(FAMILY, QUALIFIER)));
       assertEquals(0, cells.size());
     }
   }
 
   @Test
-  public void testScanAfterDeletingSpecifiedRowV2() throws IOException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
-    TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
-            .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY))
-            .build();
-    TEST_UTIL.getAdmin().createTable(desc);
-    byte[] row = Bytes.toBytes("SpecifiedRow");
-    byte[] qual0 = Bytes.toBytes("qual0");
-    byte[] qual1 = Bytes.toBytes("qual1");
-    try (Table t = TEST_UTIL.getConnection().getTable(tableName)) {
+  public void testScanAfterDeletingSpecifiedRowV2() throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+      byte[] row = Bytes.toBytes("SpecifiedRow");
+      byte[] qual0 = Bytes.toBytes("qual0");
+      byte[] qual1 = Bytes.toBytes("qual1");
       Delete d = new Delete(row);
-      t.delete(d);
+      table.delete(d);
 
       Put put = new Put(row);
       put.addColumn(FAMILY, null, VALUE);
-      t.put(put);
+      table.put(put);
 
       put = new Put(row);
       put.addColumn(FAMILY, qual1, qual1);
-      t.put(put);
+      table.put(put);
 
       put = new Put(row);
       put.addColumn(FAMILY, qual0, qual0);
-      t.put(put);
+      table.put(put);
 
-      Result r = t.get(new Get(row));
+      Result r = table.get(new Get(row));
       assertEquals(3, r.size());
       assertEquals("testValue", Bytes.toString(CellUtil.cloneValue(r.rawCells()[0])));
       assertEquals("qual0", Bytes.toString(CellUtil.cloneValue(r.rawCells()[1])));
       assertEquals("qual1", Bytes.toString(CellUtil.cloneValue(r.rawCells()[2])));
 
       TEST_UTIL.getAdmin().flush(tableName);
-      r = t.get(new Get(row));
+      r = table.get(new Get(row));
       assertEquals(3, r.size());
       assertEquals("testValue", Bytes.toString(CellUtil.cloneValue(r.rawCells()[0])));
       assertEquals("qual0", Bytes.toString(CellUtil.cloneValue(r.rawCells()[1])));
@@ -279,110 +273,112 @@ public class TestFromClientSide3 {
      */
     TEST_UTIL.getConfiguration().setInt("hbase.hstore.compaction.min", 3);
 
-    final TableName tableName = TableName.valueOf(name.getMethodName());
-    Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10);
-    Admin admin = TEST_UTIL.getAdmin();
-    ClusterConnection connection = (ClusterConnection) TEST_UTIL.getConnection();
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+      try (Admin admin = TEST_UTIL.getAdmin()) {
+        ClusterConnection connection = (ClusterConnection) TEST_UTIL.getConnection();
+
+        // Create 3 store files.
+        byte[] row = Bytes.toBytes(random.nextInt());
+        performMultiplePutAndFlush((HBaseAdmin) admin, table, row, FAMILY, 3, 100);
+
+        try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
+          // Verify we have multiple store files.
+          HRegionLocation loc = locator.getRegionLocation(row, true);
+          byte[] regionName = loc.getRegionInfo().getRegionName();
+          AdminProtos.AdminService.BlockingInterface server =
+                  connection.getAdmin(loc.getServerName());
+          assertTrue(ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() > 1);
+
+          // Issue a compaction request
+          admin.compact(tableName);
+
+          // poll wait for the compactions to happen
+          for (int i = 0; i < 10 * 1000 / 40; ++i) {
+            // The number of store files after compaction should be lesser.
+            loc = locator.getRegionLocation(row, true);
+            if (!loc.getRegionInfo().isOffline()) {
+              regionName = loc.getRegionInfo().getRegionName();
+              server = connection.getAdmin(loc.getServerName());
+              if (ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() <= 1) {
+                break;
+              }
+            }
+            Thread.sleep(40);
+          }
+          // verify the compactions took place and that we didn't just time out
+          assertTrue(ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() <= 1);
 
-    // Create 3 store files.
-    byte[] row = Bytes.toBytes(random.nextInt());
-    performMultiplePutAndFlush((HBaseAdmin) admin, hTable, row, FAMILY, 3, 100);
+          // change the compaction.min config option for this table to 5
+          LOG.info("hbase.hstore.compaction.min should now be 5");
+          HTableDescriptor htd = new HTableDescriptor(table.getTableDescriptor());
+          htd.setValue("hbase.hstore.compaction.min", String.valueOf(5));
+          admin.modifyTable(htd);
+          LOG.info("alter status finished");
 
-    try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
-      // Verify we have multiple store files.
-      HRegionLocation loc = locator.getRegionLocation(row, true);
-      byte[] regionName = loc.getRegionInfo().getRegionName();
-      AdminProtos.AdminService.BlockingInterface server = connection.getAdmin(loc.getServerName());
-      assertTrue(ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() > 1);
-
-      // Issue a compaction request
-      admin.compact(tableName);
-
-      // poll wait for the compactions to happen
-      for (int i = 0; i < 10 * 1000 / 40; ++i) {
-        // The number of store files after compaction should be lesser.
-        loc = locator.getRegionLocation(row, true);
-        if (!loc.getRegionInfo().isOffline()) {
+          // Create 3 more store files.
+          performMultiplePutAndFlush((HBaseAdmin) admin, table, row, FAMILY, 3, 10);
+
+          // Issue a compaction request
+          admin.compact(tableName);
+
+          // This time, the compaction request should not happen
+          Thread.sleep(10 * 1000);
+          loc = locator.getRegionLocation(row, true);
           regionName = loc.getRegionInfo().getRegionName();
           server = connection.getAdmin(loc.getServerName());
-          if (ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() <= 1) {
-            break;
-          }
-        }
-        Thread.sleep(40);
-      }
-      // verify the compactions took place and that we didn't just time out
-      assertTrue(ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() <= 1);
-
-      // change the compaction.min config option for this table to 5
-      LOG.info("hbase.hstore.compaction.min should now be 5");
-      HTableDescriptor htd = new HTableDescriptor(hTable.getTableDescriptor());
-      htd.setValue("hbase.hstore.compaction.min", String.valueOf(5));
-      admin.modifyTable(htd);
-      LOG.info("alter status finished");
-
-      // Create 3 more store files.
-      performMultiplePutAndFlush((HBaseAdmin) admin, hTable, row, FAMILY, 3, 10);
-
-      // Issue a compaction request
-      admin.compact(tableName);
-
-      // This time, the compaction request should not happen
-      Thread.sleep(10 * 1000);
-      loc = locator.getRegionLocation(row, true);
-      regionName = loc.getRegionInfo().getRegionName();
-      server = connection.getAdmin(loc.getServerName());
-      int sfCount = ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size();
-      assertTrue(sfCount > 1);
-
-      // change an individual CF's config option to 2 & online schema update
-      LOG.info("hbase.hstore.compaction.min should now be 2");
-      HColumnDescriptor hcd = new HColumnDescriptor(htd.getFamily(FAMILY));
-      hcd.setValue("hbase.hstore.compaction.min", String.valueOf(2));
-      htd.modifyFamily(hcd);
-      admin.modifyTable(htd);
-      LOG.info("alter status finished");
-
-      // Issue a compaction request
-      admin.compact(tableName);
-
-      // poll wait for the compactions to happen
-      for (int i = 0; i < 10 * 1000 / 40; ++i) {
-        loc = locator.getRegionLocation(row, true);
-        regionName = loc.getRegionInfo().getRegionName();
-        try {
-          server = connection.getAdmin(loc.getServerName());
-          if (ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() < sfCount) {
-            break;
+          int sfCount = ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size();
+          assertTrue(sfCount > 1);
+
+          // change an individual CF's config option to 2 & online schema update
+          LOG.info("hbase.hstore.compaction.min should now be 2");
+          HColumnDescriptor hcd = new HColumnDescriptor(htd.getFamily(FAMILY));
+          hcd.setValue("hbase.hstore.compaction.min", String.valueOf(2));
+          htd.modifyFamily(hcd);
+          admin.modifyTable(htd);
+          LOG.info("alter status finished");
+
+          // Issue a compaction request
+          admin.compact(tableName);
+
+          // poll wait for the compactions to happen
+          for (int i = 0; i < 10 * 1000 / 40; ++i) {
+            loc = locator.getRegionLocation(row, true);
+            regionName = loc.getRegionInfo().getRegionName();
+            try {
+              server = connection.getAdmin(loc.getServerName());
+              if (ProtobufUtil.getStoreFiles(server, regionName, FAMILY).size() < sfCount) {
+                break;
+              }
+            } catch (Exception e) {
+              LOG.debug("Waiting for region to come online: " + Bytes.toString(regionName));
+            }
+            Thread.sleep(40);
           }
-        } catch (Exception e) {
-          LOG.debug("Waiting for region to come online: " + Bytes.toString(regionName));
+
+          // verify the compaction took place and that we didn't just time out
+          assertTrue(ProtobufUtil.getStoreFiles(
+                  server, regionName, FAMILY).size() < sfCount);
+
+          // Finally, ensure that we can remove a custom config value after we made it
+          LOG.info("Removing CF config value");
+          LOG.info("hbase.hstore.compaction.min should now be 5");
+          hcd = new HColumnDescriptor(htd.getFamily(FAMILY));
+          hcd.setValue("hbase.hstore.compaction.min", null);
+          htd.modifyFamily(hcd);
+          admin.modifyTable(htd);
+          LOG.info("alter status finished");
+          assertNull(table.getTableDescriptor().getFamily(FAMILY).getValue(
+                  "hbase.hstore.compaction.min"));
         }
-        Thread.sleep(40);
       }
-
-      // verify the compaction took place and that we didn't just time out
-      assertTrue(ProtobufUtil.getStoreFiles(
-        server, regionName, FAMILY).size() < sfCount);
-
-      // Finally, ensure that we can remove a custom config value after we made it
-      LOG.info("Removing CF config value");
-      LOG.info("hbase.hstore.compaction.min should now be 5");
-      hcd = new HColumnDescriptor(htd.getFamily(FAMILY));
-      hcd.setValue("hbase.hstore.compaction.min", null);
-      htd.modifyFamily(hcd);
-      admin.modifyTable(htd);
-      LOG.info("alter status finished");
-      assertNull(hTable.getTableDescriptor().getFamily(FAMILY).getValue(
-          "hbase.hstore.compaction.min"));
     }
   }
 
   @Test
-  public void testHTableBatchWithEmptyPut ()throws Exception {
-      Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-          new byte[][] { FAMILY });
-    try {
+  public void testHTableBatchWithEmptyPut () throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
       List actions = (List) new ArrayList();
       Object[] results = new Object[2];
       // create an empty Put
@@ -396,24 +392,21 @@ public class TestFromClientSide3 {
       table.batch(actions, results);
       fail("Empty Put should have failed the batch call");
     } catch (IllegalArgumentException iae) {
-
-    } finally {
-      table.close();
     }
   }
 
   // Test Table.batch with large amount of mutations against the same key.
   // It used to trigger read lock's "Maximum lock count exceeded" Error.
   @Test
-  public void testHTableWithLargeBatch() throws Exception {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-        new byte[][] { FAMILY });
+  public void testHTableWithLargeBatch() throws IOException, InterruptedException {
     int sixtyFourK = 64 * 1024;
-    try {
-      List actions = new ArrayList();
-      Object[] results = new Object[(sixtyFourK + 1) * 2];
+    List actions = new ArrayList();
+    Object[] results = new Object[(sixtyFourK + 1) * 2];
+
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
-      for (int i = 0; i < sixtyFourK + 1; i ++) {
+      for (int i = 0; i < sixtyFourK + 1; i++) {
         Put put1 = new Put(ROW);
         put1.addColumn(FAMILY, QUALIFIER, VALUE);
         actions.add(put1);
@@ -424,44 +417,43 @@ public class TestFromClientSide3 {
       }
 
       table.batch(actions, results);
-    } finally {
-      table.close();
     }
   }
 
   @Test
   public void testBatchWithRowMutation() throws Exception {
     LOG.info("Starting testBatchWithRowMutation");
-    final TableName TABLENAME = TableName.valueOf("testBatchWithRowMutation");
-    try (Table t = TEST_UTIL.createTable(TABLENAME, FAMILY)) {
-      byte [][] QUALIFIERS = new byte [][] {
-        Bytes.toBytes("a"), Bytes.toBytes("b")
-      };
+    byte [][] QUALIFIERS = new byte [][] {
+      Bytes.toBytes("a"), Bytes.toBytes("b")
+    };
+
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
       RowMutations arm = RowMutations.of(Collections.singletonList(
-        new Put(ROW).addColumn(FAMILY, QUALIFIERS[0], VALUE)));
+              new Put(ROW).addColumn(FAMILY, QUALIFIERS[0], VALUE)));
       Object[] batchResult = new Object[1];
-      t.batch(Arrays.asList(arm), batchResult);
+      table.batch(Arrays.asList(arm), batchResult);
 
       Get g = new Get(ROW);
-      Result r = t.get(g);
+      Result r = table.get(g);
       assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIERS[0])));
 
       arm = RowMutations.of(Arrays.asList(
-        new Put(ROW).addColumn(FAMILY, QUALIFIERS[1], VALUE),
-        new Delete(ROW).addColumns(FAMILY, QUALIFIERS[0])));
-      t.batch(Arrays.asList(arm), batchResult);
-      r = t.get(g);
+              new Put(ROW).addColumn(FAMILY, QUALIFIERS[1], VALUE),
+              new Delete(ROW).addColumns(FAMILY, QUALIFIERS[0])));
+      table.batch(Arrays.asList(arm), batchResult);
+      r = table.get(g);
       assertEquals(0, Bytes.compareTo(VALUE, r.getValue(FAMILY, QUALIFIERS[1])));
       assertNull(r.getValue(FAMILY, QUALIFIERS[0]));
 
       // Test that we get the correct remote exception for RowMutations from batch()
       try {
         arm = RowMutations.of(Collections.singletonList(
-          new Put(ROW).addColumn(new byte[]{'b', 'o', 'g', 'u', 's'}, QUALIFIERS[0], VALUE)));
-        t.batch(Arrays.asList(arm), batchResult);
+                new Put(ROW).addColumn(new byte[]{'b', 'o', 'g', 'u', 's'}, QUALIFIERS[0], VALUE)));
+        table.batch(Arrays.asList(arm), batchResult);
         fail("Expected RetriesExhaustedWithDetailsException with NoSuchColumnFamilyException");
-      } catch(RetriesExhaustedWithDetailsException e) {
+      } catch (RetriesExhaustedWithDetailsException e) {
         String msg = e.getMessage();
         assertTrue(msg.contains("NoSuchColumnFamilyException"));
       }
@@ -469,49 +461,52 @@ public class TestFromClientSide3 {
   }
 
   @Test
-  public void testHTableExistsMethodSingleRegionSingleGet() throws Exception {
-      // Test with a single region table.
-      Table table = TEST_UTIL.createTable(
-          TableName.valueOf(name.getMethodName()),
-          new byte[][] { FAMILY });
+  public void testHTableExistsMethodSingleRegionSingleGet()
+          throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
+      // Test with a single region table.
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
 
-    Get get = new Get(ROW);
+      Get get = new Get(ROW);
 
-    boolean exist = table.exists(get);
-    assertFalse(exist);
+      boolean exist = table.exists(get);
+      assertFalse(exist);
 
-    table.put(put);
+      table.put(put);
 
-    exist = table.exists(get);
-    assertTrue(exist);
+      exist = table.exists(get);
+      assertTrue(exist);
+    }
   }
 
   @Test
-  public void testHTableExistsMethodSingleRegionMultipleGets() throws Exception {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(
-        name.getMethodName()), new byte[][] { FAMILY });
+  public void testHTableExistsMethodSingleRegionMultipleGets()
+          throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
 
-    List<Get> gets = new ArrayList<>();
-    gets.add(new Get(ROW));
-    gets.add(new Get(ANOTHERROW));
+      List<Get> gets = new ArrayList<>();
+      gets.add(new Get(ROW));
+      gets.add(new Get(ANOTHERROW));
 
-    boolean[] results = table.exists(gets);
-    assertTrue(results[0]);
-    assertFalse(results[1]);
+      boolean[] results = table.exists(gets);
+      assertTrue(results[0]);
+      assertFalse(results[1]);
+    }
   }
 
   @Test
-  public void testHTableExistsBeforeGet() throws Exception {
-    Table table = TEST_UTIL.createTable(TableName.valueOf(name.getMethodName()),
-        new byte[][] { FAMILY });
-    try {
+  public void testHTableExistsBeforeGet() throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+
       Put put = new Put(ROW);
       put.addColumn(FAMILY, QUALIFIER, VALUE);
       table.put(put);
@@ -524,17 +519,15 @@ public class TestFromClientSide3 {
       Result result = table.get(get);
       assertEquals(false, result.isEmpty());
       assertTrue(Bytes.equals(VALUE, result.getValue(FAMILY, QUALIFIER)));
-    } finally {
-      table.close();
     }
   }
 
   @Test
-  public void testHTableExistsAllBeforeGet() throws Exception {
-    final byte[] ROW2 = Bytes.add(ROW, Bytes.toBytes("2"));
-    Table table = TEST_UTIL.createTable(
-        TableName.valueOf(name.getMethodName()), new byte[][] { FAMILY });
-    try {
+  public void testHTableExistsAllBeforeGet() throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+
+      final byte[] ROW2 = Bytes.add(ROW, Bytes.toBytes("2"));
       Put put = new Put(ROW);
       put.addColumn(FAMILY, QUALIFIER, VALUE);
       table.put(put);
@@ -557,106 +550,107 @@ public class TestFromClientSide3 {
       assertTrue(Bytes.equals(VALUE, result[0].getValue(FAMILY, QUALIFIER)));
       assertEquals(false, result[1].isEmpty());
       assertTrue(Bytes.equals(VALUE, result[1].getValue(FAMILY, QUALIFIER)));
-    } finally {
-      table.close();
     }
   }
 
   @Test
   public void testHTableExistsMethodMultipleRegionsSingleGet() throws Exception {
-    Table table = TEST_UTIL.createTable(
-      TableName.valueOf(name.getMethodName()), new byte[][] { FAMILY },
-      1, new byte[] { 0x00 }, new byte[] { (byte) 0xff }, 255);
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
+    try (Table table = TEST_UTIL.createTable(
+      tableName, new byte[][] { FAMILY },
+      1, new byte[] { 0x00 }, new byte[] { (byte) 0xff }, 255)) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
-    Get get = new Get(ROW);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
 
-    boolean exist = table.exists(get);
-    assertFalse(exist);
+      Get get = new Get(ROW);
 
-    table.put(put);
+      boolean exist = table.exists(get);
+      assertFalse(exist);
+
+      table.put(put);
 
-    exist = table.exists(get);
-    assertTrue(exist);
+      exist = table.exists(get);
+      assertTrue(exist);
+    }
   }
 
   @Test
   public void testHTableExistsMethodMultipleRegionsMultipleGets() throws Exception {
-    Table table = TEST_UTIL.createTable(
-      TableName.valueOf(name.getMethodName()),
-      new byte[][] { FAMILY }, 1, new byte[] { 0x00 }, new byte[] { (byte) 0xff }, 255);
-    Put put = new Put(ROW);
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put (put);
-
-    List<Get> gets = new ArrayList<>();
-    gets.add(new Get(ANOTHERROW));
-    gets.add(new Get(Bytes.add(ROW, new byte[] { 0x00 })));
-    gets.add(new Get(ROW));
-    gets.add(new Get(Bytes.add(ANOTHERROW, new byte[] { 0x00 })));
-
-    LOG.info("Calling exists");
-    boolean[] results = table.existsAll(gets);
-    assertFalse(results[0]);
-    assertFalse(results[1]);
-    assertTrue(results[2]);
-    assertFalse(results[3]);
-
-    // Test with the first region.
-    put = new Put(new byte[] { 0x00 });
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
+    try (Table table = TEST_UTIL.createTable(
+      tableName,
+      new byte[][] { FAMILY }, 1, new byte[] { 0x00 }, new byte[] { (byte) 0xff }, 255)) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
-    gets = new ArrayList<>();
-    gets.add(new Get(new byte[] { 0x00 }));
-    gets.add(new Get(new byte[] { 0x00, 0x00 }));
-    results = table.existsAll(gets);
-    assertTrue(results[0]);
-    assertFalse(results[1]);
+      Put put = new Put(ROW);
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
 
-    // Test with the last region
-    put = new Put(new byte[] { (byte) 0xff, (byte) 0xff });
-    put.addColumn(FAMILY, QUALIFIER, VALUE);
-    table.put(put);
+      List<Get> gets = new ArrayList<>();
+      gets.add(new Get(ANOTHERROW));
+      gets.add(new Get(Bytes.add(ROW, new byte[]{0x00})));
+      gets.add(new Get(ROW));
+      gets.add(new Get(Bytes.add(ANOTHERROW, new byte[]{0x00})));
+
+      LOG.info("Calling exists");
+      boolean[] results = table.existsAll(gets);
+      assertFalse(results[0]);
+      assertFalse(results[1]);
+      assertTrue(results[2]);
+      assertFalse(results[3]);
+
+      // Test with the first region.
+      put = new Put(new byte[]{0x00});
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
 
-    gets = new ArrayList<>();
-    gets.add(new Get(new byte[] { (byte) 0xff }));
-    gets.add(new Get(new byte[] { (byte) 0xff, (byte) 0xff }));
-    gets.add(new Get(new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff }));
-    results = table.existsAll(gets);
-    assertFalse(results[0]);
-    assertTrue(results[1]);
-    assertFalse(results[2]);
+      gets = new ArrayList<>();
+      gets.add(new Get(new byte[]{0x00}));
+      gets.add(new Get(new byte[]{0x00, 0x00}));
+      results = table.existsAll(gets);
+      assertTrue(results[0]);
+      assertFalse(results[1]);
+
+      // Test with the last region
+      put = new Put(new byte[]{(byte) 0xff, (byte) 0xff});
+      put.addColumn(FAMILY, QUALIFIER, VALUE);
+      table.put(put);
+
+      gets = new ArrayList<>();
+      gets.add(new Get(new byte[]{(byte) 0xff}));
+      gets.add(new Get(new byte[]{(byte) 0xff, (byte) 0xff}));
+      gets.add(new Get(new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff}));
+      results = table.existsAll(gets);
+      assertFalse(results[0]);
+      assertTrue(results[1]);
+      assertFalse(results[2]);
+    }
   }
 
   @Test
   public void testGetEmptyRow() throws Exception {
     //Create a table and put in 1 row
-    Admin admin = TEST_UTIL.getAdmin();
-    HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(Bytes.toBytes(name.getMethodName())));
-    desc.addFamily(new HColumnDescriptor(FAMILY));
-    admin.createTable(desc);
-    Table table = TEST_UTIL.getConnection().getTable(desc.getTableName());
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
 
-    Put put = new Put(ROW_BYTES);
-    put.addColumn(FAMILY, COL_QUAL, VAL_BYTES);
-    table.put(put);
+      Put put = new Put(ROW_BYTES);
+      put.addColumn(FAMILY, COL_QUAL, VAL_BYTES);
+      table.put(put);
 
-    //Try getting the row with an empty row key
-    Result res = null;
-    try {
-      res = table.get(new Get(new byte[0]));
-      fail();
-    } catch (IllegalArgumentException e) {
-      // Expected.
+      //Try getting the row with an empty row key
+      Result res = null;
+      try {
+        res = table.get(new Get(new byte[0]));
+        fail();
+      } catch (IllegalArgumentException e) {
+        // Expected.
+      }
+      assertTrue(res == null);
+      res = table.get(new Get(Bytes.toBytes("r1-not-exist")));
+      assertTrue(res.isEmpty() == true);
+      res = table.get(new Get(ROW_BYTES));
+      assertTrue(Arrays.equals(res.getValue(FAMILY, COL_QUAL), VAL_BYTES));
     }
-    assertTrue(res == null);
-    res = table.get(new Get(Bytes.toBytes("r1-not-exist")));
-    assertTrue(res.isEmpty() == true);
-    res = table.get(new Get(ROW_BYTES));
-    assertTrue(Arrays.equals(res.getValue(FAMILY, COL_QUAL), VAL_BYTES));
-    table.close();
   }
 
   @Test
@@ -667,10 +661,8 @@ public class TestFromClientSide3 {
 
   @Test
   public void testPutWithPreBatchMutate() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
     testPreBatchMutate(tableName, () -> {
-      try {
-        Table t = TEST_UTIL.getConnection().getTable(tableName);
+      try (Table t = TEST_UTIL.getConnection().getTable(tableName)) {
         Put put = new Put(ROW);
         put.addColumn(FAMILY, QUALIFIER, VALUE);
         t.put(put);
@@ -682,11 +674,9 @@ public class TestFromClientSide3 {
 
   @Test
   public void testRowMutationsWithPreBatchMutate() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
     testPreBatchMutate(tableName, () -> {
-      try {
+      try (Table t = TEST_UTIL.getConnection().getTable(tableName)) {
         RowMutations rm = new RowMutations(ROW, 1);
-        Table t = TEST_UTIL.getConnection().getTable(tableName);
         Put put = new Put(ROW);
         put.addColumn(FAMILY, QUALIFIER, VALUE);
         rm.add(put);
@@ -702,6 +692,8 @@ public class TestFromClientSide3 {
     desc.addCoprocessor(WaitingForScanObserver.class.getName());
     desc.addFamily(new HColumnDescriptor(FAMILY));
     TEST_UTIL.getAdmin().createTable(desc);
+    // Don't use waitTableAvailable(), because the scanner will mess up the co-processor
+
     ExecutorService service = Executors.newFixedThreadPool(2);
     service.execute(rn);
     final List<Cell> cells = new ArrayList<>();
@@ -709,11 +701,12 @@ public class TestFromClientSide3 {
       try {
         // waiting for update.
         TimeUnit.SECONDS.sleep(3);
-        Table t = TEST_UTIL.getConnection().getTable(tableName);
-        Scan scan = new Scan();
-        try (ResultScanner scanner = t.getScanner(scan)) {
-          for (Result r : scanner) {
-            cells.addAll(Arrays.asList(r.rawCells()));
+        try (Table t = TEST_UTIL.getConnection().getTable(tableName)) {
+          Scan scan = new Scan();
+          try (ResultScanner scanner = t.getScanner(scan)) {
+            for (Result r : scanner) {
+              cells.addAll(Arrays.asList(r.rawCells()));
+            }
           }
         }
       } catch (IOException | InterruptedException ex) {
@@ -723,18 +716,19 @@ public class TestFromClientSide3 {
     service.shutdown();
     service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
     assertEquals("The write is blocking by RegionObserver#postBatchMutate"
-      + ", so the data is invisible to reader", 0, cells.size());
+            + ", so the data is invisible to reader", 0, cells.size());
     TEST_UTIL.deleteTable(tableName);
   }
 
   @Test
   public void testLockLeakWithDelta() throws Exception, Throwable {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
     HTableDescriptor desc = new HTableDescriptor(tableName);
     desc.addCoprocessor(WaitingForMultiMutationsObserver.class.getName());
     desc.setConfiguration("hbase.rowlock.wait.duration", String.valueOf(5000));
     desc.addFamily(new HColumnDescriptor(FAMILY));
     TEST_UTIL.getAdmin().createTable(desc);
+    TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+
     // new a connection for lower retry number.
     Configuration copy = new Configuration(TEST_UTIL.getConfiguration());
     copy.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
@@ -764,7 +758,8 @@ public class TestFromClientSide3 {
       });
       appendService.shutdown();
       appendService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
-      WaitingForMultiMutationsObserver observer = find(tableName, WaitingForMultiMutationsObserver.class);
+      WaitingForMultiMutationsObserver observer =
+              find(tableName, WaitingForMultiMutationsObserver.class);
       observer.latch.countDown();
       putService.shutdown();
       putService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
@@ -782,13 +777,14 @@ public class TestFromClientSide3 {
 
   @Test
   public void testMultiRowMutations() throws Exception, Throwable {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
     HTableDescriptor desc = new HTableDescriptor(tableName);
     desc.addCoprocessor(MultiRowMutationEndpoint.class.getName());
     desc.addCoprocessor(WaitingForMultiMutationsObserver.class.getName());
     desc.setConfiguration("hbase.rowlock.wait.duration", String.valueOf(5000));
     desc.addFamily(new HColumnDescriptor(FAMILY));
     TEST_UTIL.getAdmin().createTable(desc);
+    TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+
     // new a connection for lower retry number.
     Configuration copy = new Configuration(TEST_UTIL.getConfiguration());
     copy.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
@@ -821,9 +817,11 @@ public class TestFromClientSide3 {
           MultiRowMutationProtos.MutateRowsRequest request
             = MultiRowMutationProtos.MutateRowsRequest.newBuilder()
               .addMutationRequest(org.apache.hadoop.hbase.protobuf.ProtobufUtil.toMutation(
-                      org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType.PUT, put1))
+                      org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto
+                              .MutationType.PUT, put1))
               .addMutationRequest(org.apache.hadoop.hbase.protobuf.ProtobufUtil.toMutation(
-                      org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType.PUT, put2))
+                      org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto
+                              .MutationType.PUT, put2))
               .build();
           table.coprocessorService(MultiRowMutationProtos.MultiRowMutationService.class,
               ROW, ROW,
@@ -832,7 +830,8 @@ public class TestFromClientSide3 {
               CoprocessorRpcUtils.BlockingRpcCallback<MultiRowMutationProtos.MutateRowsResponse>
                 rpcCallback = new CoprocessorRpcUtils.BlockingRpcCallback<>();
               exe.mutateRows(controller, request, rpcCallback);
-              if (controller.failedOnException() && !(controller.getFailedOn() instanceof UnknownProtocolException)) {
+              if (controller.failedOnException() &&
+                      !(controller.getFailedOn() instanceof UnknownProtocolException)) {
                 exceptionDuringMutateRows.set(true);
               }
               return rpcCallback.get();
@@ -878,100 +877,96 @@ public class TestFromClientSide3 {
    * @throws IOException
    */
   @Test
-  public void testMVCCUsingMVCCPreAssign() throws IOException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
-    HTableDescriptor htd = new HTableDescriptor(tableName);
-    HColumnDescriptor fam = new HColumnDescriptor(FAMILY);
-    htd.addFamily(fam);
-    Admin admin = TEST_UTIL.getAdmin();
-    admin.createTable(htd);
-    Table table = admin.getConnection().getTable(TableName.valueOf(name.getMethodName()));
-    //put two row first to init the scanner
-    Put put = new Put(Bytes.toBytes("0"));
-    put.addColumn(FAMILY, Bytes.toBytes( ""), Bytes.toBytes("0"));
-    table.put(put);
-    put = new Put(Bytes.toBytes("00"));
-    put.addColumn(FAMILY, Bytes.toBytes( ""), Bytes.toBytes("0"));
-    table.put(put);
-    Scan scan = new Scan();
-    scan.setTimeRange(0, Long.MAX_VALUE);
-    scan.setCaching(1);
-    ResultScanner scanner = table.getScanner(scan);
-    int rowNum = scanner.next() != null ? 1 : 0;
-    //the started scanner shouldn't see the rows put below
-    for(int i = 1; i < 1000; i++) {
-      put = new Put(Bytes.toBytes(String.valueOf(i)));
-      put.setDurability(Durability.ASYNC_WAL);
-      put.addColumn(FAMILY, Bytes.toBytes( ""), Bytes.toBytes(i));
+  public void testMVCCUsingMVCCPreAssign() throws IOException, InterruptedException {
+    try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY })) {
+      TEST_UTIL.waitTableAvailable(tableName, WAITTABLE_MILLIS);
+      //put two row first to init the scanner
+      Put put = new Put(Bytes.toBytes("0"));
+      put.addColumn(FAMILY, Bytes.toBytes(""), Bytes.toBytes("0"));
       table.put(put);
+      put = new Put(Bytes.toBytes("00"));
+      put.addColumn(FAMILY, Bytes.toBytes(""), Bytes.toBytes("0"));
+      table.put(put);
+      Scan scan = new Scan();
+      scan.setTimeRange(0, Long.MAX_VALUE);
+      scan.setCaching(1);
+      ResultScanner scanner = table.getScanner(scan);
+      int rowNum = scanner.next() != null ? 1 : 0;
+      //the started scanner shouldn't see the rows put below
+      for (int i = 1; i < 1000; i++) {
+        put = new Put(Bytes.toBytes(String.valueOf(i)));
+        put.setDurability(Durability.ASYNC_WAL);
+        put.addColumn(FAMILY, Bytes.toBytes(""), Bytes.toBytes(i));
+        table.put(put);
+      }
+      for (Result result : scanner) {
+        rowNum++;
+      }
+      //scanner should only see two rows
+      assertEquals(2, rowNum);
+      scanner = table.getScanner(scan);
+      rowNum = 0;
+      for (Result result : scanner) {
+        rowNum++;
+      }
+      // the new scanner should see all rows
+      assertEquals(1001, rowNum);
     }
-    for(Result result : scanner) {
-      rowNum++;
-    }
-    //scanner should only see two rows
-    assertEquals(2, rowNum);
-    scanner = table.getScanner(scan);
-    rowNum = 0;
-    for(Result result : scanner) {
-      rowNum++;
-    }
-    // the new scanner should see all rows
-    assertEquals(1001, rowNum);
-
-
   }
 
   @Test
   public void testPutThenGetWithMultipleThreads() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
     final int THREAD_NUM = 20;
     final int ROUND_NUM = 10;
     for (int round = 0; round < ROUND_NUM; round++) {
       ArrayList<Thread> threads = new ArrayList<>(THREAD_NUM);
       final AtomicInteger successCnt = new AtomicInteger(0);
-      Table ht = TEST_UTIL.createTable(tableName, FAMILY);
-      for (int i = 0; i < THREAD_NUM; i++) {
-        final int index = i;
-        Thread t = new Thread(new Runnable() {
-
-          @Override
-          public void run() {
-            final byte[] row = Bytes.toBytes("row-" + index);
-            final byte[] value = Bytes.toBytes("v" + index);
-            try {
-              Put put = new Put(row);
-              put.addColumn(FAMILY, QUALIFIER, value);
-              ht.put(put);
-              Get get = new Get(row);
-              Result result = ht.get(get);
-              byte[] returnedValue = result.getValue(FAMILY, QUALIFIER);
-              if (Bytes.equals(value, returnedValue)) {
-                successCnt.getAndIncrement();
-              } else {
-                LOG.error("Should be equal but not, original value: " + Bytes.toString(value)
-                    + ", returned value: "
-                    + (returnedValue == null ? "null" : Bytes.toString(returnedValue)));
... 181 lines suppressed ...