gt:         switch (framework) {
context: package com.github.seqware.queryengine.impl.test;
  
  import com.esotericsoftware.kryo.Kryo;
  import com.esotericsoftware.kryo.io.Input;
  import com.esotericsoftware.kryo.io.Output;
  import com.github.seqware.queryengine.Benchmarking;
  import com.github.seqware.queryengine.Constants;
  import com.github.seqware.queryengine.dto.QueryEngine.FeaturePB;
  import com.github.seqware.queryengine.impl.protobufIO.FeatureIO;
  import com.github.seqware.queryengine.impl.tuplebinderIO.FeatureTB;
  import com.github.seqware.queryengine.impl.tuplebinderIO.SGIDTB;
  import com.github.seqware.queryengine.model.Feature;
  import com.github.seqware.queryengine.model.FeatureSet;
  import com.github.seqware.queryengine.model.impl.inMemory.InMemoryFeatureSet;
  import com.github.seqware.queryengine.model.impl.inMemory.InMemoryReference;
  import com.github.seqware.queryengine.util.FSGID;
  import com.sleepycat.bind.tuple.TupleInput;
  import com.sleepycat.bind.tuple.TupleOutput;
  import com.sleepycat.db.DatabaseEntry;
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.log4j.Logger;
  import junit.framework.Assert;
  import org.apache.commons.lang.SerializationUtils;
  import org.apache.hadoop.conf.Configuration;
  import org.apache.hadoop.hbase.HBaseConfiguration;
  import org.apache.hadoop.hbase.HColumnDescriptor;
  import org.apache.hadoop.hbase.HTableDescriptor;
  import org.apache.hadoop.hbase.KeyValue;
  import org.apache.hadoop.hbase.client.*;
  import org.apache.hadoop.hbase.util.Bytes;
  import org.junit.Test;
  import org.objenesis.strategy.SerializingInstantiatorStrategy;
  
  /**
   * Simple serialization/deserialization test using HBase.
   *
   * Serialization is done through Kryo and Protobuf. This class also demonstrated
   * the effect of batching on performance. (i.e. a large performance improvement)
   *
   * @author jbaran
   * @version $Id: $Id
   * @since 0.13.3
   */
  public class HBaseTest implements Benchmarking {
  
      private static final String TEST_TABLE = "seqwareTestTable";
      private static final String TEST_COLUMN = "fauxColumn";
  
      /**
       * Determines which framework should be used for serializing/de-serializing
       * objects.
       */
      private enum SerializationFramework {
          KRYO, PROTOBUF, APACHE //, TUPLEBINDER
      };
      /**
       * If Kryo is used, then this reference points to the Feature class
       * serializer/de-serializer:
       */
      private Kryo serializer;
      /**
       * If BerkeleyDB tuple binders are used, then these point to tuple binders
       */
      private FeatureTB featureTB;
      private SGIDTB sgidTB;
      /**
       * If Protobuf is used, then this reference points to the Feature class
       * serializer/de-serializer:
       */
      private FeatureIO fIO;
  
      /**
       * Represents a feature and its HBase row identifier.
       */
      private static class IdentifiedFeature {
  
          byte[] id;
          Feature feature;
  
          public IdentifiedFeature(byte[] id, Feature feature) {
              this.id = id;
              this.feature = feature;
          }
      }
  
      /**
       * Create a fresh HBase table (drop existing one) and serialize/deserialize
       * some Feature objects using Kryo.
       *
       * @throws java.io.IOException if any.
       * @throws java.lang.InterruptedException if any.
       */
      @Test
      public void testHBaseTableWithKryo() throws IOException, InterruptedException {
          // Alternative to protobuf: Kryo
          // Speed comparison can be found here: http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
          serializer = new Kryo();
  
          // Some magic to make serialization work with private default constructors:
          serializer.setInstantiatorStrategy(new SerializingInstantiatorStrategy());
  
          // Super slow: do not use the JavaSerializer:
          //serializer.register(UUID.class, new JavaSerializer());
          testHBaseTable(SerializationFramework.KRYO, false);
          if (!BENCHMARK){return;}
          testHBaseTable(SerializationFramework.KRYO, true);
      }
  
      /**
       * Create a fresh HBase table (drop existing one) and serialize/deserialize
       * a Feature objects using Protobuf.
       *
       * @throws java.io.IOException if any.
       * @throws java.lang.InterruptedException if any.
       */
      @Test
      public void testHBaseTableWithProtobuf() throws IOException, InterruptedException {
          fIO = new FeatureIO();
          testHBaseTable(SerializationFramework.PROTOBUF, false);
          if (!BENCHMARK){return;}
          testHBaseTable(SerializationFramework.PROTOBUF, true);
      }
  
      /**
       * Create a fresh HBase table (drop existing one) and serialize/deserialize
       * a Feature objects using Apache Serialization.
       *
       * @throws java.io.IOException if any.
       * @throws java.lang.InterruptedException if any.
       */
      @Test
      public void testHBaseTableWithApache() throws IOException, InterruptedException {
          testHBaseTable(SerializationFramework.APACHE, false);
          if (!BENCHMARK){return;}
          testHBaseTable(SerializationFramework.APACHE, true);
      }
  
      /**
       * Create a fresh HBase table (drop existing one) and serialize/deserialize
       * a Feature objects using BerkeleyDB tuple binders.
       *
       * @throws java.io.IOException if any.
       */
      @Test
      public void testHBaseTableWithTuple() throws IOException {
          this.featureTB = new FeatureTB();
          this.sgidTB = new SGIDTB();
          //testHBaseTable(SerializationFramework.TUPLEBINDER);
      }
  
      /**
       * Creates a fresh HBase table (drop existing one) and serialize/deserialize
       * some Feature objects.
       *
       * @throws IOException
       */
      private void testHBaseTable(SerializationFramework framework, boolean batchMode) throws IOException, InterruptedException {
          // Code from http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/package-summary.html
  
          // The HBaseConfiguration reads in hbase-site.xml and hbase-default.xml,
          // as long as these can be found in the CLASSPATH.
          Configuration config = HBaseConfiguration.create();
  
          String tableName = TEST_TABLE + framework;
  
          // Create a fresh table, i.e. delete an existing table if it exists:
          HTableDescriptor ht = new HTableDescriptor(tableName);
          ht.addFamily(new HColumnDescriptor(TEST_COLUMN));
          HBaseAdmin hba = new HBaseAdmin(config);
          if (hba.isTableAvailable(tableName)) {
              if (hba.isTableEnabled(tableName)){
                  hba.disableTable(tableName);
              }
              hba.deleteTable(tableName);
          }
          hba.createTable(ht);
  
          HTable table = new HTable(config, tableName);
          table.setAutoFlush(true);
  
          // Variables that track times for individual benchmark runs:
          long[] serializationTimes = new long[BENCHMARK_RUNS];
          long[] deserializationTimes = new long[BENCHMARK_RUNS];
          long[] totalPutTimes = new long[BENCHMARK_RUNS];
          long[] totalGetTimes = new long[BENCHMARK_RUNS];
          long totalRunTime = System.currentTimeMillis();
  
          // Create and store a feature/features:
          List<List<IdentifiedFeature>> testFeaturesList = new ArrayList<List<IdentifiedFeature>>();
  
          if (BENCHMARK) {
              for (int run = 0; run < BENCHMARK_RUNS; run++) {
                  totalPutTimes[run] = System.currentTimeMillis();
                  List<Row> putBatch = new ArrayList<Row>();
                  List<IdentifiedFeature> testFeatures = new ArrayList<IdentifiedFeature>();
                  testFeaturesList.add(testFeatures);                
                  serializationTimes[run] = System.currentTimeMillis();
                  for (int i = 0; i < BENCHMARK_FEATURES; i++) {
                      testFeatures.add(this.storeFauxFeature(framework, table, putBatch, batchMode));
                  }
                  serializationTimes[run] = System.currentTimeMillis() - serializationTimes[run];
                  if (batchMode) {
                      table.batch(putBatch);
                  }
                  table.flushCommits();
                  totalPutTimes[run] = System.currentTimeMillis() - totalPutTimes[run];
              }
          } else {
              List<IdentifiedFeature> testFeatures = new ArrayList<IdentifiedFeature>();
              testFeaturesList.add(testFeatures);    
              testFeatures.add(this.storeFauxFeature(framework, table, null, false));
          }
  
          // Retrieve a feature/features:
          if (BENCHMARK) {
              for (int run = 0; run < BENCHMARK_RUNS; run++) {
                  List<IdentifiedFeature> testFeatures = testFeaturesList.get(run);
                  totalGetTimes[run] = System.currentTimeMillis();
                  Object[] get = null;
                  if (batchMode) {
                      List<Row> batchList = this.getBatchList(testFeatures);
                      get = table.batch(batchList);
                  }
                  deserializationTimes[run] = System.currentTimeMillis();
                  for (int i = 0; i < BENCHMARK_FEATURES; i++) {
                      this.retrieveFauxFeature(framework, table, testFeatures, true, get, batchMode);
                  }
                  deserializationTimes[run] = System.currentTimeMillis() - deserializationTimes[run];
                  totalGetTimes[run] = System.currentTimeMillis() - totalGetTimes[run];
              }
          } else {
              List<IdentifiedFeature> testFeatures = testFeaturesList.get(0);
              this.retrieveFauxFeature(framework, table, testFeatures, false, null, false);
          }
  
          // Clean-up:
          table.close();
          
          totalRunTime = System.currentTimeMillis() - totalRunTime;
          
          hba.disableTable(tableName);
          hba.deleteTable(tableName);
  
          // If this is a benchmarking run, then output the benchmarking data now:
          if (BENCHMARK) {
              System.out.println("Benchmarking results (" + framework + "):");
              System.out.println(" objects serialized/deserialized per run:\t" + BENCHMARK_FEATURES);
  
              long serializationSum = 0, deserializationSum = 0, putSum = 0, getSum = 0; 
              for (int run = 0; run < BENCHMARK_RUNS; run++) {
                  System.out.println(" run " + (run + 1) + ":\t" + serializationTimes[run] + "\t" + deserializationTimes[run] + "\t(serialization/deserialization in ms)"
                          + "\t" + totalPutTimes[run] + "\t" + totalGetTimes[run] + "\t(Put/Get in ms)" );
                  serializationSum += serializationTimes[run];
                  deserializationSum += deserializationTimes[run];
                  putSum += totalPutTimes[run];
                  getSum += totalGetTimes[run];
              }
  
              System.out.println(" average:\t" + (1. * serializationSum / serializationTimes.length) + "\t" + (1. * deserializationSum / deserializationTimes.length) + "\t(serialization/deserialization in ms)"
                      + "\t" + (1. * putSum / totalPutTimes.length) + "\t" + (1. * getSum / totalGetTimes.length)  + "\t(Put/Get in ms)" );
              System.out.println(" total runtime: " + totalRunTime);
          }
      }
  
      /**
       * Serializes a features unique ID and content using Kryo.
       *
       * @param testFeature The feature that should be serialized.
       * @param sgidBytes Stream that is populated with the features unique ID.
       * @param featureBytes Stream that holds the serialized contents of the
       * feature.
       */
      private void serializeFeatureWithKryo(Feature testFeature, ByteArrayOutputStream sgidBytes, ByteArrayOutputStream featureBytes) {
          Output o = new Output(sgidBytes);
          serializer.writeObject(o, testFeature.getSGID());
          o.close();
  
          o = new Output(featureBytes);
          serializer.writeObject(o, testFeature);
          o.close();
      }
  
      /**
       * Serializes a features unique ID and content using Apache (really Java)
       * serialization.
       *
       * @param testFeature The feature that should be serialized.
       * @param sgidBytes Stream that is populated with the features unique ID.
       * @param featureBytes Stream that holds the serialized contents of the
       * feature.
       */
      private void serializeFeatureWithApache(Feature testFeature, ByteArrayOutputStream sgidBytes, ByteArrayOutputStream featureBytes) {
          Output o = new Output(sgidBytes);
          o.write(SerializationUtils.serialize(testFeature.getSGID()));
          o.close();
  
          o = new Output(featureBytes);
          o.write(SerializationUtils.serialize(testFeature));
          o.close();
      }
  
      /**
       * Serializes a features unique ID and content using TupleBinders.
       *
       * @param testFeature The feature that should be serialized.
       * @param sgidBytes Stream that is populated with the features unique ID.
       * @param featureBytes Stream that holds the serialized contents of the
       * feature.
       */
      private void serializeFeatureWithBinders(Feature testFeature, ByteArrayOutputStream sgidBytes, ByteArrayOutputStream featureBytes) throws IOException {
          Output o = new Output(sgidBytes);
          TupleOutput value = new TupleOutput();
          this.sgidTB.objectToEntry(testFeature.getSGID(), value);
          byte[] data = value.toByteArray();
          o.write(data);
          value.close();
          o.close();
  
          o = new Output(featureBytes);
          value = new TupleOutput();
          this.featureTB.objectToEntry(testFeature, value);
          data = value.toByteArray();
          o.write(data);
          value.close();
          o.close();
      }
  
      /**
       * Serializes a features unique ID and content using Protobuf.
       *
       * @param testFeature The feature that should be serialized.
       * @param sgidBytes Stream that is populated with the features unique ID.
       * @param featureBytes Stream that holds the serialized contents of the
       * feature.
       */
      private void serializeFeatureWithProtobuf(Feature testFeature, ByteArrayOutputStream sgidBytes, ByteArrayOutputStream featureBytes) throws IOException {
          FeaturePB fpb = fIO.m2pb(testFeature);
  
          Output o = new Output(sgidBytes);
          fpb.getAtom().getSgid().writeTo(o);
          o.close();
  
          o = new Output(featureBytes);
          fpb.writeTo(o);
          o.close();
      }
  
      /**
       * Generic method for deserializing a feature.
       *
       * @param framework Determines the framework that should be used for the
       * deserialization.
       * @param serializedFeature Input from which the serialized feature will be
       * read.
       * @return A deserialized feature.
       */
      private Feature deserializeFeature(SerializationFramework framework, Input serializedFeature) throws IOException {
  