diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/oldtype/NodeWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/oldtype/NodeWritable.java
index 9fc1829..7a49512 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/oldtype/NodeWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/oldtype/NodeWritable.java
@@ -23,6 +23,7 @@
 import org.apache.hadoop.io.WritableComparable;
 
 import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
 
 public class NodeWritable implements WritableComparable<NodeWritable>, Serializable {
     /**
@@ -45,7 +46,7 @@
     private PositionListWritable forwardReverseList;
     private PositionListWritable reverseForwardList;
     private PositionListWritable reverseReverseList;
-    private KmerBytesWritable kmer;
+    private VKmerBytesWritable kmer;
 
     public NodeWritable() {
         this(21);
@@ -57,7 +58,7 @@
         forwardReverseList = new PositionListWritable();
         reverseForwardList = new PositionListWritable();
         reverseReverseList = new PositionListWritable();
-        kmer = new KmerBytesWritable(kmerSize);
+        kmer = new VKmerBytesWritable();
     }
 
     public NodeWritable(PositionWritable nodeID, PositionListWritable FFList, PositionListWritable FRList,
@@ -68,7 +69,7 @@
         forwardReverseList.set(FRList);
         reverseForwardList.set(RFList);
         reverseReverseList.set(RRList);
-        kmer.set(kmer);
+        kmer.setAsCopy(kmer);
     }
 
     public void set(PositionWritable nodeID, PositionListWritable FFList, PositionListWritable FRList,
@@ -78,7 +79,7 @@
         this.forwardReverseList.set(FRList);
         this.reverseForwardList.set(RFList);
         this.reverseReverseList.set(RRList);
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
     }
 
     public void setNodeID(PositionWritable ref) {
@@ -90,7 +91,7 @@
     }
 
     public void setKmer(KmerBytesWritable right) {
-        this.kmer.set(right);
+        this.kmer.setAsCopy(right);
     }
 
     public void reset(int kmerSize) {
@@ -163,7 +164,7 @@
         this.forwardReverseList.set(node.forwardReverseList);
         this.reverseForwardList.set(node.reverseForwardList);
         this.reverseReverseList.set(node.reverseReverseList);
-        this.kmer.set(node.kmer);
+        this.kmer.setAsCopy(node.kmer);
     }
 
     @Override
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritable.java
index 284c2e7..e042840 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritable.java
@@ -26,583 +26,349 @@
 
 import edu.uci.ics.genomix.data.KmerUtil;
 import edu.uci.ics.genomix.data.Marshal;
-import edu.uci.ics.genomix.oldtype.NodeWritable.DirectionFlag;
 
 /**
- * Variable kmer length byteswritable It was used to generate the graph in which
- * phase the kmer length doesn't change. Thus the kmerByteSize of bytes doesn't
- * change either.
+ * Fixed, static-length Kmer used as the key and edge values of each
+ * NodeWritable. Kmer length should be set once during configuration and should
+ * never change.
  */
-public class KmerBytesWritable extends BinaryComparable implements
-		Serializable, WritableComparable<BinaryComparable> {
+public class KmerBytesWritable extends BinaryComparable implements Serializable, WritableComparable<BinaryComparable> {
 
-	private static final long serialVersionUID = 1L;
-	protected static final byte[] EMPTY_BYTES = {};
+    private static final long serialVersionUID = 1L;
+    protected static final byte[] EMPTY_BYTES = {};
 
-	protected int lettersInKmer;
-	protected int bytesUsed;
-	protected byte[] bytes;
-	protected int offset;
+    protected static int lettersInKmer;
+    protected static int bytesUsed;
+    protected byte[] bytes;
+    protected int offset;
 
-	/**
-	 * Initialize as empty kmer
-	 */
-	public KmerBytesWritable() {
-		this(0, EMPTY_BYTES, 0);
-	}
+    /**
+     * set the *GLOBAL* kmer length to the given k value.
+     * NOTE: this will invalidate ALL previously created kmers. This function
+     * should be called before any kmers are created
+     */
+    public static void setGlobalKmerLength(int k) {
+        bytesUsed = KmerUtil.getByteNumFromK(k);
+        lettersInKmer = k;
+    }
 
-	/**
-	 * Copy contents of kmer string
-	 */
-	public KmerBytesWritable(String kmer) {
-		setAsCopy(kmer);
-	}
+    /**
+     * Initialize as empty kmer
+     */
+    public KmerBytesWritable() {
+        bytes = new byte[bytesUsed];
+        offset = 0;
+    }
 
-	/**
-	 * Set as reference to given data
-	 */
-	public KmerBytesWritable(int k, byte[] storage, int offset) {
-		setAsReference(k, storage, offset);
-	}
+    /**
+     * Copy contents of kmer string
+     */
+    public KmerBytesWritable(String kmer) {
+        this();
+        setByRead(kmer.getBytes(), 0);
+    }
 
-	/**
-	 * Reserve space for k letters
-	 */
-	public KmerBytesWritable(int k) {
-		if (k > 0) {
-			this.bytes = new byte[KmerUtil.getByteNumFromK(k)];
-		} else {
-			this.bytes = EMPTY_BYTES;
-		}
-		this.offset = 0;
-		setKmerLength(k);
-	}
+    /**
+     * Set as reference to existing data
+     */
+    public KmerBytesWritable(byte[] storage, int offset) {
+        setAsReference(storage, offset);
+    }
 
-	/**
-	 * copy kmer in other
-	 * 
-	 * @param other
-	 */
-	public KmerBytesWritable(KmerBytesWritable other) {
-		this(other.lettersInKmer);
-		setAsCopy(other);
-	}
+    /**
+     * copy kmer in other
+     * 
+     * @param other
+     */
+    public KmerBytesWritable(KmerBytesWritable other) {
+        this();
+        setAsCopy(other);
+    }
 
-	/**
-	 * Deep copy of the given kmer
-	 * 
-	 * @param other
-	 */
-	public void setAsCopy(KmerBytesWritable other) {
-		reset(other.lettersInKmer);
-		if (lettersInKmer > 0) {
-			System.arraycopy(other.bytes, other.offset, bytes, this.offset,
-					bytesUsed);
-		}
-	}
+    /**
+     * Deep copy of the given kmer
+     * 
+     * @param other
+     */
+    public void setAsCopy(KmerBytesWritable other) {
+        if (lettersInKmer > 0) {
+            System.arraycopy(other.bytes, other.offset, bytes, this.offset, bytesUsed);
+        }
+    }
 
-	/**
-	 * set from String kmer
-	 */
-	public void setAsCopy(String kmer) {
-		setKmerLength(kmer.length());
-		bytes = kmer.getBytes();
-		offset = 0;
-	}
+    /**
+     * Deep copy of the given bytes data
+     * 
+     * @param newData
+     * @param offset
+     */
+    public void setAsCopy(byte[] newData, int offset) {
+        if (newData.length - offset < bytesUsed) {
+            throw new IllegalArgumentException("Requested " + bytesUsed + " bytes (k=" + lettersInKmer
+                    + ") but buffer has only " + (newData.length - offset) + " bytes");
+        }
+        System.arraycopy(newData, offset, bytes, this.offset, bytesUsed);
+    }
 
-	/**
-	 * Deep copy of the given bytes data
-	 * 
-	 * @param newData
-	 * @param offset
-	 */
-	public void setAsCopy(int k, byte[] newData, int offset) {
-		reset(k);
-		System.arraycopy(newData, offset, bytes, this.offset, k);
-	}
+    /**
+     * Point this datablock to the given bytes array It works like the pointer
+     * to new datablock.
+     * 
+     * @param newData
+     * @param offset
+     */
+    public void setAsReference(byte[] newData, int offset) {
+        if (newData.length - offset < bytesUsed) {
+            throw new IllegalArgumentException("Requested " + bytesUsed + " bytes (k=" + lettersInKmer
+                    + ") but buffer has only " + (newData.length - offset) + " bytes");
+        }
+        bytes = newData;
+        this.offset = offset;
+    }
 
-	/**
-	 * Reset array by kmerlength
-	 * 
-	 * @param k
-	 */
-	public void reset(int k) {
-		setKmerLength(k);
-		setSize(bytesUsed);
-		clearLeadBit();
-	}
+    /**
+     * Get one genecode (A|G|C|T) from the given kmer index e.g. Get the 4th
+     * gene of the kmer ACGTA will return T
+     * 
+     * @param pos
+     * @return
+     */
+    public byte getGeneCodeAtPosition(int pos) {
+        if (pos >= lettersInKmer || pos < 0) {
+            throw new ArrayIndexOutOfBoundsException("Gene position (" + pos + ") out of bounds for k=" + lettersInKmer);
+        }
+        return geneCodeAtPosition(pos);
+    }
 
-	/**
-	 * Point this datablock to the given bytes array It works like the pointer
-	 * to new datablock.
-	 * 
-	 * @param newData
-	 * @param offset
-	 */
-	public void setAsReference(int k, byte[] newData, int offset) {
-		this.bytes = newData;
-		this.offset = offset;
-		// my java skills are lacking. In inherited classes with a header, this
-		// will use the header version...
-		// setKmerLength(k);
-		bytesUsed = KmerUtil.getByteNumFromK(k);
-		lettersInKmer = k;
-		if (newData.length - offset < bytesUsed) {
-			throw new IllegalArgumentException("Requested " + bytesUsed
-					+ " bytes (k=" + k + ") but buffer has only "
-					+ (newData.length - offset) + " bytes");
-		}
-	}
+    /**
+     * unchecked version of getGeneCodeAtPosition. Used when kmerlength is
+     * inaccurate (mid-merge)
+     */
+    private byte geneCodeAtPosition(int pos) {
+        int posByte = pos / 4;
+        int shift = (pos % 4) << 1;
+        return (byte) ((bytes[offset + bytesUsed - 1 - posByte] >> shift) & 0x3);
+    }
 
-	/**
-	 * Ensures that there is space for at least `size` bytes of kmer (not
-	 * including any header)
-	 * 
-	 */
-	protected void setSize(int size) {
-		if (size > getCapacity()) {
-			setCapacity((size * 3 / 2));
-		}
-		this.bytesUsed = size;
-	}
+    public static int getKmerLength() {
+        return lettersInKmer;
+    }
+    
+    public static int getBytesPerKmer() {
+        return bytesUsed;
+    }
 
-	/**
-	 * return the number of bytes in use for the kmer (not including any header)
-	 */
-	protected int getCapacity() {
-		return bytes.length;
-	}
+    @Override
+    public byte[] getBytes() {
+        return bytes;
+    }
 
-	/**
-	 * shrinks/expands the storage area to allow new_cap bytes for the kmer (no
-	 * header included)
-	 */
-	protected void setCapacity(int new_cap) {
-		if (new_cap != getCapacity()) {
-			byte[] new_data = new byte[new_cap];
-			if (new_cap < bytesUsed) {
-				bytesUsed = new_cap;
-			}
-			if (bytesUsed != 0) {
-				System.arraycopy(bytes, offset, new_data, 0, bytesUsed);
-			}
-			bytes = new_data;
-			offset = 0;
-		}
-	}
+    public int getOffset() {
+        return offset;
+    }
 
-	/**
-	 * Get one genecode (A|G|C|T) from the given kmer index e.g. Get the 4th
-	 * gene of the kmer ACGTA will return T
-	 * 
-	 * @param pos
-	 * @return
-	 */
-	public byte getGeneCodeAtPosition(int pos) {
-		if (pos >= lettersInKmer) {
-			throw new IllegalArgumentException("gene position out of bound");
-		}
-		return geneCodeAtPosition(pos);
-	}
+    @Override
+    public int getLength() {
+        return bytesUsed;
+    }
 
-	// unchecked version of above. Used when kmerlength is inaccurate
-	// (mid-merge)
-	private byte geneCodeAtPosition(int pos) {
-		int posByte = pos / 4;
-		int shift = (pos % 4) << 1;
-		return (byte) ((bytes[offset + bytesUsed - 1 - posByte] >> shift) & 0x3);
-	}
+    /**
+     * Read Kmer from read text into bytes array e.g. AATAG will compress as
+     * [0x000G, 0xATAA]
+     * 
+     * @param stringBytes
+     * @param start
+     */
+    public void setByRead(byte[] stringBytes, int start) {
+        byte l = 0;
+        int bytecount = 0;
+        int bcount = this.bytesUsed - 1;
+        for (int i = start; i < start + lettersInKmer && i < stringBytes.length; i++) {
+            byte code = GeneCode.getCodeFromSymbol(stringBytes[i]);
+            l |= (byte) (code << bytecount);
+            bytecount += 2;
+            if (bytecount == 8) {
+                bytes[offset + bcount--] = l;
+                l = 0;
+                bytecount = 0;
+            }
+        }
+        if (bcount >= 0) {
+            bytes[offset] = l;
+        }
+    }
 
-	public void setKmerLength(int k) {
-		this.bytesUsed = KmerUtil.getByteNumFromK(k);
-		this.lettersInKmer = k;
-	}
+    /**
+     * Compress Reversed read into bytes array e.g. AATAG will paired to CTATT,
+     * and then compress as [0x000T,0xTATC]
+     * 
+     * @param input
+     *            array
+     * @param start
+     *            position
+     */
+    public void setByReadReverse(byte[] array, int start) {
+        byte l = 0;
+        int bytecount = 0;
+        int bcount = bytesUsed - 1;
+        // for (int i = start + kmerlength - 1; i >= 0 && i < array.length; i--)
+        // {
+        for (int i = start + lettersInKmer - 1; i >= start && i < array.length; i--) {
+            byte code = GeneCode.getPairedCodeFromSymbol(array[i]);
+            l |= (byte) (code << bytecount);
+            bytecount += 2;
+            if (bytecount == 8) {
+                bytes[offset + bcount--] = l;
+                l = 0;
+                bytecount = 0;
+            }
+        }
+        if (bcount >= 0) {
+            bytes[offset] = l;
+        }
+    }
 
-	public int getKmerLength() {
-		return lettersInKmer;
-	}
+    /**
+     * Shift Kmer to accept new char input
+     * 
+     * @param c
+     *            Input new gene character
+     * @return the shift out gene, in gene code format
+     */
+    public byte shiftKmerWithNextChar(byte c) {
+        return shiftKmerWithNextCode(GeneCode.getCodeFromSymbol(c));
+    }
 
-	@Override
-	public byte[] getBytes() {
-		return bytes;
-	}
+    /**
+     * Shift Kmer to accept new gene code
+     * 
+     * @param c
+     *            Input new gene code
+     * @return the shift out gene, in gene code format
+     */
+    public byte shiftKmerWithNextCode(byte c) {
+        byte output = (byte) (bytes[offset + bytesUsed - 1] & 0x03);
+        for (int i = bytesUsed - 1; i > 0; i--) {
+            byte in = (byte) (bytes[offset + i - 1] & 0x03);
+            bytes[offset + i] = (byte) (((bytes[offset + i] >>> 2) & 0x3f) | (in << 6));
+        }
+        int pos = ((lettersInKmer - 1) % 4) << 1;
+        byte code = (byte) (c << pos);
+        bytes[offset] = (byte) (((bytes[offset] >>> 2) & 0x3f) | code);
+        clearLeadBit();
+        return output;
+    }
 
-	public int getOffset() {
-		return offset;
-	}
+    /**
+     * Shift Kmer to accept new input char
+     * 
+     * @param c
+     *            Input new gene character
+     * @return the shiftout gene, in gene code format
+     */
+    public byte shiftKmerWithPreChar(byte c) {
+        return shiftKmerWithPreCode(GeneCode.getCodeFromSymbol(c));
+    }
 
-	@Override
-	public int getLength() {
-		return bytesUsed;
-	}
+    /**
+     * Shift Kmer to accept new gene code
+     * 
+     * @param c
+     *            Input new gene code
+     * @return the shiftout gene, in gene code format
+     */
+    public byte shiftKmerWithPreCode(byte c) {
+        int pos = ((lettersInKmer - 1) % 4) << 1;
+        byte output = (byte) ((bytes[offset] >> pos) & 0x03);
+        for (int i = 0; i < bytesUsed - 1; i++) {
+            byte in = (byte) ((bytes[offset + i + 1] >> 6) & 0x03);
+            bytes[offset + i] = (byte) ((bytes[offset + i] << 2) | in);
+        }
+        bytes[offset + bytesUsed - 1] = (byte) ((bytes[offset + bytesUsed - 1] << 2) | c);
+        clearLeadBit();
+        return output;
+    }
 
-	/**
-	 * Read Kmer from read text into bytes array e.g. AATAG will compress as
-	 * [0x000G, 0xATAA]
-	 * 
-	 * @param k
-	 * @param stringBytes
-	 *            : byte array from a _string_. Meaning there's no header
-	 * @param start
-	 */
-	public void setByRead(byte[] stringBytes, int start) {
-		byte l = 0;
-		int bytecount = 0;
-		int bcount = this.bytesUsed - 1;
-		for (int i = start; i < start + lettersInKmer && i < stringBytes.length; i++) {
-			byte code = GeneCode.getCodeFromSymbol(stringBytes[i]);
-			l |= (byte) (code << bytecount);
-			bytecount += 2;
-			if (bytecount == 8) {
-				bytes[offset + bcount--] = l;
-				l = 0;
-				bytecount = 0;
-			}
-		}
-		if (bcount >= 0) {
-			bytes[offset] = l;
-		}
-	}
+    public static void appendOneByteAtPosition(int k, byte onebyte, byte[] buffer, int start, int length) {
+        int position = start + length - 1 - k / 4;
+        if (position < start) {
+            throw new IllegalArgumentException("Buffer for kmer storage is invalid");
+        }
+        int shift = ((k) % 4) << 1;
+        int mask = shift == 0 ? 0 : ((1 << shift) - 1);
 
-	public void setByRead(int k, byte[] array, int start) {
-		reset(k);
-		setByRead(array, start);
-	}
+        buffer[position] = (byte) ((buffer[position] & mask) | ((0xff & onebyte) << shift));
+        if (position > start && shift != 0) {
+            buffer[position - 1] = (byte) ((buffer[position - 1] & (0xff - mask)) | ((byte) ((0xff & onebyte) >>> (8 - shift))));
+        }
+    }
 
-	/**
-	 * Compress Reversed read into bytes array e.g. AATAG will paired to CTATT,
-	 * and then compress as [0x000T,0xTATC]
-	 * 
-	 * @param input
-	 *            array
-	 * @param start
-	 *            position
-	 */
-	public void setByReadReverse(byte[] array, int start) {
-		byte l = 0;
-		int bytecount = 0;
-		int bcount = bytesUsed - 1;
-		// for (int i = start + kmerlength - 1; i >= 0 && i < array.length; i--)
-		// {
-		for (int i = start + lettersInKmer - 1; i >= start && i < array.length; i--) {
-			byte code = GeneCode.getPairedCodeFromSymbol(array[i]);
-			l |= (byte) (code << bytecount);
-			bytecount += 2;
-			if (bytecount == 8) {
-				bytes[offset + bcount--] = l;
-				l = 0;
-				bytecount = 0;
-			}
-		}
-		if (bcount >= 0) {
-			bytes[offset] = l;
-		}
-	}
+    public static byte getOneByteFromKmerAtPosition(int k, byte[] buffer, int start, int length) {
+        int position = start + length - 1 - k / 4;
+        if (position < start) {
+            throw new IllegalArgumentException("Buffer of kmer storage is invalid");
+        }
+        int shift = (k % 4) << 1;
+        byte data = (byte) (((0xff) & buffer[position]) >>> shift);
+        if (shift != 0 && position > start) {
+            data |= 0xff & (buffer[position - 1] << (8 - shift));
+        }
+        return data;
+    }
 
-	public void setByReadReverse(int k, byte[] array, int start) {
-		reset(k);
-		setByReadReverse(array, start);
-	}
+    protected void clearLeadBit() {
+        if (lettersInKmer % 4 != 0) {
+            bytes[offset] &= (1 << ((lettersInKmer % 4) << 1)) - 1;
+        }
+    }
 
-	/**
-	 * Shift Kmer to accept new char input
-	 * 
-	 * @param c
-	 *            Input new gene character
-	 * @return the shift out gene, in gene code format
-	 */
-	public byte shiftKmerWithNextChar(byte c) {
-		return shiftKmerWithNextCode(GeneCode.getCodeFromSymbol(c));
-	}
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        in.readFully(bytes, offset, bytesUsed);
+    }
 
-	/**
-	 * Shift Kmer to accept new gene code
-	 * 
-	 * @param c
-	 *            Input new gene code
-	 * @return the shift out gene, in gene code format
-	 */
-	public byte shiftKmerWithNextCode(byte c) {
-		byte output = (byte) (bytes[offset + bytesUsed - 1] & 0x03);
-		for (int i = bytesUsed - 1; i > 0; i--) {
-			byte in = (byte) (bytes[offset + i - 1] & 0x03);
-			bytes[offset + i] = (byte) (((bytes[offset + i] >>> 2) & 0x3f) | (in << 6));
-		}
-		int pos = ((lettersInKmer - 1) % 4) << 1;
-		byte code = (byte) (c << pos);
-		bytes[offset] = (byte) (((bytes[offset] >>> 2) & 0x3f) | code);
-		clearLeadBit();
-		return output;
-	}
+    @Override
+    public void write(DataOutput out) throws IOException {
+        out.write(bytes, offset, bytesUsed);
+    }
 
-	/**
-	 * Shift Kmer to accept new input char
-	 * 
-	 * @param c
-	 *            Input new gene character
-	 * @return the shiftout gene, in gene code format
-	 */
-	public byte shiftKmerWithPreChar(byte c) {
-		return shiftKmerWithPreCode(GeneCode.getCodeFromSymbol(c));
-	}
+    @Override
+    public int hashCode() {
+        return Marshal.hashBytes(bytes, offset, bytesUsed);
+    }
 
-	/**
-	 * Shift Kmer to accept new gene code
-	 * 
-	 * @param c
-	 *            Input new gene code
-	 * @return the shiftout gene, in gene code format
-	 */
-	public byte shiftKmerWithPreCode(byte c) {
-		int pos = ((lettersInKmer - 1) % 4) << 1;
-		byte output = (byte) ((bytes[offset] >> pos) & 0x03);
-		for (int i = 0; i < bytesUsed - 1; i++) {
-			byte in = (byte) ((bytes[offset + i + 1] >> 6) & 0x03);
-			bytes[offset + i] = (byte) ((bytes[offset + i] << 2) | in);
-		}
-		bytes[offset + bytesUsed - 1] = (byte) ((bytes[offset + bytesUsed - 1] << 2) | c);
-		clearLeadBit();
-		return output;
-	}
+    @Override
+    public boolean equals(Object right_obj) {
+        if (right_obj instanceof KmerBytesWritable) {
+            // since these may be backed by storage of different sizes, we have to manually check each byte
+            KmerBytesWritable right = (KmerBytesWritable) right_obj;
+            for (int i=0; i < bytesUsed; i++) {
+                if (bytes[offset + i] != right.bytes[right.offset + i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Merge Kmer with the next connected Kmer e.g. AAGCTAA merge with AACAACC,
-	 * if the initial kmerSize = 3 then it will return AAGCTAACAACC
-	 * 
-	 * @param initialKmerSize
-	 *            : the initial kmerSize
-	 * @param kmer
-	 *            : the next kmer
-	 */
-	public void mergeWithFFKmer(int initialKmerSize, KmerBytesWritable kmer) {
-		int preKmerLength = lettersInKmer;
-		int preSize = bytesUsed;
-		lettersInKmer += kmer.lettersInKmer - initialKmerSize + 1;
-		setSize(KmerUtil.getByteNumFromK(lettersInKmer));
-		for (int i = 1; i <= preSize; i++) {
-			bytes[offset + bytesUsed - i] = bytes[offset + preSize - i];
-		}
-		for (int k = initialKmerSize - 1; k < kmer.getKmerLength(); k += 4) {
-			byte onebyte = getOneByteFromKmerAtPosition(k, kmer.getBytes(),
-					kmer.getOffset(), kmer.getLength());
-			appendOneByteAtPosition(preKmerLength + k - initialKmerSize + 1,
-					onebyte, bytes, offset, bytesUsed);
-		}
-		clearLeadBit();
-	}
+    @Override
+    public String toString() {
+        return KmerUtil.recoverKmerFrom(lettersInKmer, bytes, offset, bytesUsed);
+    }
 
-	/**
-	 * Merge Kmer with the next connected Kmer, when that Kmer needs to be
-	 * reverse-complemented e.g. AAGCTAA merge with GGTTGTT, if the initial
-	 * kmerSize = 3 then it will return AAGCTAACAACC A merge B => A B~
-	 * 
-	 * @param initialKmerSize
-	 *            : the initial kmerSize
-	 * @param kmer
-	 *            : the next kmer
-	 */
-	public void mergeWithFRKmer(int initialKmerSize, KmerBytesWritable kmer) {
-		int preSize = bytesUsed;
-		int preKmerLength = lettersInKmer;
-		lettersInKmer += kmer.lettersInKmer - initialKmerSize + 1;
-		setSize(KmerUtil.getByteNumFromK(lettersInKmer));
-		// copy prefix into right-side of buffer
-		for (int i = 1; i <= preSize; i++) {
-			bytes[offset + bytesUsed - i] = bytes[offset + preSize - i];
-		}
+    public static class Comparator extends WritableComparator {
+        public Comparator() {
+            super(KmerBytesWritable.class);
+        }
 
-		int bytecount = (preKmerLength % 4) * 2;
-		int bcount = bytesUsed - preSize - bytecount / 8; // may overlap
-															// previous kmer
-		byte l = bcount == bytesUsed - preSize ? bytes[offset + bcount] : 0x00;
-		bytecount %= 8;
-		for (int i = kmer.lettersInKmer - initialKmerSize; i >= 0; i--) {
-			byte code = GeneCode.getPairedGeneCode(kmer
-					.getGeneCodeAtPosition(i));
-			l |= (byte) (code << bytecount);
-			bytecount += 2;
-			if (bytecount == 8) {
-				bytes[offset + bcount--] = l;
-				l = 0;
-				bytecount = 0;
-			}
-		}
-		if (bcount >= 0) {
-			bytes[offset] = l;
-		}
-	}
+        public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+            return compareBytes(b1, s1, l1, b2, s2, l2);
+        }
+    }
 
-	/**
-	 * Merge Kmer with the previous connected Kmer, when that kmer needs to be
-	 * reverse-complemented e.g. AACAACC merge with TTCTGCC, if the initial
-	 * kmerSize = 3 then it will return GGCAGAACAACC
-	 * 
-	 * @param initialKmerSize
-	 *            : the initial kmerSize
-	 * @param preKmer
-	 *            : the previous kmer
-	 */
-	public void mergeWithRFKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-		KmerBytesWritable reversed = new KmerBytesWritable(preKmer.lettersInKmer);
-		reversed.setByReadReverse(preKmer.toString().getBytes(), 0);
-		mergeWithRRKmer(initialKmerSize, reversed);
-	}
-
-	/**
-	 * Merge Kmer with the previous connected Kmer e.g. AACAACC merge with
-	 * AAGCTAA, if the initial kmerSize = 3 then it will return AAGCTAACAACC
-	 * 
-	 * @param initialKmerSize
-	 *            : the initial kmerSize
-	 * @param preKmer
-	 *            : the previous kmer
-	 */
-	public void mergeWithRRKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-		int preKmerLength = lettersInKmer;
-		int preSize = bytesUsed;
-		lettersInKmer += preKmer.lettersInKmer - initialKmerSize + 1;
-		setSize(KmerUtil.getByteNumFromK(lettersInKmer));
-		byte cacheByte = getOneByteFromKmerAtPosition(0, bytes, offset, preSize);
-
-		// copy prekmer
-		for (int k = 0; k < preKmer.lettersInKmer - initialKmerSize + 1; k += 4) {
-			byte onebyte = getOneByteFromKmerAtPosition(k, preKmer.bytes,
-					preKmer.offset, preKmer.bytesUsed);
-			appendOneByteAtPosition(k, onebyte, bytes, offset, bytesUsed);
-		}
-
-		// copy current kmer
-		int k = 4;
-		for (; k < preKmerLength; k += 4) {
-			byte onebyte = getOneByteFromKmerAtPosition(k, bytes, offset,
-					preSize);
-			appendOneByteAtPosition(preKmer.lettersInKmer - initialKmerSize + k
-					- 4 + 1, cacheByte, bytes, offset, bytesUsed);
-			cacheByte = onebyte;
-		}
-		appendOneByteAtPosition(preKmer.lettersInKmer - initialKmerSize + k - 4
-				+ 1, cacheByte, bytes, offset, bytesUsed);
-		clearLeadBit();
-	}
-
-	public void mergeWithKmerInDir(byte dir, int initialKmerSize,
-			KmerBytesWritable kmer) {
-		switch (dir & DirectionFlag.DIR_MASK) {
-		case DirectionFlag.DIR_FF:
-			mergeWithFFKmer(initialKmerSize, kmer);
-			break;
-		case DirectionFlag.DIR_FR:
-			mergeWithFRKmer(initialKmerSize, kmer);
-			break;
-		case DirectionFlag.DIR_RF:
-			mergeWithRFKmer(initialKmerSize, kmer);
-			break;
-		case DirectionFlag.DIR_RR:
-			mergeWithRRKmer(initialKmerSize, kmer);
-			break;
-		default:
-			throw new RuntimeException("Direction not recognized: " + dir);
-		}
-	}
-
-	public static void appendOneByteAtPosition(int k, byte onebyte,
-			byte[] buffer, int start, int length) {
-		int position = start + length - 1 - k / 4;
-		if (position < start) {
-			throw new IllegalArgumentException(
-					"Buffer for kmer storage is invalid");
-		}
-		int shift = ((k) % 4) << 1;
-		int mask = shift == 0 ? 0 : ((1 << shift) - 1);
-
-		buffer[position] = (byte) ((buffer[position] & mask) | ((0xff & onebyte) << shift));
-		if (position > start && shift != 0) {
-			buffer[position - 1] = (byte) ((buffer[position - 1] & (0xff - mask)) | ((byte) ((0xff & onebyte) >>> (8 - shift))));
-		}
-	}
-
-	public static byte getOneByteFromKmerAtPosition(int k, byte[] buffer,
-			int start, int length) {
-		int position = start + length - 1 - k / 4;
-		if (position < start) {
-			throw new IllegalArgumentException(
-					"Buffer of kmer storage is invalid");
-		}
-		int shift = (k % 4) << 1;
-		byte data = (byte) (((0xff) & buffer[position]) >>> shift);
-		if (shift != 0 && position > start) {
-			data |= 0xff & (buffer[position - 1] << (8 - shift));
-		}
-		return data;
-	}
-
-	protected void clearLeadBit() {
-		if (lettersInKmer % 4 != 0) {
-			bytes[offset] &= (1 << ((lettersInKmer % 4) << 1)) - 1;
-		}
-	}
-
-	@Override
-	public void readFields(DataInput in) throws IOException {
-		lettersInKmer = in.readInt();
-		bytesUsed = KmerUtil.getByteNumFromK(lettersInKmer);
-		if (lettersInKmer > 0) {
-			if (this.bytes.length < this.bytesUsed) {
-				this.bytes = new byte[this.bytesUsed];
-				this.offset = 0;
-
-			}
-			in.readFully(bytes, offset, bytesUsed);
-		}
-	}
-
-	@Override
-	public void write(DataOutput out) throws IOException {
-		out.writeInt(lettersInKmer);
-		if (lettersInKmer > 0) {
-			out.write(bytes, offset, bytesUsed);
-		}
-	}
-
-	@Override
-	public int hashCode() {
-		return super.hashCode() * 31 + this.lettersInKmer;
-	}
-
-	@Override
-	public boolean equals(Object right_obj) {
-		if (right_obj instanceof KmerBytesWritable)
-			return this.lettersInKmer == ((KmerBytesWritable) right_obj).lettersInKmer
-					&& super.equals(right_obj);
-		return false;
-	}
-
-	@Override
-	public String toString() {
-		return KmerUtil.recoverKmerFrom(this.lettersInKmer, this.getBytes(),
-				offset, this.getLength());
-	}
-
-	public static class Comparator extends WritableComparator {
-		private static final int LEADING_BYTES = 4;
-
-		public Comparator() {
-			super(KmerBytesWritable.class);
-		}
-
-		public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
-			int kmerlength1 = Marshal.getInt(b1, s1);
-			int kmerlength2 = Marshal.getInt(b2, s2);
-			if (kmerlength1 == kmerlength2) {
-				return compareBytes(b1, s1 + LEADING_BYTES, l1 - LEADING_BYTES,
-						b2, s2 + LEADING_BYTES, l2 - LEADING_BYTES);
-			}
-			return kmerlength1 - kmerlength2;
-		}
-	}
-
-	static { // register this comparator
-		WritableComparator.define(KmerBytesWritable.class, new Comparator());
-	}
+    static { // register this comparator
+        WritableComparator.define(KmerBytesWritable.class, new Comparator());
+    }
 
 }
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritableFactory.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritableFactory.java
index f805610..16df821 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritableFactory.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerBytesWritableFactory.java
@@ -16,10 +16,10 @@
 package edu.uci.ics.genomix.type;
 
 public class KmerBytesWritableFactory {
-    private KmerBytesWritable kmer;
+    private VKmerBytesWritable kmer;
 
     public KmerBytesWritableFactory(int k) {
-        kmer = new KmerBytesWritable(k);
+        kmer = new VKmerBytesWritable(k);
     }
 
     /**
@@ -30,7 +30,7 @@
      * @param array
      * @param start
      */
-    public KmerBytesWritable getKmerByRead(int k, byte[] array, int start) {
+    public VKmerBytesWritable getKmerByRead(int k, byte[] array, int start) {
         kmer.reset(k);
         kmer.setByRead(array, start);
         return kmer;
@@ -43,7 +43,7 @@
      * @param array
      * @param start
      */
-    public KmerBytesWritable getKmerByReadReverse(int k, byte[] array, int start) {
+    public VKmerBytesWritable getKmerByReadReverse(int k, byte[] array, int start) {
         kmer.reset(k);
         kmer.setByReadReverse(array, start);
         return kmer;
@@ -59,28 +59,28 @@
      * @param kmerChain
      * @return LastKmer bytes array
      */
-    public KmerBytesWritable getLastKmerFromChain(int lastK, final KmerBytesWritable kmerChain) {
-        if (lastK > kmerChain.getKmerLength()) {
+    public VKmerBytesWritable getLastKmerFromChain(int lastK, final VKmerBytesWritable kmerChain) {
+        if (lastK > kmerChain.getKmerLetterLength()) {
             return null;
         }
-        if (lastK == kmerChain.getKmerLength()) {
+        if (lastK == kmerChain.getKmerLetterLength()) {
             kmer.setAsCopy(kmerChain);
             return kmer;
         }
         kmer.reset(lastK);
 
         /** from end to start */
-        int byteInChain = kmerChain.getLength() - 1 - (kmerChain.getKmerLength() - lastK) / 4;
-        int posInByteOfChain = ((kmerChain.getKmerLength() - lastK) % 4) << 1; // *2
-        int byteInKmer = kmer.getLength() - 1;
+        int byteInChain = kmerChain.getKmerByteLength() - 1 - (kmerChain.getKmerLetterLength() - lastK) / 4;
+        int posInByteOfChain = ((kmerChain.getKmerLetterLength() - lastK) % 4) << 1; // *2
+        int byteInKmer = kmer.getKmerByteLength() - 1;
         for (; byteInKmer >= 0 && byteInChain > 0; byteInKmer--, byteInChain--) {
-            kmer.getBytes()[byteInKmer] = (byte) ((0xff & kmerChain.getBytes()[byteInChain]) >> posInByteOfChain);
-            kmer.getBytes()[byteInKmer] |= ((kmerChain.getBytes()[byteInChain - 1] << (8 - posInByteOfChain)));
+            kmer.getBytes()[byteInKmer + kmer.getKmerOffset()] = (byte) ((0xff & kmerChain.getBytes()[byteInChain + kmerChain.getKmerOffset()]) >> posInByteOfChain);
+            kmer.getBytes()[byteInKmer + kmer.getKmerOffset()] |= ((kmerChain.getBytes()[byteInChain  + kmerChain.getKmerOffset() - 1] << (8 - posInByteOfChain)));
         }
 
         /** last kmer byte */
         if (byteInKmer == 0) {
-            kmer.getBytes()[0] = (byte) ((kmerChain.getBytes()[0] & 0xff) >> posInByteOfChain);
+            kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) ((kmerChain.getBytes()[0 + kmerChain.getKmerOffset()] & 0xff) >> posInByteOfChain);
         }
         kmer.clearLeadBit();
         return kmer;
@@ -95,52 +95,52 @@
      * @param kmerChain
      * @return FirstKmer bytes array
      */
-    public KmerBytesWritable getFirstKmerFromChain(int firstK, final KmerBytesWritable kmerChain) {
-        if (firstK > kmerChain.getKmerLength()) {
+    public VKmerBytesWritable getFirstKmerFromChain(int firstK, final VKmerBytesWritable kmerChain) {
+        if (firstK > kmerChain.getKmerLetterLength()) {
             return null;
         }
-        if (firstK == kmerChain.getKmerLength()) {
+        if (firstK == kmerChain.getKmerLetterLength()) {
             kmer.setAsCopy(kmerChain);
             return kmer;
         }
         kmer.reset(firstK);
 
         int i = 1;
-        for (; i < kmer.getLength(); i++) {
-            kmer.getBytes()[kmer.getLength() - i] = kmerChain.getBytes()[kmerChain.getLength() - i];
+        for (; i < kmer.getKmerByteLength(); i++) {
+            kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - i] = kmerChain.getBytes()[kmerChain.getKmerOffset() + kmerChain.getKmerByteLength() - i];
         }
         int posInByteOfChain = (firstK % 4) << 1; // *2
         if (posInByteOfChain == 0) {
-            kmer.getBytes()[0] = kmerChain.getBytes()[kmerChain.getLength() - i];
+            kmer.getBytes()[0 + kmer.getKmerOffset()] = kmerChain.getBytes()[kmerChain.getKmerOffset() + kmerChain.getKmerByteLength() - i];
         } else {
-            kmer.getBytes()[0] = (byte) (kmerChain.getBytes()[kmerChain.getLength() - i] & ((1 << posInByteOfChain) - 1));
+            kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) (kmerChain.getBytes()[kmerChain.getKmerOffset() + kmerChain.getKmerByteLength() - i] & ((1 << posInByteOfChain) - 1));
         }
         kmer.clearLeadBit();
         return kmer;
     }
 
-    public KmerBytesWritable getSubKmerFromChain(int startK, int kSize, final KmerBytesWritable kmerChain) {
-        if (startK + kSize > kmerChain.getKmerLength()) {
+    public VKmerBytesWritable getSubKmerFromChain(int startK, int kSize, final VKmerBytesWritable kmerChain) {
+        if (startK + kSize > kmerChain.getKmerLetterLength()) {
             return null;
         }
-        if (startK == 0 && kSize == kmerChain.getKmerLength()) {
+        if (startK == 0 && kSize == kmerChain.getKmerLetterLength()) {
             kmer.setAsCopy(kmerChain);
             return kmer;
         }
         kmer.reset(kSize);
 
         /** from end to start */
-        int byteInChain = kmerChain.getLength() - 1 - startK / 4;
+        int byteInChain = kmerChain.getKmerByteLength() - 1 - startK / 4;
         int posInByteOfChain = startK % 4 << 1; // *2
-        int byteInKmer = kmer.getLength() - 1;
+        int byteInKmer = kmer.getKmerByteLength() - 1;
         for (; byteInKmer >= 0 && byteInChain > 0; byteInKmer--, byteInChain--) {
-            kmer.getBytes()[byteInKmer] = (byte) ((0xff & kmerChain.getBytes()[byteInChain]) >> posInByteOfChain);
-            kmer.getBytes()[byteInKmer] |= ((kmerChain.getBytes()[byteInChain - 1] << (8 - posInByteOfChain)));
+            kmer.getBytes()[byteInKmer + kmer.getKmerOffset()] = (byte) ((0xff & kmerChain.getBytes()[byteInChain + kmerChain.getKmerOffset()]) >> posInByteOfChain);
+            kmer.getBytes()[byteInKmer + kmer.getKmerOffset()] |= ((kmerChain.getBytes()[byteInChain + kmerChain.getKmerOffset() - 1] << (8 - posInByteOfChain)));
         }
 
         /** last kmer byte */
         if (byteInKmer == 0) {
-            kmer.getBytes()[0] = (byte) ((kmerChain.getBytes()[0] & 0xff) >> posInByteOfChain);
+            kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) ((kmerChain.getBytes()[0 + kmerChain.getKmerOffset()] & 0xff) >> posInByteOfChain);
         }
         kmer.clearLeadBit();
         return kmer;
@@ -159,15 +159,15 @@
      *            : next neighbor in gene-code format
      * @return the merged Kmer, this K of this Kmer is k+1
      */
-    public KmerBytesWritable mergeKmerWithNextCode(final KmerBytesWritable kmer, byte nextCode) {
-        this.kmer.reset(kmer.getKmerLength() + 1);
-        for (int i = 1; i <= kmer.getLength(); i++) {
-            this.kmer.getBytes()[this.kmer.getLength() - i] = kmer.getBytes()[kmer.getLength() - i];
+    public VKmerBytesWritable mergeKmerWithNextCode(final VKmerBytesWritable kmer, byte nextCode) {
+        this.kmer.reset(kmer.getKmerLetterLength() + 1);
+        for (int i = 1; i <= kmer.getKmerByteLength(); i++) {
+            this.kmer.getBytes()[this.kmer.getKmerOffset() + this.kmer.getKmerByteLength() - i] = kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - i];
         }
-        if (this.kmer.getLength() > kmer.getLength()) {
-            this.kmer.getBytes()[0] = (byte) (nextCode & 0x3);
+        if (this.kmer.getKmerByteLength() > kmer.getKmerByteLength()) {
+            this.kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) (nextCode & 0x3);
         } else {
-            this.kmer.getBytes()[0] = (byte) (kmer.getBytes()[0] | ((nextCode & 0x3) << ((kmer.getKmerLength() % 4) << 1)));
+            this.kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) (kmer.getBytes()[0 + kmer.getKmerOffset()] | ((nextCode & 0x3) << ((kmer.getKmerLetterLength() % 4) << 1)));
         }
         this.kmer.clearLeadBit();
         return this.kmer;
@@ -186,17 +186,17 @@
      *            : next neighbor in gene-code format
      * @return the merged Kmer,this K of this Kmer is k+1
      */
-    public KmerBytesWritable mergeKmerWithPreCode(final KmerBytesWritable kmer, byte preCode) {
-        this.kmer.reset(kmer.getKmerLength() + 1);
+    public VKmerBytesWritable mergeKmerWithPreCode(final VKmerBytesWritable kmer, byte preCode) {
+        this.kmer.reset(kmer.getKmerLetterLength() + 1);
         int byteInMergedKmer = 0;
-        if (kmer.getKmerLength() % 4 == 0) {
-            this.kmer.getBytes()[0] = (byte) ((kmer.getBytes()[0] >> 6) & 0x3);
+        if (kmer.getKmerLetterLength() % 4 == 0) {
+            this.kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) ((kmer.getBytes()[0 + kmer.getKmerOffset()] >> 6) & 0x3);
             byteInMergedKmer++;
         }
-        for (int i = 0; i < kmer.getLength() - 1; i++, byteInMergedKmer++) {
-            this.kmer.getBytes()[byteInMergedKmer] = (byte) ((kmer.getBytes()[i] << 2) | ((kmer.getBytes()[i + 1] >> 6) & 0x3));
+        for (int i = 0; i < kmer.getKmerByteLength() - 1; i++, byteInMergedKmer++) {
+            this.kmer.getBytes()[byteInMergedKmer + kmer.getKmerOffset()] = (byte) ((kmer.getBytes()[i + kmer.getKmerOffset()] << 2) | ((kmer.getBytes()[i + kmer.getKmerOffset() + 1] >> 6) & 0x3));
         }
-        this.kmer.getBytes()[byteInMergedKmer] = (byte) ((kmer.getBytes()[kmer.getLength() - 1] << 2) | (preCode & 0x3));
+        this.kmer.getBytes()[byteInMergedKmer + kmer.getKmerOffset()] = (byte) ((kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - 1] << 2) | (preCode & 0x3));
         this.kmer.clearLeadBit();
         return this.kmer;
     }
@@ -215,28 +215,28 @@
      *            : bytes array of next kmer
      * @return merged kmer, the new k is @preK + @nextK
      */
-    public KmerBytesWritable mergeTwoKmer(final KmerBytesWritable preKmer, final KmerBytesWritable nextKmer) {
-        kmer.reset(preKmer.getKmerLength() + nextKmer.getKmerLength());
+    public VKmerBytesWritable mergeTwoKmer(final VKmerBytesWritable preKmer, final VKmerBytesWritable nextKmer) {
+        kmer.reset(preKmer.getKmerLetterLength() + nextKmer.getKmerLetterLength());
         int i = 1;
-        for (; i <= preKmer.getLength(); i++) {
-            kmer.getBytes()[kmer.getLength() - i] = preKmer.getBytes()[preKmer.getLength() - i];
+        for (; i <= preKmer.getKmerByteLength(); i++) {
+            kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - i] = preKmer.getBytes()[preKmer.getKmerOffset() + preKmer.getKmerByteLength() - i];
         }
         if (i > 1) {
             i--;
         }
-        if (preKmer.getKmerLength() % 4 == 0) {
-            for (int j = 1; j <= nextKmer.getLength(); j++) {
-                kmer.getBytes()[kmer.getLength() - i - j] = nextKmer.getBytes()[nextKmer.getLength() - j];
+        if (preKmer.getKmerLetterLength() % 4 == 0) {
+            for (int j = 1; j <= nextKmer.getKmerByteLength(); j++) {
+                kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - i - j] = nextKmer.getBytes()[nextKmer.getKmerOffset() + nextKmer.getKmerByteLength() - j];
             }
         } else {
-            int posNeedToMove = ((preKmer.getKmerLength() % 4) << 1);
-            kmer.getBytes()[kmer.getLength() - i] |= nextKmer.getBytes()[nextKmer.getLength() - 1] << posNeedToMove;
-            for (int j = 1; j < nextKmer.getLength(); j++) {
-                kmer.getBytes()[kmer.getLength() - i - j] = (byte) (((nextKmer.getBytes()[nextKmer.getLength() - j] & 0xff) >> (8 - posNeedToMove)) | (nextKmer
-                        .getBytes()[nextKmer.getLength() - j - 1] << posNeedToMove));
+            int posNeedToMove = ((preKmer.getKmerLetterLength() % 4) << 1);
+            kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - i] |= nextKmer.getBytes()[nextKmer.getKmerOffset() + nextKmer.getKmerByteLength() - 1] << posNeedToMove;
+            for (int j = 1; j < nextKmer.getKmerByteLength(); j++) {
+                kmer.getBytes()[kmer.getKmerOffset() + kmer.getKmerByteLength() - i - j] = (byte) (((nextKmer.getBytes()[nextKmer.getKmerOffset() + nextKmer.getKmerByteLength() - j] & 0xff) >> (8 - posNeedToMove)) | (nextKmer
+                        .getBytes()[nextKmer.getKmerOffset() + nextKmer.getKmerByteLength() - j - 1] << posNeedToMove));
             }
-            if (nextKmer.getKmerLength() % 4 == 0 || (nextKmer.getKmerLength() % 4) * 2 + posNeedToMove > 8) {
-                kmer.getBytes()[0] = (byte) ((0xff & nextKmer.getBytes()[0]) >> (8 - posNeedToMove));
+            if (nextKmer.getKmerLetterLength() % 4 == 0 || (nextKmer.getKmerLetterLength() % 4) * 2 + posNeedToMove > 8) {
+                kmer.getBytes()[0 + kmer.getKmerOffset()] = (byte) ((0xff & nextKmer.getBytes()[0 + nextKmer.getKmerOffset()]) >> (8 - posNeedToMove));
             }
         }
         kmer.clearLeadBit();
@@ -255,7 +255,7 @@
      *            : input genecode
      * @return new created kmer that shifted by afterCode, the K will not change
      */
-    public KmerBytesWritable shiftKmerWithNextCode(final KmerBytesWritable kmer, byte afterCode) {
+    public VKmerBytesWritable shiftKmerWithNextCode(final VKmerBytesWritable kmer, byte afterCode) {
         this.kmer.setAsCopy(kmer);
         this.kmer.shiftKmerWithNextCode(afterCode);
         return this.kmer;
@@ -273,7 +273,7 @@
      *            : input genecode
      * @return new created kmer that shifted by preCode, the K will not change
      */
-    public KmerBytesWritable shiftKmerWithPreCode(final KmerBytesWritable kmer, byte preCode) {
+    public VKmerBytesWritable shiftKmerWithPreCode(final VKmerBytesWritable kmer, byte preCode) {
         this.kmer.setAsCopy(kmer);
         this.kmer.shiftKmerWithPreCode(preCode);
         return this.kmer;
@@ -284,22 +284,22 @@
      * 
      * @param kmer
      */
-    public KmerBytesWritable reverse(final KmerBytesWritable kmer) {
-        this.kmer.reset(kmer.getKmerLength());
+    public VKmerBytesWritable reverse(final VKmerBytesWritable kmer) {
+        this.kmer.reset(kmer.getKmerLetterLength());
 
-        int curPosAtKmer = ((kmer.getKmerLength() - 1) % 4) << 1;
+        int curPosAtKmer = ((kmer.getKmerLetterLength() - 1) % 4) << 1;
         int curByteAtKmer = 0;
 
         int curPosAtReverse = 0;
-        int curByteAtReverse = this.kmer.getLength() - 1;
-        this.kmer.getBytes()[curByteAtReverse] = 0;
-        for (int i = 0; i < kmer.getKmerLength(); i++) {
-            byte gene = (byte) ((kmer.getBytes()[curByteAtKmer] >> curPosAtKmer) & 0x03);
-            this.kmer.getBytes()[curByteAtReverse] |= gene << curPosAtReverse;
+        int curByteAtReverse = this.kmer.getKmerByteLength() - 1;
+        this.kmer.getBytes()[curByteAtReverse + this.kmer.getKmerOffset()] = 0;
+        for (int i = 0; i < kmer.getKmerLetterLength(); i++) {
+            byte gene = (byte) ((kmer.getBytes()[curByteAtKmer + kmer.getKmerOffset()] >> curPosAtKmer) & 0x03);
+            this.kmer.getBytes()[curByteAtReverse + this.kmer.getKmerOffset()] |= gene << curPosAtReverse;
             curPosAtReverse += 2;
             if (curPosAtReverse >= 8) {
                 curPosAtReverse = 0;
-                this.kmer.getBytes()[--curByteAtReverse] = 0;
+                this.kmer.getBytes()[--curByteAtReverse + this.kmer.getKmerOffset()] = 0;
             }
             curPosAtKmer -= 2;
             if (curPosAtKmer < 0) {
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerListWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerListWritable.java
index 6bf8dac..2aee32d 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerListWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerListWritable.java
@@ -10,259 +10,250 @@
 
 import org.apache.hadoop.io.Writable;
 
-import edu.uci.ics.genomix.data.KmerUtil;
 import edu.uci.ics.genomix.data.Marshal;
 
-
 /**
- * A list of fixed-length kmers.  The length of this list is stored internally 
- *
+ * A list of fixed-length kmers. The length of this list is stored internally.
  */
-public class KmerListWritable implements Writable, Iterable<KmerBytesWritable>,
-		Serializable {
-	private static final long serialVersionUID = 1L;
-	protected static final byte[] EMPTY_BYTES = { 0, 0, 0, 0 };
-	protected static final int HEADER_SIZE = 4;
+public class KmerListWritable implements Writable, Iterable<KmerBytesWritable>, Serializable {
+    private static final long serialVersionUID = 1L;
+    protected static final byte[] EMPTY_BYTES = { 0, 0, 0, 0 };
+    protected static final int HEADER_SIZE = 4;
 
-	protected byte[] storage;
-	protected int offset;
-	protected int valueCount;
+    protected byte[] storage;
+    protected int offset;
+    protected int valueCount;
+    protected int storageMaxSize;  // since we may be a reference inside a larger datablock, we must track our maximum size
 
-	protected int bytesPerKmer = 0;
-	protected int lettersPerKmer = 0;
-	private KmerBytesWritable posIter = new KmerBytesWritable();
+    private KmerBytesWritable posIter = new KmerBytesWritable();
 
-	public KmerListWritable() {
-		this.storage = EMPTY_BYTES;
-		this.valueCount = 0;
-		this.offset = 0;
-	}
+    public KmerListWritable() {
+        storage = EMPTY_BYTES;
+        valueCount = 0;
+        offset = 0;
+        storageMaxSize = storage.length; 
+    }
 
-	public KmerListWritable(int kmerlength) {
-		this();
-		this.lettersPerKmer = kmerlength;
-		this.bytesPerKmer = KmerUtil.getByteNumFromK(kmerlength);
-	}
+    public KmerListWritable(byte[] data, int offset) {
+        setNewReference(data, offset);
+    }
 
-	public KmerListWritable(int kmerlength, byte[] data, int offset) {
-		this.lettersPerKmer = kmerlength;
-		this.bytesPerKmer = KmerUtil.getByteNumFromK(kmerlength);
-		setNewReference(data, offset);
-	}
+    public KmerListWritable(List<KmerBytesWritable> kmers) {
+        this();
+        setSize(kmers.size() * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE); // reserve space for all elements
+        for (KmerBytesWritable kmer : kmers) {
+            append(kmer);
+        }
+    }
 
-	public KmerListWritable(List<KmerBytesWritable> kmers) {
-		this();
-		setSize(kmers.size()); // reserve space for all elements
-		for (KmerBytesWritable kmer : kmers) {
-			if (kmer.getKmerLength() != lettersPerKmer)
-				throw new IllegalArgumentException("Kmer " + kmer.toString()
-						+ " is of incorrect length (l=" + kmer.getKmerLength()
-						+ ") for this list (should be " + lettersPerKmer + ").");
-			append(kmer);
-		}
-	}
+    public void setNewReference(byte[] data, int offset) {
+        valueCount = Marshal.getInt(data, offset);
+        if (valueCount * KmerBytesWritable.getBytesPerKmer() > data.length - offset) {
+            throw new IllegalArgumentException("Specified data buffer (len=" + (data.length - offset)
+                    + ") is not large enough to store requested number of elements (" + valueCount + ")!");
+        }
+        this.storage = data;
+        this.offset = offset;
+        this.storageMaxSize = valueCount * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE;
+    }
 
-	public void setNewReference(byte[] data, int offset) {
-		this.valueCount = Marshal.getInt(data, offset);
-		this.storage = data;
-		this.offset = offset;
-	}
+    public void append(KmerBytesWritable kmer) {
+        setSize((1 + valueCount) * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+        System.arraycopy(kmer.getBytes(), 0, storage,
+                offset + HEADER_SIZE + valueCount * KmerBytesWritable.getBytesPerKmer(),
+                KmerBytesWritable.getBytesPerKmer());
+        valueCount += 1;
+        Marshal.putInt(valueCount, storage, offset);
+    }
 
-	public void append(KmerBytesWritable kmer) {
-		setSize((1 + valueCount) * bytesPerKmer);
-		System.arraycopy(kmer.getBytes(), 0, storage, offset + valueCount
-				* bytesPerKmer, bytesPerKmer);
-		valueCount += 1;
-	}
+    /*
+     * Append the otherList to the end of myList
+     */
+    public void appendList(KmerListWritable otherList) {
+        if (otherList.valueCount > 0) {
+            setSize((valueCount + otherList.valueCount) * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+            // copy contents of otherList into the end of my storage
+            System.arraycopy(otherList.storage, otherList.offset + HEADER_SIZE, storage, offset + HEADER_SIZE
+                    + valueCount * KmerBytesWritable.getBytesPerKmer(),
+                    otherList.valueCount * KmerBytesWritable.getBytesPerKmer());
+            valueCount += otherList.valueCount;
+            Marshal.putInt(valueCount, storage, offset);
+        }
+    }
 
-	/*
-	 * Append the otherList to the end of myList
-	 */
-	public void appendList(KmerListWritable otherList) {
-		if (otherList.valueCount > 0) {
-			setSize((valueCount + otherList.valueCount) * bytesPerKmer);
-			// copy contents of otherList into the end of my storage
-			System.arraycopy(otherList.storage, otherList.offset, storage,
-					offset + valueCount * bytesPerKmer, otherList.valueCount
-							* bytesPerKmer);
-			valueCount += otherList.valueCount;
-		}
-	}
+    /**
+     * Save the union of my list and otherList. Uses a temporary HashSet for
+     * uniquefication
+     */
+    public void unionUpdate(KmerListWritable otherList) {
+        int newSize = valueCount + otherList.valueCount;
+        HashSet<KmerBytesWritable> uniqueElements = new HashSet<KmerBytesWritable>(newSize);
+        for (KmerBytesWritable kmer : this) {
+            uniqueElements.add(kmer);
+        }
+        for (KmerBytesWritable kmer : otherList) {
+            uniqueElements.add(kmer);
+        }
+        valueCount = 0;
+        setSize(newSize * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+        for (KmerBytesWritable kmer : uniqueElements) {
+            append(kmer);
+        }
+        Marshal.putInt(valueCount, storage, offset);
+    }
 
-	/**
-	 * Save the union of my list and otherList. Uses a temporary HashSet for
-	 * uniquefication
-	 */
-	public void unionUpdate(KmerListWritable otherList) {
-		int newSize = valueCount + otherList.valueCount;
-		HashSet<KmerBytesWritable> uniqueElements = new HashSet<KmerBytesWritable>(
-				newSize);
-		for (KmerBytesWritable kmer : this) {
-			uniqueElements.add(kmer);
-		}
-		for (KmerBytesWritable kmer : otherList) {
-			uniqueElements.add(kmer);
-		}
-		valueCount = 0;
-		setSize(newSize);
-		for (KmerBytesWritable kmer : uniqueElements) {
-			append(kmer);
-		}
-	}
+    protected void setSize(int size) {
+        if (size > getCapacity()) {
+            setCapacity((size * 3 / 2));
+        }
+    }
 
-	protected void setSize(int size) {
-		if (size > getCapacity()) {
-			setCapacity((size * 3 / 2));
-		}
-	}
+    protected int getCapacity() {
+        return storageMaxSize - offset;
+    }
 
-	protected int getCapacity() {
-		return storage.length - offset;
-	}
+    protected void setCapacity(int new_cap) {
+        if (new_cap > getCapacity()) {
+            byte[] new_data = new byte[new_cap];
+            if (valueCount > 0) {
+                System.arraycopy(storage, offset, new_data, 0, valueCount * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+            }
+            storage = new_data;
+            offset = 0;
+            storageMaxSize = storage.length;
+        }
+    }
 
-	protected void setCapacity(int new_cap) {
-		if (new_cap > getCapacity()) {
-			byte[] new_data = new byte[new_cap];
-			if (storage.length - offset > 0) {
-				System.arraycopy(storage, offset, new_data, 0, storage.length
-						- offset);
-			}
-			storage = new_data;
-			offset = 0;
-		}
-	}
+    public void reset() {
+        valueCount = 0;
+    }
 
-	public void reset(int kmerSize) {
-		lettersPerKmer = kmerSize;
-		bytesPerKmer = KmerUtil.getByteNumFromK(lettersPerKmer);
-		storage = EMPTY_BYTES;
-		valueCount = 0;
-		offset = 0;
-	}
+    public KmerBytesWritable getPosition(int i) {
+        if (i >= valueCount) {
+            throw new ArrayIndexOutOfBoundsException("No such positions");
+        }
+        posIter.setAsReference(storage, offset + HEADER_SIZE + i * KmerBytesWritable.getBytesPerKmer());
+        return posIter;
+    }
 
-	public KmerBytesWritable getPosition(int i) {
-		if (i >= valueCount) {
-			throw new ArrayIndexOutOfBoundsException("No such positions");
-		}
-		posIter.setAsReference(lettersPerKmer, storage, offset + i
-				* bytesPerKmer);
-		return posIter;
-	}
+    public void setCopy(KmerListWritable otherList) {
+        setCopy(otherList.storage, otherList.offset);
+    }
 
-	public void set(KmerListWritable otherList) {
-		this.lettersPerKmer = otherList.lettersPerKmer;
-		this.bytesPerKmer = otherList.bytesPerKmer;
-		set(otherList.valueCount, otherList.storage, otherList.offset);
-	}
+    /**
+     * read a KmerListWritable from newData, which should include the header
+     */
+    public void setCopy(byte[] newData, int offset) {
+        int newValueCount = Marshal.getInt(newData, offset);
+        setSize(newValueCount * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+        if (newValueCount > 0) {
+            System.arraycopy(newData, offset + HEADER_SIZE, storage, this.offset + HEADER_SIZE, newValueCount
+                    * KmerBytesWritable.getBytesPerKmer());
+        }
+        valueCount = newValueCount;
+        Marshal.putInt(valueCount, storage, this.offset);
+    }
 
-	public void set(int valueCount, byte[] newData, int offset) {
-		this.valueCount = valueCount;
-		setSize(valueCount * bytesPerKmer);
-		if (valueCount > 0) {
-			System.arraycopy(newData, offset, storage, this.offset, valueCount
-					* bytesPerKmer);
-		}
-	}
+    @Override
+    public Iterator<KmerBytesWritable> iterator() {
+        Iterator<KmerBytesWritable> it = new Iterator<KmerBytesWritable>() {
 
-	@Override
-	public Iterator<KmerBytesWritable> iterator() {
-		Iterator<KmerBytesWritable> it = new Iterator<KmerBytesWritable>() {
+            private int currentIndex = 0;
 
-			private int currentIndex = 0;
+            @Override
+            public boolean hasNext() {
+                return currentIndex < valueCount;
+            }
 
-			@Override
-			public boolean hasNext() {
-				return currentIndex < valueCount;
-			}
+            @Override
+            public KmerBytesWritable next() {
+                return getPosition(currentIndex++);
+            }
 
-			@Override
-			public KmerBytesWritable next() {
-				return getPosition(currentIndex++);
-			}
+            @Override
+            public void remove() {
+                if (currentIndex < valueCount)
+                    System.arraycopy(storage, offset + currentIndex * KmerBytesWritable.getBytesPerKmer(), storage,
+                            offset + (currentIndex - 1) * KmerBytesWritable.getBytesPerKmer(),
+                            (valueCount - currentIndex) * KmerBytesWritable.getBytesPerKmer());
+                valueCount--;
+                currentIndex--;
+                Marshal.putInt(valueCount, storage, offset);
+            }
+        };
+        return it;
+    }
 
-			@Override
-			public void remove() {
-				if (currentIndex < valueCount)
-					System.arraycopy(storage, offset + currentIndex
-							* bytesPerKmer, storage, offset
-							+ (currentIndex - 1) * bytesPerKmer,
-							(valueCount - currentIndex) * bytesPerKmer);
-				valueCount--;
-				currentIndex--;
-			}
-		};
-		return it;
-	}
+    /*
+     * remove the first instance of `toRemove`. Uses a linear scan. Throws an
+     * exception if not in this list.
+     */
+    public void remove(KmerBytesWritable toRemove, boolean ignoreMissing) {
+        Iterator<KmerBytesWritable> posIterator = this.iterator();
+        while (posIterator.hasNext()) {
+            if (toRemove.equals(posIterator.next())) {
+                posIterator.remove();
+                return;  // break as soon as the element is found 
+            }
+        }
+        // element was not found
+        if (!ignoreMissing) {
+            throw new ArrayIndexOutOfBoundsException("the KmerBytesWritable `" + toRemove.toString()
+                    + "` was not found in this list.");
+        }
+    }
 
-	/*
-	 * remove the first instance of `toRemove`. Uses a linear scan. Throws an
-	 * exception if not in this list.
-	 */
-	public void remove(KmerBytesWritable toRemove, boolean ignoreMissing) {
-		Iterator<KmerBytesWritable> posIterator = this.iterator();
-		while (posIterator.hasNext()) {
-			if (toRemove.equals(posIterator.next())) {
-				posIterator.remove();
-				return;
-			}
-		}
-		if (!ignoreMissing) {
-			throw new ArrayIndexOutOfBoundsException("the KmerBytesWritable `"
-					+ toRemove.toString() + "` was not found in this list.");
-		}
-	}
+    public void remove(KmerBytesWritable toRemove) {
+        remove(toRemove, false);
+    }
 
-	public void remove(KmerBytesWritable toRemove) {
-		remove(toRemove, false);
-	}
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        valueCount = in.readInt();
+        setSize(valueCount * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+        in.readFully(storage, offset + HEADER_SIZE, valueCount * KmerBytesWritable.getBytesPerKmer() - HEADER_SIZE);
+        Marshal.putInt(valueCount, storage, offset);
+    }
 
-	@Override
-	public void readFields(DataInput in) throws IOException {
-		this.valueCount = in.readInt();
-		setSize(valueCount * bytesPerKmer);// kmerByteSize
-		in.readFully(storage, offset, valueCount * bytesPerKmer);// kmerByteSize
-	}
+    @Override
+    public void write(DataOutput out) throws IOException {
+        out.write(storage, offset, valueCount * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE);
+    }
 
-	@Override
-	public void write(DataOutput out) throws IOException {
-		out.writeInt(valueCount);
-		out.write(storage, offset, valueCount * bytesPerKmer);
-	}
+    public int getCountOfPosition() {
+        return valueCount;
+    }
 
-	public int getCountOfPosition() {
-		return valueCount;
-	}
+    public byte[] getByteArray() {
+        return storage;
+    }
 
-	public byte[] getByteArray() {
-		return storage;
-	}
+    public int getStartOffset() {
+        return offset;
+    }
 
-	public int getStartOffset() {
-		return offset;
-	}
+    public int getLength() {
+        return valueCount * KmerBytesWritable.getBytesPerKmer() + HEADER_SIZE;
+    }
 
-	public int getLength() {
-		return valueCount * bytesPerKmer;
-	}
+    @Override
+    public String toString() {
+        StringBuilder sbuilder = new StringBuilder();
+        sbuilder.append('[');
+        for (int i = 0; i < valueCount; i++) {
+            sbuilder.append(getPosition(i).toString());
+            sbuilder.append(',');
+        }
+        if (valueCount > 0) {
+            sbuilder.setCharAt(sbuilder.length() - 1, ']');
+        } else {
+            sbuilder.append(']');
+        }
+        return sbuilder.toString();
+    }
 
-	@Override
-	public String toString() {
-		StringBuilder sbuilder = new StringBuilder();
-		sbuilder.append('[');
-		for (int i = 0; i < valueCount; i++) {
-			sbuilder.append(getPosition(i).toString());
-			sbuilder.append(',');
-		}
-		if (valueCount > 0) {
-			sbuilder.setCharAt(sbuilder.length() - 1, ']');
-		} else {
-			sbuilder.append(']');
-		}
-		return sbuilder.toString();
-	}
-
-	@Override
-	public int hashCode() {
-		return Marshal.hashBytes(getByteArray(), getStartOffset(), getLength());
-	}
+    @Override
+    public int hashCode() {
+        return Marshal.hashBytes(getByteArray(), getStartOffset(), getLength());
+    }
 }
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
index 98e37dc..362c12e 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
@@ -1,25 +1,27 @@
 package edu.uci.ics.genomix.type;
 
+import java.io.ByteArrayOutputStream;
 import java.io.DataInput;
 import java.io.DataOutput;
+import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.Serializable;
 
+import org.apache.hadoop.io.DataOutputBuffer;
 import org.apache.hadoop.io.WritableComparable;
 
 
 public class NodeWritable implements WritableComparable<NodeWritable>, Serializable{
 
     private static final long serialVersionUID = 1L;
-    public static final NodeWritable EMPTY_NODE = new NodeWritable(0);
+    public static final NodeWritable EMPTY_NODE = new NodeWritable();
     
     private PositionListWritable nodeIdList;
     private KmerListWritable forwardForwardList;
     private KmerListWritable forwardReverseList;
     private KmerListWritable reverseForwardList;
     private KmerListWritable reverseReverseList;
-    private KmerBytesWritable kmer;
-    private int kmerlength = 0;
+    private VKmerBytesWritable kmer;
     
     // merge/update directions
     public static class DirectionFlag {
@@ -31,48 +33,41 @@
     }
     
     public NodeWritable() {
-        this(0);
-    }
-    
-    public NodeWritable(int kmerlenth) {
-        this.kmerlength = kmerlenth;
         nodeIdList = new PositionListWritable();
-        forwardForwardList = new KmerListWritable(kmerlenth);
-        forwardReverseList = new KmerListWritable(kmerlenth);
-        reverseForwardList = new KmerListWritable(kmerlenth);
-        reverseReverseList = new KmerListWritable(kmerlenth);
-        kmer = new KmerBytesWritable(); //in graph construction - not set kmerlength Optimization: VKmer
+        forwardForwardList = new KmerListWritable();
+        forwardReverseList = new KmerListWritable();
+        reverseForwardList = new KmerListWritable();
+        reverseReverseList = new KmerListWritable();
+        kmer = new VKmerBytesWritable();  // in graph construction - not set kmerlength Optimization: VKmer
     }
     
     public NodeWritable(PositionListWritable nodeIdList, KmerListWritable FFList, KmerListWritable FRList,
-            KmerListWritable RFList, KmerListWritable RRList, KmerBytesWritable kmer) {
-        this(kmer.getKmerLength());
+            KmerListWritable RFList, KmerListWritable RRList, VKmerBytesWritable kmer) {
+        this();
         set(nodeIdList, FFList, FRList, RFList, RRList, kmer);
     }
     
     public void set(NodeWritable node){
-        this.kmerlength = node.kmerlength;
         set(node.nodeIdList, node.forwardForwardList, node.forwardReverseList, node.reverseForwardList, 
                 node.reverseReverseList, node.kmer);
     }
     
     public void set(PositionListWritable nodeIdList, KmerListWritable FFList, KmerListWritable FRList,
-            KmerListWritable RFList, KmerListWritable RRList, KmerBytesWritable kmer) {
+            KmerListWritable RFList, KmerListWritable RRList, VKmerBytesWritable kmer2) {
         this.nodeIdList.set(nodeIdList);
-        this.forwardForwardList.set(FFList);
-        this.forwardReverseList.set(FRList);
-        this.reverseForwardList.set(RFList);
-        this.reverseReverseList.set(RRList);
-        this.kmer.setAsCopy(kmer);
+        this.forwardForwardList.setCopy(FFList);
+        this.forwardReverseList.setCopy(FRList);
+        this.reverseForwardList.setCopy(RFList);
+        this.reverseReverseList.setCopy(RRList);
+        this.kmer.setAsCopy(kmer2);
     }
 
-    public void reset(int kmerSize) {
-        this.kmerlength = kmerSize;
+    public void reset() {
         this.nodeIdList.reset();
-        this.forwardForwardList.reset(kmerSize);
-        this.forwardReverseList.reset(kmerSize);
-        this.reverseForwardList.reset(kmerSize);
-        this.reverseReverseList.reset(kmerSize);
+        this.forwardForwardList.reset();
+        this.forwardReverseList.reset();
+        this.reverseForwardList.reset();
+        this.reverseReverseList.reset();
         this.kmer.reset(0);
     }
     
@@ -85,24 +80,16 @@
         this.nodeIdList.set(nodeIdList);
     }
 
-    public KmerBytesWritable getKmer() {
+    public VKmerBytesWritable getKmer() {
         return kmer;
     }
 
-    public void setKmer(KmerBytesWritable kmer) {
+    public void setKmer(VKmerBytesWritable kmer) {
         this.kmer.setAsCopy(kmer);
     }
     
-    public int getKmerlength() {
-        return kmerlength;
-    }
-
-    public void setKmerlength(int kmerlength) {
-        this.kmerlength = kmerlength;
-    }
-
-    public int getCount() {
-        return kmer.getKmerLength();
+    public int getKmerLength() {
+        return kmer.getKmerLetterLength();
     }
     
     public KmerListWritable getFFList() {
@@ -122,19 +109,19 @@
     }
     
 	public void setFFList(KmerListWritable forwardForwardList) {
-		this.forwardForwardList.set(forwardForwardList);
+		this.forwardForwardList.setCopy(forwardForwardList);
 	}
 
 	public void setFRList(KmerListWritable forwardReverseList) {
-		this.forwardReverseList.set(forwardReverseList);
+		this.forwardReverseList.setCopy(forwardReverseList);
 	}
 
 	public void setRFList(KmerListWritable reverseForwardList) {
-		this.reverseForwardList.set(reverseForwardList);
+		this.reverseForwardList.setCopy(reverseForwardList);
 	}
 
 	public void setRRList(KmerListWritable reverseReverseList) {
-		this.reverseReverseList.set(reverseReverseList);
+		this.reverseReverseList.setCopy(reverseReverseList);
 	}
 
 	public KmerListWritable getListFromDir(byte dir) {
@@ -152,9 +139,60 @@
         }
     }
 	
+	/**
+	 * Returns the length of the byte-array version of this node
+	 */
+	public int getSerializedLength() {
+	    return nodeIdList.getLength() + forwardForwardList.getLength() + forwardReverseList.getLength() + 
+	            reverseForwardList.getLength() + reverseReverseList.getLength() + kmer.getLength();
+	}
+	
+	/**
+     * Return this Node's representation as a new byte array 
+     */
+    public byte[] marshalToByteArray() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(getSerializedLength());
+        DataOutputStream out = new DataOutputStream(baos);
+        write(out);
+        return baos.toByteArray();
+    }
+    
+    public void setAsCopy(byte[] data, int offset) {
+        int curOffset = offset;
+        nodeIdList.set(data, curOffset);
+        
+        curOffset += nodeIdList.getLength();
+        forwardForwardList.setCopy(data, curOffset);
+        curOffset += forwardForwardList.getLength();
+        forwardReverseList.setCopy(data, curOffset);
+        curOffset += forwardReverseList.getLength();
+        reverseForwardList.setCopy(data, curOffset);
+        curOffset += reverseForwardList.getLength();
+        reverseReverseList.setCopy(data, curOffset);
+        
+        curOffset += reverseReverseList.getLength();
+        kmer.setAsCopy(data, curOffset);
+    }
+    
+    public void setAsReference(byte[] data, int offset) {
+        int curOffset = offset;
+        nodeIdList.setNewReference(data, curOffset);
+        
+        curOffset += nodeIdList.getLength();
+        forwardForwardList.setNewReference(data, curOffset);
+        curOffset += forwardForwardList.getLength();
+        forwardReverseList.setNewReference(data, curOffset);
+        curOffset += forwardReverseList.getLength();
+        reverseForwardList.setNewReference(data, curOffset);
+        curOffset += reverseForwardList.getLength();
+        reverseReverseList.setNewReference(data, curOffset);
+        
+        curOffset += reverseReverseList.getLength();
+        kmer.setAsReference(data, curOffset);
+    }
+	
     @Override
     public void write(DataOutput out) throws IOException {
-        out.writeInt(kmerlength);
         this.nodeIdList.write(out);
         this.forwardForwardList.write(out);
         this.forwardReverseList.write(out);
@@ -165,8 +203,7 @@
 
     @Override
     public void readFields(DataInput in) throws IOException {
-        this.kmerlength = in.readInt();
-        reset(kmerlength);
+        reset();
         this.nodeIdList.readFields(in);
         this.forwardForwardList.readFields(in);
         this.forwardReverseList.readFields(in);
@@ -211,15 +248,15 @@
         return sbuilder.toString();
     }
 
-    public void mergeForwardNext(NodeWritable nextNode, int initialKmerSize) {
-        this.forwardForwardList.set(nextNode.forwardForwardList);
-        this.forwardReverseList.set(nextNode.forwardReverseList);
+    public void mergeForwardNext(final NodeWritable nextNode, int initialKmerSize) {
+        this.forwardForwardList.setCopy(nextNode.forwardForwardList);
+        this.forwardReverseList.setCopy(nextNode.forwardReverseList);
         kmer.mergeWithFFKmer(initialKmerSize, nextNode.getKmer());
     }
 
-    public void mergeForwardPre(NodeWritable preNode, int initialKmerSize) {
-        this.reverseForwardList.set(preNode.reverseForwardList);
-        this.reverseReverseList.set(preNode.reverseReverseList);
+    public void mergeForwardPre(final NodeWritable preNode, int initialKmerSize) {
+        this.reverseForwardList.setCopy(preNode.reverseForwardList);
+        this.reverseReverseList.setCopy(preNode.reverseReverseList);
         kmer.mergeWithRRKmer(initialKmerSize, preNode.getKmer());
     }
     
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionListWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionListWritable.java
index b056c14..8de4b0e 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionListWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionListWritable.java
@@ -13,78 +13,84 @@
 import edu.uci.ics.genomix.data.Marshal;
 import edu.uci.ics.genomix.type.PositionWritable;
 
-public class PositionListWritable implements Writable, Iterable<PositionWritable>, Serializable{
+public class PositionListWritable implements Writable, Iterable<PositionWritable>, Serializable {
     private static final long serialVersionUID = 1L;
+    protected static final byte[] EMPTY_BYTES = {0,0,0,0};
+    protected static final int HEADER_SIZE = 4;
+    
     protected byte[] storage;
     protected int offset;
     protected int valueCount;
-    protected static final byte[] EMPTY = {};
-    
+    protected int maxStorageSize;
+
+
     protected PositionWritable posIter = new PositionWritable();
-    
+
     public PositionListWritable() {
-        this.storage = EMPTY;
-        this.valueCount = 0;
-        this.offset = 0;
+        storage = EMPTY_BYTES;
+        valueCount = 0;
+        offset = 0;
+        maxStorageSize = storage.length; 
     }
-    
-    public PositionListWritable(int count, byte[] data, int offset) {
-        setNewReference(count, data, offset);
+
+    public PositionListWritable(byte[] data, int offset) {
+        setNewReference(data, offset);
     }
-    
+
     public PositionListWritable(List<PositionWritable> posns) {
         this();
-        setSize(posns.size());  // reserve space for all elements
+        setSize(posns.size() * PositionWritable.LENGTH + HEADER_SIZE); // reserve space for all elements
         for (PositionWritable p : posns) {
             append(p);
         }
     }
-    
-    public void setNewReference(int count, byte[] data, int offset) {
-        this.valueCount = count;
+  
+    public void setNewReference(byte[] data, int offset) {
+        this.valueCount = Marshal.getInt(data, offset);
         this.storage = data;
         this.offset = offset;
+        maxStorageSize = valueCount * PositionWritable.LENGTH + HEADER_SIZE;
     }
-    
+
     public void append(long uuid) {
-        setSize((1 + valueCount) * PositionWritable.LENGTH);
-        Marshal.putLong(uuid, storage, offset + valueCount * PositionWritable.LENGTH);
+        setSize((1 + valueCount) * PositionWritable.LENGTH + HEADER_SIZE);
+        Marshal.putLong(uuid, storage, offset + valueCount * PositionWritable.LENGTH + HEADER_SIZE);
         valueCount += 1;
+        Marshal.putInt(valueCount, storage, offset);
     }
-    
-    public void append(byte mateId, long readId, int posId){
+
+    public void append(byte mateId, long readId, int posId) {
         append(PositionWritable.makeUUID(mateId, readId, posId));
     }
-    
+
     public void append(PositionWritable pos) {
-        if(pos != null)
+        if (pos != null)
             append(pos.getUUID());
         else
             throw new RuntimeException("This position is null pointer!");
     }
-    
+
     /*
      * Append the otherList to the end of myList
      */
     public void appendList(PositionListWritable otherList) {
         if (otherList.valueCount > 0) {
-            setSize((valueCount + otherList.valueCount) * PositionWritable.LENGTH);
+            setSize((valueCount + otherList.valueCount) * PositionWritable.LENGTH + HEADER_SIZE);
             // copy contents of otherList into the end of my storage
-            System.arraycopy(otherList.storage, otherList.offset,
-                    storage, offset + valueCount * PositionWritable.LENGTH, 
-                    otherList.valueCount * PositionWritable.LENGTH);
+            System.arraycopy(otherList.storage, otherList.offset + HEADER_SIZE, storage, offset + valueCount
+                    * PositionWritable.LENGTH + HEADER_SIZE, otherList.valueCount * PositionWritable.LENGTH);
             valueCount += otherList.valueCount;
+            Marshal.putInt(valueCount, storage, offset);
         }
     }
-    
+
     /**
      * Save the union of my list and otherList. Uses a temporary HashSet for
      * uniquefication
      */
     public void unionUpdate(PositionListWritable otherList) {
         int newSize = valueCount + otherList.valueCount;
-        HashSet<PositionWritable> uniqueElements = new HashSet<PositionWritable>(
-                newSize);
+        HashSet<PositionWritable> uniqueElements = new HashSet<PositionWritable>(newSize);
         for (PositionWritable pos : this) {
             uniqueElements.add(pos);
         }
@@ -92,71 +98,75 @@
             uniqueElements.add(pos);
         }
         valueCount = 0;
-        setSize(newSize);
+        setSize(newSize * PositionWritable.LENGTH + HEADER_SIZE);
         for (PositionWritable pos : uniqueElements) {
             append(pos);
         }
     }
-    
+
     public static int getCountByDataLength(int length) {
         if (length % PositionWritable.LENGTH != 0) {
             throw new IllegalArgumentException("Length of positionlist is invalid");
         }
         return length / PositionWritable.LENGTH;
     }
-    
+
     public void set(PositionListWritable otherList) {
-        set(otherList.valueCount, otherList.storage, otherList.offset);
+        set(otherList.storage, otherList.offset);
     }
 
-    public void set(int valueCount, byte[] newData, int offset) {
-        this.valueCount = valueCount;
-        setSize(valueCount * PositionWritable.LENGTH);
-        if (valueCount > 0) {
-            System.arraycopy(newData, offset, storage, this.offset, valueCount * PositionWritable.LENGTH);
+    public void set(byte[] newData, int newOffset) {
+        int newValueCount = Marshal.getInt(newData, newOffset);
+        setSize(newValueCount * PositionWritable.LENGTH + HEADER_SIZE);
+        if (newValueCount > 0) {
+            System.arraycopy(newData, newOffset + HEADER_SIZE, storage, this.offset + HEADER_SIZE, newValueCount * PositionWritable.LENGTH);
         }
+        valueCount = newValueCount;
+        Marshal.putInt(valueCount, storage, this.offset);
     }
 
     public void reset() {
         valueCount = 0;
+        Marshal.putInt(valueCount, storage, offset);
     }
-    
+
     protected void setSize(int size) {
         if (size > getCapacity()) {
             setCapacity((size * 3 / 2));
         }
     }
-    
+
     protected int getCapacity() {
-        return storage.length - offset;
+        return maxStorageSize - offset;
     }
 
     protected void setCapacity(int new_cap) {
         if (new_cap > getCapacity()) {
             byte[] new_data = new byte[new_cap];
-            if (storage.length - offset > 0) {
-                System.arraycopy(storage, offset, new_data, 0, storage.length - offset);
+            if (valueCount > 0) {
+                System.arraycopy(storage, offset, new_data, 0, valueCount * PositionWritable.LENGTH + HEADER_SIZE);
             }
             storage = new_data;
             offset = 0;
+            maxStorageSize = storage.length;
         }
     }
-    
+
     public PositionWritable getPosition(int i) {
         if (i >= valueCount) {
             throw new ArrayIndexOutOfBoundsException("No such positions");
         }
-        posIter.setNewReference(storage, offset + i * PositionWritable.LENGTH);
+        posIter.setNewReference(storage, offset + i * PositionWritable.LENGTH + HEADER_SIZE);
         return posIter;
     }
-    
+
     public void resetPosition(int i, long uuid) {
         if (i >= valueCount) {
             throw new ArrayIndexOutOfBoundsException("No such positions");
         }
-        Marshal.putLong(uuid, storage, offset + i * PositionWritable.LENGTH);
+        Marshal.putLong(uuid, storage, offset + i * PositionWritable.LENGTH + HEADER_SIZE);
     }
-    
+
     public int getCountOfPosition() {
         return valueCount;
     }
@@ -170,9 +180,9 @@
     }
 
     public int getLength() {
-        return valueCount * PositionWritable.LENGTH;
+        return valueCount * PositionWritable.LENGTH + HEADER_SIZE;
     }
-    
+
     @Override
     public Iterator<PositionWritable> iterator() {
         Iterator<PositionWritable> it = new Iterator<PositionWritable>() {
@@ -191,50 +201,54 @@
 
             @Override
             public void remove() {
-                if(currentIndex < valueCount)
-                    System.arraycopy(storage, offset + currentIndex * PositionWritable.LENGTH, 
-                          storage, offset + (currentIndex - 1) * PositionWritable.LENGTH, 
-                          (valueCount - currentIndex) * PositionWritable.LENGTH);
+                if (currentIndex < valueCount)
+                    System.arraycopy(storage, offset + currentIndex * PositionWritable.LENGTH + HEADER_SIZE, storage, offset
+                            + (currentIndex - 1) * PositionWritable.LENGTH + HEADER_SIZE, (valueCount - currentIndex)
+                            * PositionWritable.LENGTH);
                 valueCount--;
                 currentIndex--;
+                Marshal.putInt(valueCount, storage, offset);
             }
         };
         return it;
     }
-    
+
     /*
      * remove the first instance of @toRemove. Uses a linear scan.  Throws an exception if not in this list.
      */
     public void remove(PositionWritable toRemove, boolean ignoreMissing) {
         Iterator<PositionWritable> posIterator = this.iterator();
         while (posIterator.hasNext()) {
-            if(toRemove.equals(posIterator.next())) {
+            if (toRemove.equals(posIterator.next())) {
                 posIterator.remove();
-                return;
+                return;  // found it. return early. 
             }
         }
+        // element not found.
         if (!ignoreMissing) {
-        	throw new ArrayIndexOutOfBoundsException("the PositionWritable `" + toRemove.toString() + "` was not found in this list.");
+            throw new ArrayIndexOutOfBoundsException("the PositionWritable `" + toRemove.toString()
+                    + "` was not found in this list.");
         }
     }
-    
+
     public void remove(PositionWritable toRemove) {
-    	remove(toRemove, false);
+        remove(toRemove, false);
     }
-    
+
     @Override
     public void write(DataOutput out) throws IOException {
         out.writeInt(valueCount);
-        out.write(storage, offset, valueCount * PositionWritable.LENGTH);
+        out.write(storage, offset + HEADER_SIZE, valueCount * PositionWritable.LENGTH);
     }
-    
+
     @Override
     public void readFields(DataInput in) throws IOException {
         this.valueCount = in.readInt();
-        setSize(valueCount * PositionWritable.LENGTH);
-        in.readFully(storage, offset, valueCount * PositionWritable.LENGTH);
+        setSize(valueCount * PositionWritable.LENGTH + HEADER_SIZE);
+        in.readFully(storage, offset + HEADER_SIZE, valueCount * PositionWritable.LENGTH);
+        Marshal.putInt(valueCount, storage, offset);
     }
-    
+
     @Override
     public String toString() {
         StringBuilder sbuilder = new StringBuilder();
@@ -250,12 +264,12 @@
         }
         return sbuilder.toString();
     }
-    
+
     @Override
     public int hashCode() {
         return Marshal.hashBytes(getByteArray(), getStartOffset(), getLength());
     }
-    
+
     @Override
     public boolean equals(Object o) {
         if (!(o instanceof PositionListWritable))
@@ -263,9 +277,9 @@
         PositionListWritable other = (PositionListWritable) o;
         if (this.valueCount != other.valueCount)
             return false;
-        for (int i=0; i < this.valueCount; i++) {
-                if (!this.getPosition(i).equals(other.getPosition(i)))
-                    return false;
+        for (int i = 0; i < this.valueCount; i++) {
+            if (!this.getPosition(i).equals(other.getPosition(i)))
+                return false;
         }
         return true;
     }
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionWritable.java
index 1079677..03d66a6 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/PositionWritable.java
@@ -119,10 +119,10 @@
     }
     
     /*
-     * String of form "(readId-posID_mate)" where mate is _1 or _2
+     * String of form "(readId-posID_mate)" where mate is _0 or _1
      */
     @Override
     public String toString() {
-        return "(" + this.getReadId() + "-" + this.getPosId() + "_" + (this.getMateId() + 1) + ")";
+        return "(" + this.getReadId() + "-" + this.getPosId() + "_" + (this.getMateId()) + ")";
     }
 }
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerBytesWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerBytesWritable.java
index 7fed5c7..c38e35d 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerBytesWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerBytesWritable.java
@@ -18,255 +18,596 @@
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
+import java.io.Serializable;
 
+import org.apache.hadoop.io.BinaryComparable;
+import org.apache.hadoop.io.WritableComparable;
 import org.apache.hadoop.io.WritableComparator;
 
 import edu.uci.ics.genomix.data.KmerUtil;
 import edu.uci.ics.genomix.data.Marshal;
+import edu.uci.ics.genomix.oldtype.NodeWritable.DirectionFlag;
 
 /**
  * Variable-length kmer which stores its length internally.
- * 
  * Note: `offset` as used in this class is the offset at which the *kmer*
  * begins. There is a {@value HEADER_SIZE}-byte header preceding the kmer
  */
-public class VKmerBytesWritable extends KmerBytesWritable {
+public class VKmerBytesWritable extends BinaryComparable implements Serializable, WritableComparable<BinaryComparable> {
+    private static final long serialVersionUID = 1L;
+    protected static final byte[] EMPTY_BYTES = { 0, 0, 0, 0 }; // int indicating 0 length
+    protected static final int HEADER_SIZE = 4; // number of bytes for header info
 
-	private static final long serialVersionUID = 1L;
-	protected static final byte[] EMPTY_BYTES = { 0, 0, 0, 0 }; // int
-																// indicating 0
-																// length
-	protected static final int HEADER_SIZE = 4; // number of bytes for header
-												// info
+    protected int lettersInKmer;
+    protected int bytesUsed;
+    protected byte[] bytes;
+    protected int kmerStartOffset;
+    protected int storageMaxSize;  // since we may be a reference inside a larger datablock, we must track our maximum size
 
-	/**
-	 * Initialize as empty kmer
-	 */
-	public VKmerBytesWritable() {
-		this(EMPTY_BYTES, HEADER_SIZE);
-	}
+    /**
+     * Initialize as empty kmer
+     */
+    public VKmerBytesWritable() {
+        this(EMPTY_BYTES, 0);
+    }
 
-	/**
-	 * Copy contents of kmer string
-	 */
-	public VKmerBytesWritable(String kmer) {
-		bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(kmer.length())];
-		offset = HEADER_SIZE;
-		setAsCopy(kmer);
-	}
+    /**
+     * Copy contents of kmer string
+     */
+    public VKmerBytesWritable(String kmer) {
+        bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(kmer.length())];
+        kmerStartOffset = HEADER_SIZE;
+        storageMaxSize = bytes.length;
+        setAsCopy(kmer);
+    }
 
-	/**
-	 * Set as reference to given data
-	 * 
-	 * @param storage
-	 *            : byte array with header
-	 * @param offset
-	 */
-	public VKmerBytesWritable(byte[] storage, int offset) {
-		setAsReference(storage, offset);
-	}
+    /**
+     * Set as reference to given data
+     * 
+     * @param storage
+     *            : byte array with header
+     * @param offset
+     */
+    public VKmerBytesWritable(byte[] storage, int offset) {
+        setAsReference(storage, offset);
+    }
 
-	/**
-	 * Reserve space for k letters
-	 */
-	public VKmerBytesWritable(int k) {
-		if (k > 0) {
-			bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(k)];
-		} else {
-			bytes = EMPTY_BYTES;
-		}
-		offset = HEADER_SIZE;
-		setKmerLength(k);
-	}
+    /**
+     * Reserve space for k letters
+     */
+    public VKmerBytesWritable(int k) {
+        if (k > 0) {
+            bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(k)];
+        } else if (k == 0) {
+            bytes = EMPTY_BYTES;
+        } else {
+            throw new IllegalArgumentException("Invalid K (" + k + ").");
+        }
+        kmerStartOffset = HEADER_SIZE;
+        storageMaxSize = bytes.length;
+        setKmerLength(k);
+    }
 
-	/**
-	 * deep copy of kmer in other
-	 * 
-	 * @param other
-	 */
-	public VKmerBytesWritable(VKmerBytesWritable other) {
-		this(other.lettersInKmer);
-		setAsCopy(other);
-	}
+    /**
+     * deep copy of kmer in other
+     * 
+     * @param other
+     */
+    public VKmerBytesWritable(VKmerBytesWritable other) {
+        this(other.lettersInKmer);
+        setAsCopy(other);
+    }
 
-	/**
-	 * Deep copy of the given kmer
-	 * 
-	 * @param other
-	 */
-	@Override
-	public void setAsCopy(KmerBytesWritable other) {
-		reset(other.lettersInKmer);
-		if (lettersInKmer > 0) {
-			System.arraycopy(other.bytes, other.offset, bytes, this.offset,
-					bytesUsed);
-		}
-	}
+    /**
+     * Deep copy of the given kmer
+     * 
+     * @param other
+     */
+    public void setAsCopy(VKmerBytesWritable other) {
+        reset(other.lettersInKmer);
+        if (lettersInKmer > 0) {
+            System.arraycopy(other.bytes, other.kmerStartOffset, bytes, this.kmerStartOffset, bytesUsed);
+        }
+    }
 
-	/**
-	 * set from String kmer
-	 */
-	@Override
-	public void setAsCopy(String kmer) {
-		int k = kmer.length();
-		reset(k);
-		System.arraycopy(kmer.getBytes(), 0, bytes, offset, bytesUsed);
-	}
+    /**
+     * set from String kmer
+     */
+    public void setAsCopy(String kmer) {
+        int k = kmer.length();
+        reset(k);
+        System.arraycopy(kmer.getBytes(), 0, bytes, kmerStartOffset, bytesUsed);
+    }
 
-	/**
-	 * Deep copy of the given bytes data
-	 * 
-	 * @param newData
-	 *            : byte array to copy (should have a header)
-	 * @param offset
-	 */
-	public void setAsCopy(byte[] newData, int offset) {
-		int k = Marshal.getInt(newData, offset);
-		reset(k);
-		System.arraycopy(newData, offset + HEADER_SIZE, bytes, this.offset,
-				bytesUsed);
-	}
+    /**
+     * Deep copy of the given bytes data
+     * 
+     * @param newData
+     *            : byte array to copy (should have a header)
+     * @param offset
+     */
+    public void setAsCopy(byte[] newData, int offset) {
+        int k = Marshal.getInt(newData, offset);
+        reset(k);
+        System.arraycopy(newData, offset + HEADER_SIZE, bytes, this.kmerStartOffset, bytesUsed);
+    }
 
-	/**
-	 * Point this datablock to the given bytes array It works like the pointer
-	 * to new datablock.
-	 * 
-	 * @param newData
-	 *            : byte array to copy (should have a header)
-	 * @param blockOffset
-	 */
-	public void setAsReference(byte[] newData, int blockOffset) {
-		this.bytes = newData;
-		this.offset = blockOffset + HEADER_SIZE;
-		int kRequested = Marshal.getInt(newData, blockOffset);
-		int bytesRequested = KmerUtil.getByteNumFromK(kRequested) + HEADER_SIZE;
-		if (newData.length - blockOffset < bytesRequested) {
-			throw new IllegalArgumentException("Requested " + bytesRequested
-					+ " bytes (k=" + kRequested + ") but buffer has only "
-					+ (newData.length - blockOffset) + " bytes");
-		}
-		setKmerLength(kRequested);
-	}
+    /**
+     * Point this datablock to the given bytes array It works like the pointer
+     * to new datablock.
+     * 
+     * @param newData
+     *            : byte array to copy (should have a header)
+     * @param blockOffset
+     */
+    public void setAsReference(byte[] newData, int blockOffset) {
+        bytes = newData;
+        kmerStartOffset = blockOffset + HEADER_SIZE;
+        int kRequested = Marshal.getInt(newData, blockOffset);
+        int bytesRequested = KmerUtil.getByteNumFromK(kRequested) + HEADER_SIZE;
+        if (newData.length - blockOffset < bytesRequested) {
+            throw new IllegalArgumentException("Requested " + bytesRequested + " bytes (k=" + kRequested
+                    + ") but buffer has only " + (newData.length - blockOffset) + " bytes");
+        }
+        storageMaxSize = bytesRequested;  // since we are a reference, store our max capacity
+        setKmerLength(kRequested);
+    }
 
-	@Override
-	public void setKmerLength(int k) {
-		this.bytesUsed = KmerUtil.getByteNumFromK(k);
-		this.lettersInKmer = k;
-		Marshal.putInt(k, bytes, offset - HEADER_SIZE);
-	}
+    /**
+     * Reset array by kmerlength
+     * 
+     * @param k
+     */
+    public void reset(int k) {
+        int newByteLength = KmerUtil.getByteNumFromK(k);
+        if (bytesUsed < newByteLength) {
+            bytes = new byte[newByteLength + HEADER_SIZE];
+            kmerStartOffset = HEADER_SIZE;
+            storageMaxSize = bytes.length;
+        }
+        setKmerLength(k);
+    }
 
-	@Override
-	protected int getCapacity() {
-		return bytes.length - HEADER_SIZE;
-	}
+    protected void clearLeadBit() {
+        if (lettersInKmer % 4 != 0) {
+            bytes[kmerStartOffset] &= (1 << ((lettersInKmer % 4) << 1)) - 1;
+        }
+    }
 
-	@Override
-	protected void setCapacity(int new_cap) {
-		if (new_cap != getCapacity()) {
-			byte[] new_data = new byte[new_cap + HEADER_SIZE];
-			if (new_cap < bytesUsed) {
-				bytesUsed = new_cap;
-			}
-			if (bytesUsed != 0) {
-				System.arraycopy(bytes, offset, new_data, HEADER_SIZE,
-						bytesUsed);
-			}
-			bytes = new_data;
-			offset = HEADER_SIZE;
-		}
-	}
+    /**
+     * Get one genecode (A|G|C|T) from the given kmer index e.g. Get the 4th
+     * gene of the kmer ACGTA will return T
+     * 
+     * @param pos
+     * @return
+     */
+    public byte getGeneCodeAtPosition(int pos) {
+        if (pos >= lettersInKmer || pos < 0) {
+            throw new ArrayIndexOutOfBoundsException("Gene position (" + pos + ") out of bounds for k=" + lettersInKmer);
+        }
+        return geneCodeAtPosition(pos);
+    }
 
-	@Override
-	public void mergeWithFFKmer(int initialKmerSize, KmerBytesWritable kmer) {
-		super.mergeWithFFKmer(initialKmerSize, kmer);
-		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
-	}
+    /**
+     * unchecked version of getGeneCodeAtPosition. Used when kmerlength is
+     * inaccurate (mid-merge)
+     */
+    private byte geneCodeAtPosition(int pos) {
+        int posByte = pos / 4;
+        int shift = (pos % 4) << 1;
+        return (byte) ((bytes[kmerStartOffset + bytesUsed - 1 - posByte] >> shift) & 0x3);
+    }
 
-	@Override
-	public void mergeWithFRKmer(int initialKmerSize, KmerBytesWritable kmer) {
-		super.mergeWithFRKmer(initialKmerSize, kmer);
-		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
-	}
+    /**
+     * Shift Kmer to accept new char input
+     * 
+     * @param c
+     *            Input new gene character
+     * @return the shift out gene, in gene code format
+     */
+    public byte shiftKmerWithNextChar(byte c) {
+        return shiftKmerWithNextCode(GeneCode.getCodeFromSymbol(c));
+    }
 
-	@Override
-	public void mergeWithRFKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-		super.mergeWithRFKmer(initialKmerSize, preKmer);
-		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
-	}
+    /**
+     * Shift Kmer to accept new gene code
+     * 
+     * @param c
+     *            Input new gene code
+     * @return the shift out gene, in gene code format
+     */
+    public byte shiftKmerWithNextCode(byte c) {
+        byte output = (byte) (bytes[kmerStartOffset + bytesUsed - 1] & 0x03);
+        for (int i = bytesUsed - 1; i > 0; i--) {
+            byte in = (byte) (bytes[kmerStartOffset + i - 1] & 0x03);
+            bytes[kmerStartOffset + i] = (byte) (((bytes[kmerStartOffset + i] >>> 2) & 0x3f) | (in << 6));
+        }
+        int pos = ((lettersInKmer - 1) % 4) << 1;
+        byte code = (byte) (c << pos);
+        bytes[kmerStartOffset] = (byte) (((bytes[kmerStartOffset] >>> 2) & 0x3f) | code);
+        clearLeadBit();
+        return output;
+    }
 
-	@Override
-	public void mergeWithRRKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-		super.mergeWithRRKmer(initialKmerSize, preKmer);
-		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
-	}
+    /**
+     * Shift Kmer to accept new input char
+     * 
+     * @param c
+     *            Input new gene character
+     * @return the shiftout gene, in gene code format
+     */
+    public byte shiftKmerWithPreChar(byte c) {
+        return shiftKmerWithPreCode(GeneCode.getCodeFromSymbol(c));
+    }
 
-	@Override
-	public void readFields(DataInput in) throws IOException {
-		lettersInKmer = in.readInt();
-		bytesUsed = KmerUtil.getByteNumFromK(lettersInKmer);
-		if (lettersInKmer > 0) {
-			if (getCapacity() < this.bytesUsed) {
-				this.bytes = new byte[this.bytesUsed + HEADER_SIZE];
-				this.offset = HEADER_SIZE;
-			}
-			in.readFully(bytes, offset, bytesUsed);
-		}
-		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
-	}
+    /**
+     * Shift Kmer to accept new gene code
+     * 
+     * @param c
+     *            Input new gene code
+     * @return the shiftout gene, in gene code format
+     */
+    public byte shiftKmerWithPreCode(byte c) {
+        int pos = ((lettersInKmer - 1) % 4) << 1;
+        byte output = (byte) ((bytes[kmerStartOffset] >> pos) & 0x03);
+        for (int i = 0; i < bytesUsed - 1; i++) {
+            byte in = (byte) ((bytes[kmerStartOffset + i + 1] >> 6) & 0x03);
+            bytes[kmerStartOffset + i] = (byte) ((bytes[kmerStartOffset + i] << 2) | in);
+        }
+        bytes[kmerStartOffset + bytesUsed - 1] = (byte) ((bytes[kmerStartOffset + bytesUsed - 1] << 2) | c);
+        clearLeadBit();
+        return output;
+    }
 
-	/**
-	 * write the entire byte array including the header
-	 */
-	@Override
-	public void write(DataOutput out) throws IOException {
-		out.write(bytes, offset - HEADER_SIZE, bytesUsed + HEADER_SIZE);
-	}
+    public int getKmerLetterLength() {
+        return lettersInKmer;
+    }
 
-	@Override
-	public boolean equals(Object right) {
-		if (right instanceof VKmerBytesWritable) {
-			return super.equals(right); // compare bytes directly
-		} else if (right instanceof KmerBytesWritable) {
-			// for Kmers, we need to skip our header
-			KmerBytesWritable rightKmer = (KmerBytesWritable) right;
-			if (lettersInKmer != rightKmer.lettersInKmer) { // check length
-				return false;
-			}
-			for (int i = 0; i < lettersInKmer; i++) { // check letters
-				if (bytes[i + HEADER_SIZE] != rightKmer.bytes[i]) {
-					return false;
-				}
-			}
-			return true;
-		}
-		return false;
-	}
+    @Override
+    public byte[] getBytes() {
+        return bytes;
+    }
 
-	@Override
-	public String toString() {
-		return KmerUtil.recoverKmerFrom(this.lettersInKmer, this.getBytes(),
-				offset, this.getLength());
-	}
+    /**
+     * Return the (hyracks-specific) data block offset. This includes the header.
+     */
+    public int getBlockOffset() {
+        return kmerStartOffset - HEADER_SIZE;
+    }
 
-	public static class Comparator extends WritableComparator {
+    /**
+     * Return the data block offset where the kmer data begins. This excludes the header.
+     */
+    public int getKmerOffset() {
+        return kmerStartOffset;
+    }
 
-		public Comparator() {
-			super(VKmerBytesWritable.class);
-		}
+    /**
+     * Return the number of bytes used by both header and kmer chain
+     */
+    @Override
+    public int getLength() {
+        return bytesUsed + HEADER_SIZE;
+    }
+    
+    /**
+     * Return the number of bytes used by the kmer chain
+     */
+    public int getKmerByteLength() {
+        return bytesUsed;
+    }
+    
 
-		public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
-			int kmerlength1 = Marshal.getInt(b1, s1);
-			int kmerlength2 = Marshal.getInt(b2, s2);
-			if (kmerlength1 == kmerlength2) {
-				return compareBytes(b1, s1 + HEADER_SIZE, l1 - HEADER_SIZE, b2,
-						s2 + HEADER_SIZE, l2 - HEADER_SIZE);
-			}
-			return kmerlength1 - kmerlength2;
-		}
-	}
+    public void setKmerLength(int k) {
+        this.bytesUsed = KmerUtil.getByteNumFromK(k);
+        this.lettersInKmer = k;
+        saveHeader(k);
+    }
 
-	static { // register this comparator
-		WritableComparator.define(VKmerBytesWritable.class, new Comparator());
-	}
+    protected int getKmerByteCapacity() {
+        return storageMaxSize  - HEADER_SIZE;
+    }
+
+    protected void setKmerByteCapacity(int new_cap) {
+        if (new_cap != getKmerByteCapacity()) {
+            byte[] new_data = new byte[new_cap + HEADER_SIZE];
+            if (new_cap < bytesUsed) {
+                bytesUsed = new_cap;
+            }
+            if (bytesUsed != 0) {
+                System.arraycopy(bytes, kmerStartOffset, new_data, HEADER_SIZE, bytesUsed);
+            }
+            bytes = new_data;
+            kmerStartOffset = HEADER_SIZE;
+            storageMaxSize = bytes.length;
+        }
+    }
+
+    private void saveHeader(int length) {
+        Marshal.putInt(length, bytes, kmerStartOffset - HEADER_SIZE);
+    }
+
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        lettersInKmer = in.readInt();
+        bytesUsed = KmerUtil.getByteNumFromK(lettersInKmer);
+        if (lettersInKmer > 0) {
+            if (getKmerByteCapacity() < this.bytesUsed) {
+                this.bytes = new byte[this.bytesUsed + HEADER_SIZE];
+                this.kmerStartOffset = HEADER_SIZE;
+                storageMaxSize = bytes.length;
+            }
+            in.readFully(bytes, kmerStartOffset, bytesUsed);
+        }
+    }
+
+    /**
+     * write the entire byte array including the header
+     */
+    @Override
+    public void write(DataOutput out) throws IOException {
+        out.write(bytes, kmerStartOffset - HEADER_SIZE, bytesUsed + HEADER_SIZE);
+    }
+
+    @Override
+    public int hashCode() {
+        return Marshal.hashBytes(bytes, kmerStartOffset - HEADER_SIZE, bytesUsed + HEADER_SIZE);
+    }
+
+    @Override
+    public boolean equals(Object right_obj) {
+        if (right_obj instanceof VKmerBytesWritable) {
+            // since these may be backed by storage of different sizes, we have to manually check each byte, including the header
+            VKmerBytesWritable right = (VKmerBytesWritable) right_obj;
+            for (int i = -HEADER_SIZE; i < bytesUsed; i++) {
+                if (bytes[kmerStartOffset + i] != right.bytes[right.kmerStartOffset + i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return KmerUtil.recoverKmerFrom(this.lettersInKmer, bytes, kmerStartOffset, bytesUsed);
+    }
+
+    public static class Comparator extends WritableComparator {
+
+        public Comparator() {
+            super(VKmerBytesWritable.class);
+        }
+
+        public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+            int kmerlength1 = Marshal.getInt(b1, s1);
+            int kmerlength2 = Marshal.getInt(b2, s2);
+            if (kmerlength1 == kmerlength2) {
+                return compareBytes(b1, s1 + HEADER_SIZE, l1 - HEADER_SIZE, b2, s2 + HEADER_SIZE, l2 - HEADER_SIZE);
+            }
+            return kmerlength1 - kmerlength2;
+        }
+    }
+
+    static { // register this comparator
+        WritableComparator.define(VKmerBytesWritable.class, new Comparator());
+    }
+
+    /**
+     * Ensures that there is space for at least `size` bytes of kmer (not
+     * including any header)
+     */
+    protected void setSize(int size) {
+        if (size > getKmerByteCapacity()) {
+            setKmerByteCapacity((size * 3 / 2));
+        }
+        this.bytesUsed = size;
+    }
+
+    public void setByRead(int k, byte[] stringBytes, int start) {
+        reset(k);
+        setByRead(stringBytes, start);
+    }
+
+    /**
+     * Read Kmer from read text into bytes array e.g. AATAG will compress as
+     * [0x000G, 0xATAA]
+     * 
+     * @param stringBytes
+     * @param start
+     */
+    public void setByRead(byte[] stringBytes, int start) {
+        byte l = 0;
+        int bytecount = 0;
+        int bcount = this.bytesUsed - 1;
+        for (int i = start; i < start + lettersInKmer && i < stringBytes.length; i++) {
+            byte code = GeneCode.getCodeFromSymbol(stringBytes[i]);
+            l |= (byte) (code << bytecount);
+            bytecount += 2;
+            if (bytecount == 8) {
+                bytes[kmerStartOffset + bcount--] = l;
+                l = 0;
+                bytecount = 0;
+            }
+        }
+        if (bcount >= 0) {
+            bytes[kmerStartOffset] = l;
+        }
+    }
+
+    public void setByReadReverse(int k, byte[] stringBytes, int start) {
+        reset(k);
+        setByReadReverse(stringBytes, start);
+    }
+
+    /**
+     * Compress Reversed read into bytes array e.g. AATAG will paired to CTATT,
+     * and then compress as [0x000T,0xTATC]
+     * 
+     * @param input
+     *            array
+     * @param start
+     *            position
+     */
+    public void setByReadReverse(byte[] array, int start) {
+        byte l = 0;
+        int bytecount = 0;
+        int bcount = bytesUsed - 1;
+        // for (int i = start + kmerlength - 1; i >= 0 && i < array.length; i--)
+        // {
+        for (int i = start + lettersInKmer - 1; i >= start && i < array.length; i--) {
+            byte code = GeneCode.getPairedCodeFromSymbol(array[i]);
+            l |= (byte) (code << bytecount);
+            bytecount += 2;
+            if (bytecount == 8) {
+                bytes[kmerStartOffset + bcount--] = l;
+                l = 0;
+                bytecount = 0;
+            }
+        }
+        if (bcount >= 0) {
+            bytes[kmerStartOffset] = l;
+        }
+    }
+
+    /**
+     * Merge Kmer with the next connected Kmer e.g. AAGCTAA merge with AACAACC,
+     * if the initial kmerSize = 3 then it will return AAGCTAACAACC
+     * 
+     * @param initialKmerSize
+     *            : the initial kmerSize
+     * @param kmer
+     *            : the next kmer
+     */
+    public void mergeWithFFKmer(int initialKmerSize, VKmerBytesWritable kmer) {
+        int preKmerLength = lettersInKmer;
+        int preSize = bytesUsed;
+        lettersInKmer += kmer.lettersInKmer - initialKmerSize + 1;
+        setSize(KmerUtil.getByteNumFromK(lettersInKmer));
+        for (int i = 1; i <= preSize; i++) {
+            bytes[kmerStartOffset + bytesUsed - i] = bytes[kmerStartOffset + preSize - i];
+        }
+        for (int k = initialKmerSize - 1; k < kmer.getKmerLetterLength(); k += 4) {
+            byte onebyte = KmerBytesWritable.getOneByteFromKmerAtPosition(k, kmer.bytes, kmer.kmerStartOffset,
+                    kmer.bytesUsed);
+            KmerBytesWritable.appendOneByteAtPosition(preKmerLength + k - initialKmerSize + 1, onebyte, bytes,
+                    kmerStartOffset, bytesUsed);
+        }
+        clearLeadBit();
+        saveHeader(lettersInKmer);
+    }
+
+    /**
+     * Merge Kmer with the next connected Kmer, when that Kmer needs to be
+     * reverse-complemented e.g. AAGCTAA merge with GGTTGTT, if the initial
+     * kmerSize = 3 then it will return AAGCTAACAACC A merge B => A B~
+     * 
+     * @param initialKmerSize
+     *            : the initial kmerSize
+     * @param kmer
+     *            : the next kmer
+     */
+    public void mergeWithFRKmer(int initialKmerSize, VKmerBytesWritable kmer) {
+        int preSize = bytesUsed;
+        int preKmerLength = lettersInKmer;
+        lettersInKmer += kmer.lettersInKmer - initialKmerSize + 1;
+        setSize(KmerUtil.getByteNumFromK(lettersInKmer));
+        // copy prefix into right-side of buffer
+        for (int i = 1; i <= preSize; i++) {
+            bytes[kmerStartOffset + bytesUsed - i] = bytes[kmerStartOffset + preSize - i];
+        }
+
+        int bytecount = (preKmerLength % 4) * 2;
+        int bcount = bytesUsed - preSize - bytecount / 8; // may overlap
+                                                          // previous kmer
+        byte l = bcount == bytesUsed - preSize ? bytes[kmerStartOffset + bcount] : 0x00;
+        bytecount %= 8;
+        for (int i = kmer.lettersInKmer - initialKmerSize; i >= 0; i--) {
+            byte code = GeneCode.getPairedGeneCode(kmer.getGeneCodeAtPosition(i));
+            l |= (byte) (code << bytecount);
+            bytecount += 2;
+            if (bytecount == 8) {
+                bytes[kmerStartOffset + bcount--] = l;
+                l = 0;
+                bytecount = 0;
+            }
+        }
+        if (bcount >= 0) {
+            bytes[kmerStartOffset] = l;
+        }
+        saveHeader(lettersInKmer);
+    }
+
+    /**
+     * Merge Kmer with the previous connected Kmer, when that kmer needs to be
+     * reverse-complemented e.g. AACAACC merge with TTCTGCC, if the initial
+     * kmerSize = 3 then it will return GGCAGAACAACC
+     * 
+     * @param initialKmerSize
+     *            : the initial kmerSize
+     * @param preKmer
+     *            : the previous kmer
+     */
+    public void mergeWithRFKmer(int initialKmerSize, VKmerBytesWritable preKmer) {
+        VKmerBytesWritable reversed = new VKmerBytesWritable(preKmer.lettersInKmer);
+        reversed.setByReadReverse(preKmer.toString().getBytes(), 0);
+        mergeWithRRKmer(initialKmerSize, reversed);
+    }
+
+    /**
+     * Merge Kmer with the previous connected Kmer e.g. AACAACC merge with
+     * AAGCTAA, if the initial kmerSize = 3 then it will return AAGCTAACAACC
+     * 
+     * @param initialKmerSize
+     *            : the initial kmerSize
+     * @param preKmer
+     *            : the previous kmer
+     */
+    public void mergeWithRRKmer(int initialKmerSize, VKmerBytesWritable preKmer) {
+        int preKmerLength = lettersInKmer;
+        int preSize = bytesUsed;
+        lettersInKmer += preKmer.lettersInKmer - initialKmerSize + 1;
+        setSize(KmerUtil.getByteNumFromK(lettersInKmer));
+        byte cacheByte = KmerBytesWritable.getOneByteFromKmerAtPosition(0, bytes, kmerStartOffset, preSize);
+
+        // copy prekmer
+        for (int k = 0; k < preKmer.lettersInKmer - initialKmerSize + 1; k += 4) {
+            byte onebyte = KmerBytesWritable.getOneByteFromKmerAtPosition(k, preKmer.bytes, preKmer.kmerStartOffset,
+                    preKmer.bytesUsed);
+            KmerBytesWritable.appendOneByteAtPosition(k, onebyte, bytes, kmerStartOffset, bytesUsed);
+        }
+
+        // copy current kmer
+        int k = 4;
+        for (; k < preKmerLength; k += 4) {
+            byte onebyte = KmerBytesWritable.getOneByteFromKmerAtPosition(k, bytes, kmerStartOffset, preSize);
+            KmerBytesWritable.appendOneByteAtPosition(preKmer.lettersInKmer - initialKmerSize + k - 4 + 1, cacheByte,
+                    bytes, kmerStartOffset, bytesUsed);
+            cacheByte = onebyte;
+        }
+        KmerBytesWritable.appendOneByteAtPosition(preKmer.lettersInKmer - initialKmerSize + k - 4 + 1, cacheByte,
+                bytes, kmerStartOffset, bytesUsed);
+        clearLeadBit();
+    }
+
+    public void mergeWithKmerInDir(byte dir, int initialKmerSize, VKmerBytesWritable kmer) {
+        switch (dir & DirectionFlag.DIR_MASK) {
+            case DirectionFlag.DIR_FF:
+                mergeWithFFKmer(initialKmerSize, kmer);
+                break;
+            case DirectionFlag.DIR_FR:
+                mergeWithFRKmer(initialKmerSize, kmer);
+                break;
+            case DirectionFlag.DIR_RF:
+                mergeWithRFKmer(initialKmerSize, kmer);
+                break;
+            case DirectionFlag.DIR_RR:
+                mergeWithRRKmer(initialKmerSize, kmer);
+                break;
+            default:
+                throw new RuntimeException("Direction not recognized: " + dir);
+        }
+    }
 
 }
diff --git a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableFactoryTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableFactoryTest.java
index 1eb58c8..663d8dd 100644
--- a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableFactoryTest.java
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableFactoryTest.java
@@ -19,8 +19,8 @@
 import org.junit.Test;
 
 import edu.uci.ics.genomix.type.GeneCode;
-import edu.uci.ics.genomix.type.KmerBytesWritable;
 import edu.uci.ics.genomix.type.KmerBytesWritableFactory;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
 
 public class KmerBytesWritableFactoryTest {
     static byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
@@ -29,17 +29,17 @@
 
     @Test
     public void TestGetLastKmer() {
-        KmerBytesWritable kmer = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer = new VKmerBytesWritable(9);
         kmer.setByRead(array, 0);
         Assert.assertEquals("AGCTGACCG", kmer.toString());
-        KmerBytesWritable lastKmer;
+        VKmerBytesWritable lastKmer;
         for (int i = 8; i > 0; i--) {
             lastKmer = kmerFactory.getLastKmerFromChain(i, kmer);
             Assert.assertEquals("AGCTGACCG".substring(9 - i), lastKmer.toString());
             lastKmer = kmerFactory.getSubKmerFromChain(9 - i, i, kmer);
             Assert.assertEquals("AGCTGACCG".substring(9 - i), lastKmer.toString());
         }
-        KmerBytesWritable vlastKmer;
+        VKmerBytesWritable vlastKmer;
         for (int i = 8; i > 0; i--) {
             vlastKmer = kmerFactory.getLastKmerFromChain(i, kmer);
             Assert.assertEquals("AGCTGACCG".substring(9 - i), vlastKmer.toString());
@@ -50,17 +50,17 @@
 
     @Test
     public void TestGetFirstKmer() {
-        KmerBytesWritable kmer = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer = new VKmerBytesWritable(9);
         kmer.setByRead(array, 0);
         Assert.assertEquals("AGCTGACCG", kmer.toString());
-        KmerBytesWritable firstKmer;
+        VKmerBytesWritable firstKmer;
         for (int i = 8; i > 0; i--) {
             firstKmer = kmerFactory.getFirstKmerFromChain(i, kmer);
             Assert.assertEquals("AGCTGACCG".substring(0, i), firstKmer.toString());
             firstKmer = kmerFactory.getSubKmerFromChain(0, i, kmer);
             Assert.assertEquals("AGCTGACCG".substring(0, i), firstKmer.toString());
         }
-        KmerBytesWritable vfirstKmer;
+        VKmerBytesWritable vfirstKmer;
         for (int i = 8; i > 0; i--) {
             vfirstKmer = kmerFactory.getFirstKmerFromChain(i, kmer);
             Assert.assertEquals("AGCTGACCG".substring(0, i), vfirstKmer.toString());
@@ -71,12 +71,12 @@
 
     @Test
     public void TestGetSubKmer() {
-        KmerBytesWritable kmer = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer = new VKmerBytesWritable(9);
         kmer.setByRead(array, 0);
         Assert.assertEquals("AGCTGACCG", kmer.toString());
-        KmerBytesWritable subKmer;
-        for (int istart = 0; istart < kmer.getKmerLength() - 1; istart++) {
-            for (int isize = 1; isize + istart <= kmer.getKmerLength(); isize++) {
+        VKmerBytesWritable subKmer;
+        for (int istart = 0; istart < kmer.getKmerLetterLength() - 1; istart++) {
+            for (int isize = 1; isize + istart <= kmer.getKmerLetterLength(); isize++) {
                 subKmer = kmerFactory.getSubKmerFromChain(istart, isize, kmer);
                 Assert.assertEquals("AGCTGACCG".substring(istart, istart + isize), subKmer.toString());
             }
@@ -85,60 +85,60 @@
 
     @Test
     public void TestMergeNext() {
-        KmerBytesWritable kmer = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer = new VKmerBytesWritable(9);
         kmer.setByRead(array, 0);
         Assert.assertEquals("AGCTGACCG", kmer.toString());
 
         String text = "AGCTGACCG";
         for (byte x = GeneCode.A; x <= GeneCode.T; x++) {
-            KmerBytesWritable newkmer = kmerFactory.mergeKmerWithNextCode(kmer, x);
+            VKmerBytesWritable newkmer = kmerFactory.mergeKmerWithNextCode(kmer, x);
             text = text + (char) GeneCode.GENE_SYMBOL[x];
             Assert.assertEquals(text, newkmer.toString());
-            kmer = new KmerBytesWritable(newkmer);
+            kmer = new VKmerBytesWritable(newkmer);
         }
         for (byte x = GeneCode.A; x <= GeneCode.T; x++) {
-            KmerBytesWritable newkmer = kmerFactory.mergeKmerWithNextCode(kmer, x);
+            VKmerBytesWritable newkmer = kmerFactory.mergeKmerWithNextCode(kmer, x);
             text = text + (char) GeneCode.GENE_SYMBOL[x];
             Assert.assertEquals(text, newkmer.toString());
-            kmer = new KmerBytesWritable(newkmer);
+            kmer = new VKmerBytesWritable(newkmer);
         }
     }
 
     @Test
     public void TestMergePre() {
-        KmerBytesWritable kmer = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer = new VKmerBytesWritable(9);
         kmer.setByRead(array, 0);
         Assert.assertEquals("AGCTGACCG", kmer.toString());
         String text = "AGCTGACCG";
         for (byte x = GeneCode.A; x <= GeneCode.T; x++) {
-            KmerBytesWritable newkmer = kmerFactory.mergeKmerWithPreCode(kmer, x);
+            VKmerBytesWritable newkmer = kmerFactory.mergeKmerWithPreCode(kmer, x);
             text = (char) GeneCode.GENE_SYMBOL[x] + text;
             Assert.assertEquals(text, newkmer.toString());
-            kmer = new KmerBytesWritable(newkmer);
+            kmer = new VKmerBytesWritable(newkmer);
         }
         for (byte x = GeneCode.A; x <= GeneCode.T; x++) {
-            KmerBytesWritable newkmer = kmerFactory.mergeKmerWithPreCode(kmer, x);
+            VKmerBytesWritable newkmer = kmerFactory.mergeKmerWithPreCode(kmer, x);
             text = (char) GeneCode.GENE_SYMBOL[x] + text;
             Assert.assertEquals(text, newkmer.toString());
-            kmer = new KmerBytesWritable(newkmer);
+            kmer = new VKmerBytesWritable(newkmer);
         }
     }
 
     @Test
     public void TestMergeTwoKmer() {
-        KmerBytesWritable kmer1 = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer1 = new VKmerBytesWritable(9);
         kmer1.setByRead(array, 0);
         String text1 = "AGCTGACCG";
-        KmerBytesWritable kmer2 = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer2 = new VKmerBytesWritable(9);
         kmer2.setByRead(array, 1);
         String text2 = "GCTGACCGT";
         Assert.assertEquals(text1, kmer1.toString());
         Assert.assertEquals(text2, kmer2.toString());
 
-        KmerBytesWritable merged = kmerFactory.mergeTwoKmer(kmer1, kmer2);
+        VKmerBytesWritable merged = kmerFactory.mergeTwoKmer(kmer1, kmer2);
         Assert.assertEquals(text1 + text2, merged.toString());
 
-        KmerBytesWritable kmer3 = new KmerBytesWritable(3);
+        VKmerBytesWritable kmer3 = new VKmerBytesWritable(3);
         kmer3.setByRead(array, 1);
         String text3 = "GCT";
         Assert.assertEquals(text3, kmer3.toString());
@@ -148,17 +148,17 @@
         merged = kmerFactory.mergeTwoKmer(kmer3, kmer1);
         Assert.assertEquals(text3 + text1, merged.toString());
 
-        KmerBytesWritable kmer4 = new KmerBytesWritable(8);
+        VKmerBytesWritable kmer4 = new VKmerBytesWritable(8);
         kmer4.setByRead(array, 0);
         String text4 = "AGCTGACC";
         Assert.assertEquals(text4, kmer4.toString());
         merged = kmerFactory.mergeTwoKmer(kmer4, kmer3);
         Assert.assertEquals(text4 + text3, merged.toString());
 
-        KmerBytesWritable kmer5 = new KmerBytesWritable(7);
+        VKmerBytesWritable kmer5 = new VKmerBytesWritable(7);
         kmer5.setByRead(array, 0);
         String text5 = "AGCTGAC";
-        KmerBytesWritable kmer6 = new KmerBytesWritable(9);
+        VKmerBytesWritable kmer6 = new VKmerBytesWritable(9);
         kmer6.setByRead(9, array, 1);
         String text6 = "GCTGACCGT";
         merged = kmerFactory.mergeTwoKmer(kmer5, kmer6);
@@ -173,19 +173,18 @@
         String text8 = "GCTG";
         merged = kmerFactory.mergeTwoKmer(kmer5, kmer6);
         Assert.assertEquals(text5 + text8, merged.toString());
-
     }
 
     @Test
     public void TestShift() {
-        KmerBytesWritable kmer = new KmerBytesWritable(kmerFactory.getKmerByRead(9, array, 0));
+        VKmerBytesWritable kmer = new VKmerBytesWritable(kmerFactory.getKmerByRead(9, array, 0));
         String text = "AGCTGACCG";
         Assert.assertEquals(text, kmer.toString());
 
-        KmerBytesWritable kmerForward = kmerFactory.shiftKmerWithNextCode(kmer, GeneCode.A);
+        VKmerBytesWritable kmerForward = kmerFactory.shiftKmerWithNextCode(kmer, GeneCode.A);
         Assert.assertEquals(text, kmer.toString());
         Assert.assertEquals("GCTGACCGA", kmerForward.toString());
-        KmerBytesWritable kmerBackward = kmerFactory.shiftKmerWithPreCode(kmer, GeneCode.C);
+        VKmerBytesWritable kmerBackward = kmerFactory.shiftKmerWithPreCode(kmer, GeneCode.C);
         Assert.assertEquals(text, kmer.toString());
         Assert.assertEquals("CAGCTGACC", kmerBackward.toString());
 
@@ -193,10 +192,10 @@
 
     @Test
     public void TestReverseKmer() {
-        KmerBytesWritable kmer = new KmerBytesWritable(7);
+        VKmerBytesWritable kmer = new VKmerBytesWritable(7);
         kmer.setByRead(array, 0);
         Assert.assertEquals(kmer.toString(), "AGCTGAC");
-        KmerBytesWritable reversed = kmerFactory.reverse(kmer);
+        VKmerBytesWritable reversed = kmerFactory.reverse(kmer);
         Assert.assertEquals(reversed.toString(), "CAGTCGA");
     }
 }
diff --git a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableTest.java
index 807ac13..54d29eb 100644
--- a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableTest.java
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerBytesWritableTest.java
@@ -28,7 +28,8 @@
 
     @Test
     public void TestCompressKmer() {
-        KmerBytesWritable kmer = new KmerBytesWritable(k);
+        KmerBytesWritable.setGlobalKmerLength(k);
+        KmerBytesWritable kmer = new KmerBytesWritable();
         kmer.setByRead(array, 0);
         Assert.assertEquals(kmer.toString(), "AATAGAA");
 
@@ -38,7 +39,8 @@
 
     @Test
     public void TestMoveKmer() {
-        KmerBytesWritable kmer = new KmerBytesWritable(k);
+        KmerBytesWritable.setGlobalKmerLength(k);
+        KmerBytesWritable kmer = new KmerBytesWritable();
         kmer.setByRead(array, 0);
         Assert.assertEquals(kmer.toString(), "AATAGAA");
 
@@ -54,7 +56,8 @@
 
     @Test
     public void TestCompressKmerReverse() {
-        KmerBytesWritable kmer = new KmerBytesWritable(k);
+        KmerBytesWritable.setGlobalKmerLength(k);
+        KmerBytesWritable kmer = new KmerBytesWritable();
         kmer.setByRead(array, 0);
         Assert.assertEquals(kmer.toString(), "AATAGAA");
 
@@ -64,7 +67,8 @@
 
     @Test
     public void TestMoveKmerReverse() {
-        KmerBytesWritable kmer = new KmerBytesWritable(k);
+        KmerBytesWritable.setGlobalKmerLength(k);
+        KmerBytesWritable kmer = new KmerBytesWritable();
         kmer.setByRead(array, 0);
         Assert.assertEquals(kmer.toString(), "AATAGAA");
 
@@ -80,7 +84,8 @@
 
     @Test
     public void TestGetGene() {
-        KmerBytesWritable kmer = new KmerBytesWritable(9);
+        KmerBytesWritable.setGlobalKmerLength(9);
+        KmerBytesWritable kmer = new KmerBytesWritable();
         String text = "AGCTGACCG";
         byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G' };
         kmer.setByRead(array, 0);
@@ -95,8 +100,9 @@
         byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
         String string = "AGCTGACCGT";
         for (int k = 3; k <= 10; k++) {
-            KmerBytesWritable kmer = new KmerBytesWritable(k);
-            KmerBytesWritable kmerAppend = new KmerBytesWritable(k);
+            KmerBytesWritable.setGlobalKmerLength(k);
+            KmerBytesWritable kmer = new KmerBytesWritable();
+            KmerBytesWritable kmerAppend = new KmerBytesWritable();
             kmer.setByRead(array, 0);
             Assert.assertEquals(string.substring(0, k), kmer.toString());
             for (int b = 0; b < k; b++) {
@@ -113,201 +119,4 @@
             Assert.assertEquals(kmer.toString(), kmerAppend.toString());
         }
     }
-
-    @Test
-    public void TestMergeFFKmer() {
-        byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
-        String text = "AGCTGACCGT";
-        KmerBytesWritable kmer1 = new KmerBytesWritable(8);
-        kmer1.setByRead(array, 0);
-        String text1 = "AGCTGACC";
-        KmerBytesWritable kmer2 = new KmerBytesWritable(8);
-        kmer2.setByRead(array, 1);
-        String text2 = "GCTGACCG";
-        Assert.assertEquals(text2, kmer2.toString());
-        KmerBytesWritable merge = new KmerBytesWritable(kmer1);
-        int kmerSize = 8;
-        merge.mergeWithFFKmer(kmerSize, kmer2);
-        Assert.assertEquals(text1 + text2.substring(kmerSize - 1), merge.toString());
-
-        for (int i = 1; i < 8; i++) {
-            merge.setAsCopy(kmer1);
-            merge.mergeWithFFKmer(i, kmer2);
-            Assert.assertEquals(text1 + text2.substring(i - 1), merge.toString());
-        }
-
-        for (int ik = 1; ik <= 10; ik++) {
-            for (int jk = 1; jk <= 10; jk++) {
-                kmer1 = new KmerBytesWritable(ik);
-                kmer2 = new KmerBytesWritable(jk);
-                kmer1.setByRead(array, 0);
-                kmer2.setByRead(array, 0);
-                text1 = text.substring(0, ik);
-                text2 = text.substring(0, jk);
-                Assert.assertEquals(text1, kmer1.toString());
-                Assert.assertEquals(text2, kmer2.toString());
-                for (int x = 1; x < jk; x++) {
-                    merge.setAsCopy(kmer1);
-                    merge.mergeWithFFKmer(x, kmer2);
-                    Assert.assertEquals(text1 + text2.substring(x - 1), merge.toString());
-                }
-            }
-        }
-    }
-    
-    @Test
-    public void TestMergeFRKmer() {
-        int kmerSize = 3;
-        String result = "AAGCTAACAACC";
-        byte[] resultArray = result.getBytes();
-        
-        String text1 = "AAGCTAA";
-        KmerBytesWritable kmer1 = new KmerBytesWritable(text1.length());
-        kmer1.setByRead(resultArray, 0);
-        Assert.assertEquals(text1, kmer1.toString());
-        
-        // kmer2 is the rc of the end of the read
-        String text2 = "GGTTGTT";
-        KmerBytesWritable kmer2 = new KmerBytesWritable(text2.length());
-        kmer2.setByReadReverse(resultArray, result.length() - text2.length());
-        Assert.assertEquals(text2, kmer2.toString());
-        
-        KmerBytesWritable merge = new KmerBytesWritable(kmer1);
-        merge.mergeWithFRKmer(kmerSize, kmer2);
-        Assert.assertEquals(result, merge.toString());
-        
-        int i = 1;
-        merge.setAsCopy(kmer1);
-        merge.mergeWithFRKmer(i, kmer2);
-        Assert.assertEquals("AAGCTAAAACAACC", merge.toString());
-        
-        i = 2;
-        merge.setAsCopy(kmer1);
-        merge.mergeWithFRKmer(i, kmer2);
-        Assert.assertEquals("AAGCTAAACAACC", merge.toString());
-        
-        i = 3;
-        merge.setAsCopy(kmer1);
-        merge.mergeWithFRKmer(i, kmer2);
-        Assert.assertEquals("AAGCTAACAACC", merge.toString());
-    }
-    
-    
-    @Test
-    public void TestMergeRFKmer() {
-        int kmerSize = 3;
-        String result = "GGCACAACAACCC";
-        byte[] resultArray = result.getBytes();
-        
-        String text1 = "AACAACCC";
-        KmerBytesWritable kmer1 = new KmerBytesWritable(text1.length());
-        kmer1.setByRead(resultArray, 5);
-        Assert.assertEquals(text1, kmer1.toString());
-        
-        // kmer2 is the rc of the end of the read
-        String text2 = "TTGTGCC";
-        KmerBytesWritable kmer2 = new KmerBytesWritable(text2.length());
-        kmer2.setByReadReverse(resultArray, 0);
-        Assert.assertEquals(text2, kmer2.toString());
-        
-        KmerBytesWritable merge = new KmerBytesWritable(kmer1);
-        merge.mergeWithRFKmer(kmerSize, kmer2);
-        Assert.assertEquals(result, merge.toString());
-        
-        int i = 1;
-        merge.setAsCopy(kmer1);
-        merge.mergeWithRFKmer(i, kmer2);
-        Assert.assertEquals("GGCACAAAACAACCC", merge.toString());
-        
-        i = 2;
-        merge.setAsCopy(kmer1);
-        merge.mergeWithRFKmer(i, kmer2);
-        Assert.assertEquals("GGCACAAACAACCC", merge.toString());
-        
-        i = 3;
-        merge.setAsCopy(kmer1);
-        merge.mergeWithRFKmer(i, kmer2);
-        Assert.assertEquals("GGCACAACAACCC", merge.toString());
-        
-//        String test1 = "CTTAT";
-//        String test2 = "AGACC";  // rc = GGTCT
-//        KmerBytesWritable k1 = new KmerBytesWritable(5);
-//        KmerBytesWritable k2 = new KmerBytesWritable(5);
-//        k1.setByRead(test1.getBytes(), 0);
-//        k2.setByRead(test2.getBytes(), 0);
-//        k1.mergeWithRFKmer(3, k2);
-//        Assert.assertEquals("GGTCTTAT", k1.toString());  //GGTCGTCT  -> AGACGACC ??
-        
-        String test3 = "CTA";
-        String test4 = "AGA";  // rc = TCT
-        KmerBytesWritable k3 = new KmerBytesWritable(3);
-        KmerBytesWritable k4 = new KmerBytesWritable(3);
-        k3.setByRead(test3.getBytes(), 0);
-        k4.setByRead(test4.getBytes(), 0);
-        k3.mergeWithRFKmer(3, k4);
-        Assert.assertEquals("TCTA", k3.toString());
-//        Assert.assertEquals("CTAT", k3);  // this is an incorrect test case-- the merge always flips the passed-in kmer
-    }
-    
-    
-
-    @Test
-    public void TestMergeRRKmer() {
-        byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
-        String text = "AGCTGACCGT";
-        KmerBytesWritable kmer1 = new KmerBytesWritable(8);
-        kmer1.setByRead(array, 0);
-        String text1 = "AGCTGACC";
-        KmerBytesWritable kmer2 = new KmerBytesWritable(8);
-        kmer2.setByRead(array, 1);
-        String text2 = "GCTGACCG";
-        Assert.assertEquals(text2, kmer2.toString());
-        KmerBytesWritable merge = new KmerBytesWritable(kmer2);
-        int kmerSize = 8;
-        merge.mergeWithRRKmer(kmerSize, kmer1);
-        Assert.assertEquals(text1 + text2.substring(kmerSize - 1), merge.toString());
-
-        for (int i = 1; i < 8; i++) {
-            merge.setAsCopy(kmer2);
-            merge.mergeWithRRKmer(i, kmer1);
-            Assert.assertEquals(text1.substring(0, text1.length() - i + 1) + text2, merge.toString());
-        }
-
-        for (int ik = 1; ik <= 10; ik++) {
-            for (int jk = 1; jk <= 10; jk++) {
-                kmer1 = new KmerBytesWritable(ik);
-                kmer2 = new KmerBytesWritable(jk);
-                kmer1.setByRead(array, 0);
-                kmer2.setByRead(array, 0);
-                text1 = text.substring(0, ik);
-                text2 = text.substring(0, jk);
-                Assert.assertEquals(text1, kmer1.toString());
-                Assert.assertEquals(text2, kmer2.toString());
-                for (int x = 1; x < ik; x++) {
-                    merge.setAsCopy(kmer2);
-                    merge.mergeWithRRKmer(x, kmer1);
-                    Assert.assertEquals(text1.substring(0, text1.length() - x + 1) + text2, merge.toString());
-                }
-            }
-        }
-    }
-
-    @Test
-    public void TestMergeRFAndRRKmer() {
-    	String test1 = "TAGAT";
-    	String test2 = "TCTAG";  // rc = CTAGA
-    	String test3 = "GCTAG";
-    	KmerBytesWritable k1 = new KmerBytesWritable(5);
-        KmerBytesWritable k2 = new KmerBytesWritable(5);
-        KmerBytesWritable k3 = new KmerBytesWritable(5);
-        k1.setByRead(test1.getBytes(), 0);
-        k2.setByRead(test2.getBytes(), 0);
-        k3.setByRead(test3.getBytes(), 0);
-        k1.mergeWithRFKmer(5, k2);
-        Assert.assertEquals("CTAGAT", k1.toString());
-        k1.mergeWithRRKmer(5, k3);
-        Assert.assertEquals("GCTAGAT", k1.toString());
-    }
 }
-
-
diff --git a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java
index 1bbb771..5a69a3c 100644
--- a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java
@@ -20,20 +20,22 @@
         //one kmer in list and reset each time
         KmerBytesWritable kmer;
         for (int i = 1; i < 200; i++) {
-            kmer = new KmerBytesWritable(i);
+            KmerBytesWritable.setGlobalKmerLength(i);
+            kmer = new KmerBytesWritable();
             String randomString = generateString(i);
             byte[] array = randomString.getBytes();
             kmer.setByRead(array, 0);
-            kmerList.reset(kmer.getKmerLength());
+            kmerList.reset();
             kmerList.append(kmer);
-            Assert.assertEquals(kmerList.getPosition(0).toString(), randomString);
+            Assert.assertEquals(randomString, kmerList.getPosition(0).toString());
             Assert.assertEquals(1, kmerList.getCountOfPosition());
         }
         
-        kmerList.reset(0);
+        kmerList.reset();
+        KmerBytesWritable.setGlobalKmerLength(5);
         //add one more kmer each time and fix kmerSize
         for (int i = 0; i < 200; i++) {
-            kmer = new KmerBytesWritable(5);
+            kmer = new KmerBytesWritable();
             String randomString = generateString(5);
             byte[] array = randomString.getBytes();
             kmer.setByRead(array, 0);
@@ -44,8 +46,8 @@
         
         byte [] another = new byte [kmerList.getLength()*2];
         int start = 20;
-        System.arraycopy(kmerList.getByteArray(), 0, another, start, kmerList.getLength());
-        KmerListWritable plist2 = new KmerListWritable(kmerList.kmerlength, kmerList.getCountOfPosition(),another,start);
+        System.arraycopy(kmerList.getByteArray(), kmerList.getStartOffset(), another, start, kmerList.getLength());
+        KmerListWritable plist2 = new KmerListWritable(another, start);
         for(int i = 0; i < plist2.getCountOfPosition(); i++){
             Assert.assertEquals(kmerList.getPosition(i).toString(), plist2.getPosition(i).toString());
         }
@@ -59,12 +61,13 @@
         int i;
         KmerBytesWritable kmer;
         for (i = 0; i < 200; i++) {
-            kmer = new KmerBytesWritable(5);
+            KmerBytesWritable.setGlobalKmerLength(5);
+            kmer = new KmerBytesWritable();
             String randomString = generateString(5);
             byte[] array = randomString.getBytes();
             kmer.setByRead(array, 0);
             kmerList.append(kmer);
-            Assert.assertEquals(kmerList.getPosition(i).toString(), randomString);
+            Assert.assertEquals(randomString, kmerList.getPosition(i).toString());
             Assert.assertEquals(i + 1, kmerList.getCountOfPosition());
         }
         
@@ -72,12 +75,12 @@
         KmerBytesWritable tmpKmer = new KmerBytesWritable();
         i = 0;
         KmerListWritable copyList = new KmerListWritable();
-        copyList.set(kmerList);
+        copyList.setCopy(kmerList);
         Iterator<KmerBytesWritable> iterator;
         for(int j = 0; j < 5; j++){
             iterator = copyList.iterator();
             byte[] array = kmerList.getPosition(j).toString().getBytes();
-            KmerBytesWritable deletePos = new KmerBytesWritable(5);
+            KmerBytesWritable deletePos = new KmerBytesWritable();
             deletePos.setByRead(array, 0);
             while(iterator.hasNext()){
                 tmpKmer = iterator.next();
diff --git a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/PositionListWritableTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/PositionListWritableTest.java
index fea658d..ac7322e 100644
--- a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/PositionListWritableTest.java
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/PositionListWritableTest.java
@@ -41,7 +41,7 @@
         byte [] another = new byte [plist.getLength()*2];
         int start = 20;
         System.arraycopy(plist.getByteArray(), 0, another, start, plist.getLength());
-        PositionListWritable plist2 = new PositionListWritable(plist.getCountOfPosition(),another,start);
+        PositionListWritable plist2 = new PositionListWritable(another,start);
         for( i = 0; i < plist2.getCountOfPosition(); i++){
             Assert.assertEquals(plist.getPosition(i), plist2.getPosition(i));
         }
@@ -84,19 +84,22 @@
             iterator = copyList.iterator();
             PositionWritable deletePos = new PositionWritable();
             deletePos.set((byte)1, (long)j, j);
+            boolean removed = false;
             while(iterator.hasNext()){
                 pos = iterator.next();
                 if(pos.equals(deletePos)){
                     iterator.remove();
+                    removed = true;
                     break;
                 }
             }
+            Assert.assertTrue(removed);
             Assert.assertEquals(5 - 1 - j, copyList.getCountOfPosition());
             while(iterator.hasNext()){
                 pos = iterator.next();
-                Assert.assertTrue(pos.getUUID() != deletePos.getUUID());
-                Assert.assertTrue(pos.getReadId() != deletePos.getReadId());
-                Assert.assertTrue(pos.getPosId() != deletePos.getPosId());
+                Assert.assertTrue(! (pos.getUUID() == deletePos.getUUID() && 
+                                  pos.getReadId() == deletePos.getReadId() && 
+                                  pos.getPosId() == deletePos.getPosId()));
                 i++;
             }
         }
diff --git a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/VKmerBytesWritableTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/VKmerBytesWritableTest.java
index a50e465..5dd4f82 100644
--- a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/VKmerBytesWritableTest.java
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/VKmerBytesWritableTest.java
@@ -24,386 +24,376 @@
 import edu.uci.ics.genomix.type.VKmerBytesWritable;
 
 public class VKmerBytesWritableTest {
-	static byte[] array = { 'A', 'A', 'T', 'A', 'G', 'A', 'A', 'G' };
-	static int k = 7;
+    static byte[] array = { 'A', 'A', 'T', 'A', 'G', 'A', 'A', 'G' };
+    static int k = 7;
 
-	@Test
-	public void TestCompressKmer() {
-		VKmerBytesWritable kmer = new VKmerBytesWritable(k);
-		kmer.setByRead(array, 0);
-		Assert.assertEquals(kmer.toString(), "AATAGAA");
+    @Test
+    public void TestCompressKmer() {
+        VKmerBytesWritable kmer = new VKmerBytesWritable(k);
+        kmer.setByRead(array, 0);
+        Assert.assertEquals(kmer.toString(), "AATAGAA");
 
-		kmer.setByRead(array, 1);
-		Assert.assertEquals(kmer.toString(), "ATAGAAG");
-	}
+        kmer.setByRead(array, 1);
+        Assert.assertEquals(kmer.toString(), "ATAGAAG");
+    }
 
-	@Test
-	public void TestMoveKmer() {
-		VKmerBytesWritable kmer = new VKmerBytesWritable(k);
-		kmer.setByRead(array, 0);
-		Assert.assertEquals(kmer.toString(), "AATAGAA");
+    @Test
+    public void TestMoveKmer() {
+        VKmerBytesWritable kmer = new VKmerBytesWritable(k);
+        kmer.setByRead(array, 0);
+        Assert.assertEquals(kmer.toString(), "AATAGAA");
 
-		for (int i = k; i < array.length - 1; i++) {
-			kmer.shiftKmerWithNextCode(array[i]);
-			Assert.assertTrue(false);
-		}
+        for (int i = k; i < array.length - 1; i++) {
+            kmer.shiftKmerWithNextCode(array[i]);
+            Assert.assertTrue(false);
+        }
 
-		byte out = kmer.shiftKmerWithNextChar(array[array.length - 1]);
-		Assert.assertEquals(out, GeneCode.getCodeFromSymbol((byte) 'A'));
-		Assert.assertEquals(kmer.toString(), "ATAGAAG");
-	}
+        byte out = kmer.shiftKmerWithNextChar(array[array.length - 1]);
+        Assert.assertEquals(out, GeneCode.getCodeFromSymbol((byte) 'A'));
+        Assert.assertEquals(kmer.toString(), "ATAGAAG");
+    }
 
-	@Test
-	public void TestCompressKmerReverse() {
-		VKmerBytesWritable kmer = new VKmerBytesWritable(k);
-		kmer.setByRead(array, 0);
-		Assert.assertEquals(kmer.toString(), "AATAGAA");
+    @Test
+    public void TestCompressKmerReverse() {
+        VKmerBytesWritable kmer = new VKmerBytesWritable(k);
+        kmer.setByRead(array, 0);
+        Assert.assertEquals(kmer.toString(), "AATAGAA");
 
-		kmer.setByReadReverse(array, 1);
-		Assert.assertEquals(kmer.toString(), "CTTCTAT");
-	}
+        kmer.setByReadReverse(array, 1);
+        Assert.assertEquals(kmer.toString(), "CTTCTAT");
+    }
 
-	@Test
-	public void TestMoveKmerReverse() {
-		VKmerBytesWritable kmer = new VKmerBytesWritable(k);
-		kmer.setByRead(array, 0);
-		Assert.assertEquals(kmer.toString(), "AATAGAA");
+    @Test
+    public void TestMoveKmerReverse() {
+        VKmerBytesWritable kmer = new VKmerBytesWritable(k);
+        kmer.setByRead(array, 0);
+        Assert.assertEquals(kmer.toString(), "AATAGAA");
 
-		for (int i = k; i < array.length - 1; i++) {
-			kmer.shiftKmerWithPreChar(array[i]);
-			Assert.assertTrue(false);
-		}
+        for (int i = k; i < array.length - 1; i++) {
+            kmer.shiftKmerWithPreChar(array[i]);
+            Assert.assertTrue(false);
+        }
 
-		byte out = kmer.shiftKmerWithPreChar(array[array.length - 1]);
-		Assert.assertEquals(out, GeneCode.getCodeFromSymbol((byte) 'A'));
-		Assert.assertEquals(kmer.toString(), "GAATAGA");
-	}
+        byte out = kmer.shiftKmerWithPreChar(array[array.length - 1]);
+        Assert.assertEquals(out, GeneCode.getCodeFromSymbol((byte) 'A'));
+        Assert.assertEquals(kmer.toString(), "GAATAGA");
+    }
 
-	@Test
-	public void TestGetGene() {
-		VKmerBytesWritable kmer = new VKmerBytesWritable(9);
-		String text = "AGCTGACCG";
-		byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G' };
-		kmer.setByRead(array, 0);
+    @Test
+    public void TestGetGene() {
+        VKmerBytesWritable kmer = new VKmerBytesWritable(9);
+        String text = "AGCTGACCG";
+        byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G' };
+        kmer.setByRead(array, 0);
 
-		for (int i = 0; i < 9; i++) {
-			Assert.assertEquals(text.charAt(i), (char) (GeneCode
-					.getSymbolFromCode(kmer.getGeneCodeAtPosition(i))));
-		}
-	}
+        for (int i = 0; i < 9; i++) {
+            Assert.assertEquals(text.charAt(i), (char) (GeneCode.getSymbolFromCode(kmer.getGeneCodeAtPosition(i))));
+        }
+    }
 
-	@Test
-	public void TestGetOneByteFromKmer() {
-		byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
-		String string = "AGCTGACCGT";
-		for (int k = 3; k <= 10; k++) {
-			VKmerBytesWritable kmer = new VKmerBytesWritable(k);
-			VKmerBytesWritable kmerAppend = new VKmerBytesWritable(k);
-			kmer.setByRead(array, 0);
-			Assert.assertEquals(string.substring(0, k), kmer.toString());
-			for (int b = 0; b < k; b++) {
-				byte byteActual = VKmerBytesWritable
-						.getOneByteFromKmerAtPosition(b, kmer.getBytes(),
-								kmer.getOffset(), kmer.getLength());
-				byte byteExpect = GeneCode.getCodeFromSymbol(array[b]);
-				for (int i = 1; i < 4 && b + i < k; i++) {
-					byteExpect += GeneCode.getCodeFromSymbol(array[b + i]) << (i * 2);
-				}
-				Assert.assertEquals(byteActual, byteExpect);
-				VKmerBytesWritable.appendOneByteAtPosition(b, byteActual,
-						kmerAppend.getBytes(), kmerAppend.getOffset(),
-						kmerAppend.getLength());
-			}
-			Assert.assertEquals(kmer.toString(), kmerAppend.toString());
-		}
-	}
+    @Test
+    public void TestGetOneByteFromKmer() {
+        byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
+        String string = "AGCTGACCGT";
+        for (int k = 3; k <= 10; k++) {
+            VKmerBytesWritable kmer = new VKmerBytesWritable(k);
+            VKmerBytesWritable kmerAppend = new VKmerBytesWritable(k);
+            kmer.setByRead(array, 0);
+            Assert.assertEquals(string.substring(0, k), kmer.toString());
+            for (int b = 0; b < k; b++) {
+                byte byteActual = KmerBytesWritable.getOneByteFromKmerAtPosition(b, kmer.getBytes(),
+                        kmer.getKmerOffset(), kmer.getKmerByteLength());
+                byte byteExpect = GeneCode.getCodeFromSymbol(array[b]);
+                for (int i = 1; i < 4 && b + i < k; i++) {
+                    byteExpect += GeneCode.getCodeFromSymbol(array[b + i]) << (i * 2);
+                }
+                Assert.assertEquals(byteActual, byteExpect);
+                KmerBytesWritable.appendOneByteAtPosition(b, byteActual, kmerAppend.getBytes(),
+                        kmerAppend.getKmerOffset(), kmerAppend.getKmerByteLength());
+            }
+            Assert.assertEquals(kmer.toString(), kmerAppend.toString());
+        }
+    }
 
-	@Test
-	public void TestMergeFFKmer() {
-		byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
-		String text = "AGCTGACCGT";
-		VKmerBytesWritable kmer1 = new VKmerBytesWritable(8);
-		kmer1.setByRead(array, 0);
-		String text1 = "AGCTGACC";
-		Assert.assertEquals(text1, kmer1.toString());
-		
-		VKmerBytesWritable kmer2 = new VKmerBytesWritable(8);
-		kmer2.setByRead(array, 1);
-		String text2 = "GCTGACCG";
-		Assert.assertEquals(text2, kmer2.toString());
-		
-		VKmerBytesWritable merge = new VKmerBytesWritable(kmer1);
-		int kmerSize = 8;
-		merge.mergeWithFFKmer(kmerSize, kmer2);
-		Assert.assertEquals(text1 + text2.substring(kmerSize - 1),
-				merge.toString());
+    @Test
+    public void TestMergeFFKmer() {
+        byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
+        String text = "AGCTGACCGT";
+        VKmerBytesWritable kmer1 = new VKmerBytesWritable(8);
+        kmer1.setByRead(array, 0);
+        String text1 = "AGCTGACC";
+        Assert.assertEquals(text1, kmer1.toString());
 
-		for (int i = 1; i < 8; i++) {
-			merge.setAsCopy(kmer1);
-			merge.mergeWithFFKmer(i, kmer2);
-			Assert.assertEquals(text1 + text2.substring(i - 1),
-					merge.toString());
-		}
+        VKmerBytesWritable kmer2 = new VKmerBytesWritable(8);
+        kmer2.setByRead(array, 1);
+        String text2 = "GCTGACCG";
+        Assert.assertEquals(text2, kmer2.toString());
 
-		for (int ik = 1; ik <= 10; ik++) {
-			for (int jk = 1; jk <= 10; jk++) {
-				kmer1 = new VKmerBytesWritable(ik);
-				kmer2 = new VKmerBytesWritable(jk);
-				kmer1.setByRead(array, 0);
-				kmer2.setByRead(array, 0);
-				text1 = text.substring(0, ik);
-				text2 = text.substring(0, jk);
-				Assert.assertEquals(text1, kmer1.toString());
-				Assert.assertEquals(text2, kmer2.toString());
-				for (int x = 1; x < jk; x++) {
-					merge.setAsCopy(kmer1);
-					merge.mergeWithFFKmer(x, kmer2);
-					Assert.assertEquals(text1 + text2.substring(x - 1),
-							merge.toString());
-				}
-			}
-		}
-	}
+        VKmerBytesWritable merge = new VKmerBytesWritable(kmer1);
+        int kmerSize = 8;
+        merge.mergeWithFFKmer(kmerSize, kmer2);
+        Assert.assertEquals(text1 + text2.substring(kmerSize - 1), merge.toString());
 
-	@Test
-	public void TestMergeFRKmer() {
-		int kmerSize = 3;
-		String result = "AAGCTAACAACC";
-		byte[] resultArray = result.getBytes();
+        for (int i = 1; i < 8; i++) {
+            merge.setAsCopy(kmer1);
+            merge.mergeWithFFKmer(i, kmer2);
+            Assert.assertEquals(text1 + text2.substring(i - 1), merge.toString());
+        }
 
-		String text1 = "AAGCTAA";
-		VKmerBytesWritable kmer1 = new VKmerBytesWritable(text1.length());
-		kmer1.setByRead(resultArray, 0);
-		Assert.assertEquals(text1, kmer1.toString());
+        for (int ik = 1; ik <= 10; ik++) {
+            for (int jk = 1; jk <= 10; jk++) {
+                kmer1 = new VKmerBytesWritable(ik);
+                kmer2 = new VKmerBytesWritable(jk);
+                kmer1.setByRead(array, 0);
+                kmer2.setByRead(array, 0);
+                text1 = text.substring(0, ik);
+                text2 = text.substring(0, jk);
+                Assert.assertEquals(text1, kmer1.toString());
+                Assert.assertEquals(text2, kmer2.toString());
+                for (int x = 1; x < jk; x++) {
+                    merge.setAsCopy(kmer1);
+                    merge.mergeWithFFKmer(x, kmer2);
+                    Assert.assertEquals(text1 + text2.substring(x - 1), merge.toString());
+                }
+            }
+        }
+    }
 
-		// kmer2 is the rc of the end of the read
-		String text2 = "GGTTGTT";
-		VKmerBytesWritable kmer2 = new VKmerBytesWritable(text2.length());
-		kmer2.setByReadReverse(resultArray, result.length() - text2.length());
-		Assert.assertEquals(text2, kmer2.toString());
+    @Test
+    public void TestMergeFRKmer() {
+        int kmerSize = 3;
+        String result = "AAGCTAACAACC";
+        byte[] resultArray = result.getBytes();
 
-		VKmerBytesWritable merge = new VKmerBytesWritable(kmer1);
-		merge.mergeWithFRKmer(kmerSize, kmer2);
-		Assert.assertEquals(result, merge.toString());
+        String text1 = "AAGCTAA";
+        VKmerBytesWritable kmer1 = new VKmerBytesWritable(text1.length());
+        kmer1.setByRead(resultArray, 0);
+        Assert.assertEquals(text1, kmer1.toString());
 
-		int i = 1;
-		merge.setAsCopy(kmer1);
-		merge.mergeWithFRKmer(i, kmer2);
-		Assert.assertEquals("AAGCTAAAACAACC", merge.toString());
+        // kmer2 is the rc of the end of the read
+        String text2 = "GGTTGTT";
+        VKmerBytesWritable kmer2 = new VKmerBytesWritable(text2.length());
+        kmer2.setByReadReverse(resultArray, result.length() - text2.length());
+        Assert.assertEquals(text2, kmer2.toString());
 
-		i = 2;
-		merge.setAsCopy(kmer1);
-		merge.mergeWithFRKmer(i, kmer2);
-		Assert.assertEquals("AAGCTAAACAACC", merge.toString());
+        VKmerBytesWritable merge = new VKmerBytesWritable(kmer1);
+        merge.mergeWithFRKmer(kmerSize, kmer2);
+        Assert.assertEquals(result, merge.toString());
 
-		i = 3;
-		merge.setAsCopy(kmer1);
-		merge.mergeWithFRKmer(i, kmer2);
-		Assert.assertEquals("AAGCTAACAACC", merge.toString());
-	}
+        int i = 1;
+        merge.setAsCopy(kmer1);
+        merge.mergeWithFRKmer(i, kmer2);
+        Assert.assertEquals("AAGCTAAAACAACC", merge.toString());
 
-	@Test
-	public void TestMergeRFKmer() {
-		int kmerSize = 3;
-		String result = "GGCACAACAACCC";
-		byte[] resultArray = result.getBytes();
+        i = 2;
+        merge.setAsCopy(kmer1);
+        merge.mergeWithFRKmer(i, kmer2);
+        Assert.assertEquals("AAGCTAAACAACC", merge.toString());
 
-		String text1 = "AACAACCC";
-		VKmerBytesWritable kmer1 = new VKmerBytesWritable(text1.length());
-		kmer1.setByRead(resultArray, 5);
-		Assert.assertEquals(text1, kmer1.toString());
+        i = 3;
+        merge.setAsCopy(kmer1);
+        merge.mergeWithFRKmer(i, kmer2);
+        Assert.assertEquals("AAGCTAACAACC", merge.toString());
+    }
 
-		// kmer2 is the rc of the end of the read
-		String text2 = "TTGTGCC";
-		VKmerBytesWritable kmer2 = new VKmerBytesWritable(text2.length());
-		kmer2.setByReadReverse(resultArray, 0);
-		Assert.assertEquals(text2, kmer2.toString());
+    @Test
+    public void TestMergeRFKmer() {
+        int kmerSize = 3;
+        String result = "GGCACAACAACCC";
+        byte[] resultArray = result.getBytes();
 
-		VKmerBytesWritable merge = new VKmerBytesWritable(kmer1);
-		merge.mergeWithRFKmer(kmerSize, kmer2);
-		Assert.assertEquals(result, merge.toString());
+        String text1 = "AACAACCC";
+        VKmerBytesWritable kmer1 = new VKmerBytesWritable(text1.length());
+        kmer1.setByRead(resultArray, 5);
+        Assert.assertEquals(text1, kmer1.toString());
 
-		int i = 1;
-		merge.setAsCopy(kmer1);
-		merge.mergeWithRFKmer(i, kmer2);
-		Assert.assertEquals("GGCACAAAACAACCC", merge.toString());
+        // kmer2 is the rc of the end of the read
+        String text2 = "TTGTGCC";
+        VKmerBytesWritable kmer2 = new VKmerBytesWritable(text2.length());
+        kmer2.setByReadReverse(resultArray, 0);
+        Assert.assertEquals(text2, kmer2.toString());
 
-		i = 2;
-		merge.setAsCopy(kmer1);
-		merge.mergeWithRFKmer(i, kmer2);
-		Assert.assertEquals("GGCACAAACAACCC", merge.toString());
+        VKmerBytesWritable merge = new VKmerBytesWritable(kmer1);
+        merge.mergeWithRFKmer(kmerSize, kmer2);
+        Assert.assertEquals(result, merge.toString());
 
-		i = 3;
-		merge.setAsCopy(kmer1);
-		merge.mergeWithRFKmer(i, kmer2);
-		Assert.assertEquals("GGCACAACAACCC", merge.toString());
+        int i = 1;
+        merge.setAsCopy(kmer1);
+        merge.mergeWithRFKmer(i, kmer2);
+        Assert.assertEquals("GGCACAAAACAACCC", merge.toString());
 
-		// String test1 = "CTTAT";
-		// String test2 = "AGACC"; // rc = GGTCT
-		// VKmerBytesWritable k1 = new VKmerBytesWritable(5);
-		// VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		// k1.setByRead(test1.getBytes(), 0);
-		// k2.setByRead(test2.getBytes(), 0);
-		// k1.mergeWithRFKmer(3, k2);
-		// Assert.assertEquals("GGTCTTAT", k1.toString()); //GGTCGTCT ->
-		// AGACGACC ??
+        i = 2;
+        merge.setAsCopy(kmer1);
+        merge.mergeWithRFKmer(i, kmer2);
+        Assert.assertEquals("GGCACAAACAACCC", merge.toString());
 
-		String test3 = "CTA";
-		String test4 = "AGA"; // rc = TCT
-		VKmerBytesWritable k3 = new VKmerBytesWritable(3);
-		VKmerBytesWritable k4 = new VKmerBytesWritable(3);
-		k3.setByRead(test3.getBytes(), 0);
-		k4.setByRead(test4.getBytes(), 0);
-		k3.mergeWithRFKmer(3, k4);
-		Assert.assertEquals("TCTA", k3.toString());
-		// Assert.assertEquals("CTAT", k3); // this is an incorrect test case--
-		// the merge always flips the passed-in kmer
-	}
+        i = 3;
+        merge.setAsCopy(kmer1);
+        merge.mergeWithRFKmer(i, kmer2);
+        Assert.assertEquals("GGCACAACAACCC", merge.toString());
 
-	@Test
-	public void TestMergeRRKmer() {
-		byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
-		String text = "AGCTGACCGT";
-		VKmerBytesWritable kmer1 = new VKmerBytesWritable(8);
-		kmer1.setByRead(array, 0);
-		String text1 = "AGCTGACC";
-		VKmerBytesWritable kmer2 = new VKmerBytesWritable(8);
-		kmer2.setByRead(array, 1);
-		String text2 = "GCTGACCG";
-		Assert.assertEquals(text2, kmer2.toString());
-		VKmerBytesWritable merge = new VKmerBytesWritable(kmer2);
-		int kmerSize = 8;
-		merge.mergeWithRRKmer(kmerSize, kmer1);
-		Assert.assertEquals(text1 + text2.substring(kmerSize - 1),
-				merge.toString());
+        // String test1 = "CTTAT";
+        // String test2 = "AGACC"; // rc = GGTCT
+        // VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        // VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        // k1.setByRead(test1.getBytes(), 0);
+        // k2.setByRead(test2.getBytes(), 0);
+        // k1.mergeWithRFKmer(3, k2);
+        // Assert.assertEquals("GGTCTTAT", k1.toString()); //GGTCGTCT ->
+        // AGACGACC ??
 
-		for (int i = 1; i < 8; i++) {
-			merge.setAsCopy(kmer2);
-			merge.mergeWithRRKmer(i, kmer1);
-			Assert.assertEquals(text1.substring(0, text1.length() - i + 1)
-					+ text2, merge.toString());
-		}
+        String test3 = "CTA";
+        String test4 = "AGA"; // rc = TCT
+        VKmerBytesWritable k3 = new VKmerBytesWritable(3);
+        VKmerBytesWritable k4 = new VKmerBytesWritable(3);
+        k3.setByRead(test3.getBytes(), 0);
+        k4.setByRead(test4.getBytes(), 0);
+        k3.mergeWithRFKmer(3, k4);
+        Assert.assertEquals("TCTA", k3.toString());
+        // Assert.assertEquals("CTAT", k3); // this is an incorrect test case--
+        // the merge always flips the passed-in kmer
+    }
 
-		for (int ik = 1; ik <= 10; ik++) {
-			for (int jk = 1; jk <= 10; jk++) {
-				kmer1 = new VKmerBytesWritable(ik);
-				kmer2 = new VKmerBytesWritable(jk);
-				kmer1.setByRead(array, 0);
-				kmer2.setByRead(array, 0);
-				text1 = text.substring(0, ik);
-				text2 = text.substring(0, jk);
-				Assert.assertEquals(text1, kmer1.toString());
-				Assert.assertEquals(text2, kmer2.toString());
-				for (int x = 1; x < ik; x++) {
-					merge.setAsCopy(kmer2);
-					merge.mergeWithRRKmer(x, kmer1);
-					Assert.assertEquals(
-							text1.substring(0, text1.length() - x + 1) + text2,
-							merge.toString());
-				}
-			}
-		}
-	}
+    @Test
+    public void TestMergeRRKmer() {
+        byte[] array = { 'A', 'G', 'C', 'T', 'G', 'A', 'C', 'C', 'G', 'T' };
+        String text = "AGCTGACCGT";
+        VKmerBytesWritable kmer1 = new VKmerBytesWritable(8);
+        kmer1.setByRead(array, 0);
+        String text1 = "AGCTGACC";
+        VKmerBytesWritable kmer2 = new VKmerBytesWritable(8);
+        kmer2.setByRead(array, 1);
+        String text2 = "GCTGACCG";
+        Assert.assertEquals(text2, kmer2.toString());
+        VKmerBytesWritable merge = new VKmerBytesWritable(kmer2);
+        int kmerSize = 8;
+        merge.mergeWithRRKmer(kmerSize, kmer1);
+        Assert.assertEquals(text1 + text2.substring(kmerSize - 1), merge.toString());
 
-	@Test
-	public void TestMergeRFAndRRKmer() {
-		String test1 = "TAGAT";
-		String test2 = "TCTAG"; // rc = CTAGA
-		String test3 = "GCTAG";
-		VKmerBytesWritable k1 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k3 = new VKmerBytesWritable(5);
-		k1.setByRead(test1.getBytes(), 0);
-		k2.setByRead(test2.getBytes(), 0);
-		k3.setByRead(test3.getBytes(), 0);
-		k1.mergeWithRFKmer(5, k2);
-		Assert.assertEquals("CTAGAT", k1.toString());
-		k1.mergeWithRRKmer(5, k3);
-		Assert.assertEquals("GCTAGAT", k1.toString());
-	}
-	
-	@Test
-	public void TestMergeRFAndRFKmer() {
-		String test1 = "TAGAT";
-		String test2 = "TCTAG"; // rc = CTAGA
-		String test3 = "CTAGC"; // rc = GCTAG
-		VKmerBytesWritable k1 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k3 = new VKmerBytesWritable(5);
-		k1.setByRead(test1.getBytes(), 0);
-		k2.setByRead(test2.getBytes(), 0);
-		k3.setByRead(test3.getBytes(), 0);
-		k1.mergeWithRFKmer(5, k2);
-		Assert.assertEquals("CTAGAT", k1.toString());
-		k1.mergeWithRFKmer(5, k3);
-		Assert.assertEquals("GCTAGAT", k1.toString());
-	}
-	
-	@Test
-	public void TestMergeRFAndFRKmer() {
-		String test1 = "TAGAT"; // rc = ATCTA
-		String test2 = "TCTAG"; // rc = CTAGA
-		String test3 = "GCTAG"; // rc = CTAGC
-		VKmerBytesWritable k1 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k3 = new VKmerBytesWritable(5);
-		k1.setByRead(test1.getBytes(), 0);
-		k2.setByRead(test2.getBytes(), 0);
-		k3.setByRead(test3.getBytes(), 0);
-		k2.mergeWithRFKmer(5, k1);
-		Assert.assertEquals("ATCTAG", k2.toString());
-		k2.mergeWithFRKmer(5, k3);
-		Assert.assertEquals("ATCTAGC", k2.toString());
-	}
-	
-	@Test
-	public void TestMergeRFAndFFKmer() {
-		String test1 = "TAGAT"; // rc = ATCTA
-		String test2 = "TCTAG"; // rc = CTAGA
-		String test3 = "CTAGC"; // rc = GCTAG
-		VKmerBytesWritable k1 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k3 = new VKmerBytesWritable(5);
-		k1.setByRead(test1.getBytes(), 0);
-		k2.setByRead(test2.getBytes(), 0);
-		k3.setByRead(test3.getBytes(), 0);
-		k2.mergeWithRFKmer(5, k1);
-		Assert.assertEquals("ATCTAG", k2.toString());
-		k2.mergeWithFFKmer(5, k3);
-		Assert.assertEquals("ATCTAGC", k2.toString());
-	}
-	
-	@Test
-	public void TestMergeKmerAndVKmer() {
-		String test1 = "TAGAT"; // rc = ATCTA
-		String test2 = "TCTAG"; // rc = CTAGA
-		String test3 = "CTAGC"; // rc = GCTAG
-		KmerBytesWritable k1 = new KmerBytesWritable(5);
-		VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k3 = new VKmerBytesWritable(5);
-		k1.setByRead(test1.getBytes(), 0);
-		k2.setByRead(test2.getBytes(), 0);
-		k3.setByRead(test3.getBytes(), 0);
-		k2.mergeWithRFKmer(5, k1);
-		Assert.assertEquals("ATCTAG", k2.toString());
-		k2.mergeWithFFKmer(5, k3);
-		Assert.assertEquals("ATCTAGC", k2.toString());
-	}
-	
-	@Test
-	public void TestMergeKmerAndVKmerRFAndRFKmer() {
-		String test1 = "TAGAT";
-		String test2 = "TCTAG"; // rc = CTAGA
-		String test3 = "CTAGC"; // rc = GCTAG
-		KmerBytesWritable k1 = new KmerBytesWritable(5);
-		VKmerBytesWritable k2 = new VKmerBytesWritable(5);
-		VKmerBytesWritable k3 = new VKmerBytesWritable(5);
-		k1.setByRead(test1.getBytes(), 0);
-		k2.setByRead(test2.getBytes(), 0);
-		k3.setByRead(test3.getBytes(), 0);
-		k1.mergeWithRFKmer(5, k2);
-		Assert.assertEquals("CTAGAT", k1.toString());
-		k1.mergeWithRFKmer(5, k3);
-		Assert.assertEquals("GCTAGAT", k1.toString());
-	}
+        for (int i = 1; i < 8; i++) {
+            merge.setAsCopy(kmer2);
+            merge.mergeWithRRKmer(i, kmer1);
+            Assert.assertEquals(text1.substring(0, text1.length() - i + 1) + text2, merge.toString());
+        }
+
+        for (int ik = 1; ik <= 10; ik++) {
+            for (int jk = 1; jk <= 10; jk++) {
+                kmer1 = new VKmerBytesWritable(ik);
+                kmer2 = new VKmerBytesWritable(jk);
+                kmer1.setByRead(array, 0);
+                kmer2.setByRead(array, 0);
+                text1 = text.substring(0, ik);
+                text2 = text.substring(0, jk);
+                Assert.assertEquals(text1, kmer1.toString());
+                Assert.assertEquals(text2, kmer2.toString());
+                for (int x = 1; x < ik; x++) {
+                    merge.setAsCopy(kmer2);
+                    merge.mergeWithRRKmer(x, kmer1);
+                    Assert.assertEquals(text1.substring(0, text1.length() - x + 1) + text2, merge.toString());
+                }
+            }
+        }
+    }
+
+    @Test
+    public void TestMergeRFAndRRKmer() {
+        String test1 = "TAGAT";
+        String test2 = "TCTAG"; // rc = CTAGA
+        String test3 = "GCTAG";
+        VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k3 = new VKmerBytesWritable(5);
+        k1.setByRead(test1.getBytes(), 0);
+        k2.setByRead(test2.getBytes(), 0);
+        k3.setByRead(test3.getBytes(), 0);
+        k1.mergeWithRFKmer(5, k2);
+        Assert.assertEquals("CTAGAT", k1.toString());
+        k1.mergeWithRRKmer(5, k3);
+        Assert.assertEquals("GCTAGAT", k1.toString());
+    }
+
+    @Test
+    public void TestMergeRFAndRFKmer() {
+        String test1 = "TAGAT";
+        String test2 = "TCTAG"; // rc = CTAGA
+        String test3 = "CTAGC"; // rc = GCTAG
+        VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k3 = new VKmerBytesWritable(5);
+        k1.setByRead(test1.getBytes(), 0);
+        k2.setByRead(test2.getBytes(), 0);
+        k3.setByRead(test3.getBytes(), 0);
+        k1.mergeWithRFKmer(5, k2);
+        Assert.assertEquals("CTAGAT", k1.toString());
+        k1.mergeWithRFKmer(5, k3);
+        Assert.assertEquals("GCTAGAT", k1.toString());
+    }
+
+    @Test
+    public void TestMergeRFAndFRKmer() {
+        String test1 = "TAGAT"; // rc = ATCTA
+        String test2 = "TCTAG"; // rc = CTAGA
+        String test3 = "GCTAG"; // rc = CTAGC
+        VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k3 = new VKmerBytesWritable(5);
+        k1.setByRead(test1.getBytes(), 0);
+        k2.setByRead(test2.getBytes(), 0);
+        k3.setByRead(test3.getBytes(), 0);
+        k2.mergeWithRFKmer(5, k1);
+        Assert.assertEquals("ATCTAG", k2.toString());
+        k2.mergeWithFRKmer(5, k3);
+        Assert.assertEquals("ATCTAGC", k2.toString());
+    }
+
+    @Test
+    public void TestMergeRFAndFFKmer() {
+        String test1 = "TAGAT"; // rc = ATCTA
+        String test2 = "TCTAG"; // rc = CTAGA
+        String test3 = "CTAGC"; // rc = GCTAG
+        VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k3 = new VKmerBytesWritable(5);
+        k1.setByRead(test1.getBytes(), 0);
+        k2.setByRead(test2.getBytes(), 0);
+        k3.setByRead(test3.getBytes(), 0);
+        k2.mergeWithRFKmer(5, k1);
+        Assert.assertEquals("ATCTAG", k2.toString());
+        k2.mergeWithFFKmer(5, k3);
+        Assert.assertEquals("ATCTAGC", k2.toString());
+    }
+
+    @Test
+    public void TestMergeThreeVKmersRF_FF() {
+        String test1 = "TAGAT"; // rc = ATCTA
+        String test2 = "TCTAG"; // rc = CTAGA
+        String test3 = "CTAGC"; // rc = GCTAG
+        VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k3 = new VKmerBytesWritable(5);
+        k1.setByRead(test1.getBytes(), 0);
+        k2.setByRead(test2.getBytes(), 0);
+        k3.setByRead(test3.getBytes(), 0);
+        k2.mergeWithRFKmer(5, k1);
+        Assert.assertEquals("ATCTAG", k2.toString());
+        k2.mergeWithFFKmer(5, k3);
+        Assert.assertEquals("ATCTAGC", k2.toString());
+    }
+
+    @Test
+    public void TestMergeThreeVKmerRF_RF() {
+        String test1 = "TAGAT";
+        String test2 = "TCTAG"; // rc = CTAGA
+        String test3 = "CTAGC"; // rc = GCTAG
+        VKmerBytesWritable k1 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k2 = new VKmerBytesWritable(5);
+        VKmerBytesWritable k3 = new VKmerBytesWritable(5);
+        k1.setByRead(test1.getBytes(), 0);
+        k2.setByRead(test2.getBytes(), 0);
+        k3.setByRead(test3.getBytes(), 0);
+        k1.mergeWithRFKmer(5, k2);
+        Assert.assertEquals("CTAGAT", k1.toString());
+        k1.mergeWithRFKmer(5, k3);
+        Assert.assertEquals("GCTAGAT", k1.toString());
+    }
 }
