@Test
public void testIndexScan() throws IOException {

  nextTsAndCreateTransaction();
  transaction.put(MAIN_TABLE, new ThemisPut(ANOTHER_ROW).add(FAMILY, QUALIFIER, ANOTHER_VALUE));
  transaction.put(MAIN_TABLE, new ThemisPut(ROW).add(FAMILY, QUALIFIER, VALUE));
  transaction.put(MAIN_TABLE, new ThemisPut(ROW).add(FAMILY, ANOTHER_QUALIFIER, VALUE));
  transaction.put(MAIN_TABLE, new ThemisPut(ROW).add(ANOTHER_FAMILY, QUALIFIER, VALUE));
  mockTsAndCommitTransaction();
  
  nextTsAndCreateTransaction();
  IndexScan indexScan = new IndexScan(INDEX_COLUMN);
  ResultScanner scanner = transaction.getScanner(MAIN_TABLE, indexScan);
  Assert.assertTrue(scanner instanceof IndexScanner);
  checkReadResult(ANOTHER_VALUE, COLUMN, scanner.next());
  checkReadResults(new byte[][] { VALUE, VALUE, VALUE }, new ColumnCoordinate[] { COLUMN,
      COLUMN_WITH_ANOTHER_QUALIFIER, COLUMN_WITH_ANOTHER_FAMILY }, scanner.next());
  checkAndCloseScanner(scanner);
  
  // start/stop row for index scan
  indexScan = new IndexScan(INDEX_COLUMN, ANOTHER_VALUE, ANOTHER_VALUE);
  scanner = transaction.getScanner(MAIN_TABLE, indexScan);
  Assert.assertTrue(scanner instanceof IndexScanner);
  checkReadResult(ANOTHER_VALUE, COLUMN, scanner.next());
  checkAndCloseScanner(scanner);
  
  // Delete/Update
  transaction.delete(MAIN_TABLE, new ThemisDelete(ROW).deleteColumn(FAMILY, ANOTHER_QUALIFIER));
  transaction.put(MAIN_TABLE, new ThemisPut(ROW).add(ANOTHER_FAMILY, QUALIFIER, ANOTHER_VALUE));
  mockTsAndCommitTransaction();
  // won't get new result before update timestamp
  indexScan = new IndexScan(INDEX_COLUMN);
  scanner = transaction.getScanner(MAIN_TABLE, indexScan);
  Assert.assertTrue(scanner instanceof IndexScanner);
  checkReadResult(ANOTHER_VALUE, COLUMN, scanner.next());
  checkReadResults(new byte[][] { VALUE, VALUE, VALUE }, new ColumnCoordinate[] { COLUMN,
      COLUMN_WITH_ANOTHER_QUALIFIER, COLUMN_WITH_ANOTHER_FAMILY }, scanner.next());
  checkAndCloseScanner(scanner);
  nextTsAndCreateTransaction();
  indexScan = new IndexScan(INDEX_COLUMN);
  scanner = transaction.getScanner(MAIN_TABLE, indexScan);
  Assert.assertTrue(scanner instanceof IndexScanner);
  checkReadResult(ANOTHER_VALUE, COLUMN, scanner.next());
  checkReadResults(new byte[][] { VALUE, ANOTHER_VALUE }, new ColumnCoordinate[] { COLUMN,
      COLUMN_WITH_ANOTHER_FAMILY }, scanner.next());
  checkAndCloseScanner(scanner);
  
  // update value to make tow rows have the same index column value
  transaction.put(MAIN_TABLE, new ThemisPut(ANOTHER_ROW).add(FAMILY, QUALIFIER, VALUE));
  mockTsAndCommitTransaction();
  
  nextTsAndCreateTransaction();
  indexScan = new IndexScan(INDEX_COLUMN);
  scanner = transaction.getScanner(MAIN_TABLE, indexScan);
  Assert.assertTrue(scanner instanceof IndexScanner);
  checkReadResult(VALUE, COLUMN, scanner.next());
  checkReadResults(new byte[][] { VALUE, ANOTHER_VALUE }, new ColumnCoordinate[] { COLUMN,
      COLUMN_WITH_ANOTHER_FAMILY }, scanner.next());
  checkAndCloseScanner(scanner);
}