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 2738b43..2d2907c 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
@@ -29,582 +29,618 @@
 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.
+ * 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.
  */
-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 int lettersInKmer;
+	protected int bytesUsed;
+	protected byte[] bytes;
+	protected int offset;
 
-    /**
-     * Initialize as empty kmer
-     */
-    public KmerBytesWritable() {
-        this(0, EMPTY_BYTES, 0);
-    }
+	/**
+	 * Initialize as empty kmer
+	 */
+	public KmerBytesWritable() {
+		this(0, EMPTY_BYTES, 0);
+	}
 
-    /**
-     * Copy contents of kmer string
-     */
-    public KmerBytesWritable(String kmer) {
-        setAsCopy(kmer);
-    }
+	/**
+	 * Copy contents of kmer string
+	 */
+	public KmerBytesWritable(String kmer) {
+		setAsCopy(kmer);
+	}
 
-    /**
-     * Set as reference to given data
-     */
-    public KmerBytesWritable(int k, byte[] storage, int offset) {
-        setAsReference(k, storage, offset);
-    }
+	/**
+	 * Set as reference to given data
+	 */
+	public KmerBytesWritable(int k, byte[] storage, int offset) {
+		setAsReference(k, storage, offset);
+	}
 
-    /**
-     * 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);
-    }
+	/**
+	 * 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);
+	}
 
-    /**
-     * 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(other.lettersInKmer);
+		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, lettersInKmer);
-        }
-    }
+	/**
+	 * 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);
+		}
+	}
 
-    /**
-     * set from String kmer
-     */
-    public void setAsCopy(String kmer) {
-        setKmerLength(kmer.length());
-        bytes = kmer.getBytes();
-        offset = 0;
-    }
+	/**
+	 * 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(int k, byte[] newData, int offset) {
-        reset(k);
-        System.arraycopy(newData, offset, bytes, this.offset, k);
-    }
+	/**
+	 * 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);
+	}
 
-    /**
-     * Reset array by kmerlength
-     * 
-     * @param k
-     */
-    public void reset(int k) {
-        setKmerLength(k);
-        setSize(bytesUsed);
-        clearLeadBit();
-    }
+	/**
+	 * Reset array by kmerlength
+	 * 
+	 * @param k
+	 */
+	public void reset(int k) {
+		setKmerLength(k);
+		setSize(bytesUsed);
+		clearLeadBit();
+	}
 
-    /**
-     * 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;
-        setKmerLength(k);
-        if (newData.length - offset < bytesUsed) {
-            throw new IllegalArgumentException("Requested " + bytesUsed + " bytes (k=" + k
-                    + ") but buffer has only " + (newData.length - offset) + " bytes");
-        }
-    }
+	/**
+	 * 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");
+		}
+	}
 
-    protected void setSize(int size) {
-        if (size > getCapacity()) {
-            setCapacity((size * 3 / 2));
-        }
-        this.bytesUsed = size;
-    }
+	/**
+	 * 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;
+	}
 
-    protected int getCapacity() {
-        return bytes.length;
-    }
+	/**
+	 * return the number of bytes in use for the kmer (not including any header)
+	 */
+	protected int getCapacity() {
+		return bytes.length;
+	}
 
-    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;
-        }
-    }
+	/**
+	 * 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;
+		}
+	}
 
-    /**
-     * 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);
-    }
+	/**
+	 * 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);
+	}
 
-    // 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);
-    }
+	// 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);
+	}
 
-    public void setKmerLength(int k) {
-        this.bytesUsed = KmerUtil.getByteNumFromK(k);
-        this.lettersInKmer = k;
-    }
+	public void setKmerLength(int k) {
+		this.bytesUsed = KmerUtil.getByteNumFromK(k);
+		this.lettersInKmer = k;
+	}
 
-    public int getKmerLength() {
-        return lettersInKmer;
-    }
+	public int getKmerLength() {
+		return lettersInKmer;
+	}
 
-    @Override
-    public byte[] getBytes() {
-        return bytes;
-    }
+	@Override
+	public byte[] getBytes() {
+		return bytes;
+	}
 
-    public int getOffset() {
-        return offset;
-    }
+	public int getOffset() {
+		return offset;
+	}
 
-    @Override
-    public int getLength() {
-        return bytesUsed;
-    }
+	@Override
+	public int getLength() {
+		return bytesUsed;
+	}
 
-    /**
-     * 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;
-        }
-    }
+	/**
+	 * 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 void setByRead(int k, byte[] array, int start) {
-        reset(k);
-        setByRead(array, start);
-    }
+	public void setByRead(int k, byte[] array, int start) {
+		reset(k);
+		setByRead(array, 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[offset + bcount--] = l;
-                l = 0;
-                bytecount = 0;
-            }
-        }
-        if (bcount >= 0) {
-            bytes[offset] = l;
-        }
-    }
+	/**
+	 * 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 void setByReadReverse(int k, byte[] array, int start) {
-        reset(k);
-        setByReadReverse(array, start);
-    }
+	public void setByReadReverse(int k, byte[] array, int start) {
+		reset(k);
+		setByReadReverse(array, start);
+	}
 
-    /**
-     * 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));
-    }
+	/**
+	 * 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));
+	}
 
-    /**
-     * 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;
-    }
+	/**
+	 * 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;
+	}
 
-    /**
-     * 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));
-    }
+	/**
+	 * 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));
+	}
 
-    /**
-     * 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;
-    }
+	/**
+	 * 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;
+	}
 
-    /**
-     * 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();
-    }
+	/**
+	 * 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();
+	}
 
-    /**
-     * 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];
-        }
+	/**
+	 * 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];
+		}
 
-        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;
-        }
-    }
+		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;
+		}
+	}
 
-    /**
-     * 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) {
-        int preKmerLength = lettersInKmer;
-        int preSize = bytesUsed;
-        lettersInKmer += preKmer.lettersInKmer - initialKmerSize + 1;
-        setSize(KmerUtil.getByteNumFromK(lettersInKmer));
-        //        byte cacheByte = getOneByteFromKmerAtPosition(0, bytes, offset, preSize);
+	/**
+	 * 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) {
+		int preKmerLength = lettersInKmer;
+		int preSize = bytesUsed;
+		lettersInKmer += preKmer.lettersInKmer - initialKmerSize + 1;
+		setSize(KmerUtil.getByteNumFromK(lettersInKmer));
+		// byte cacheByte = getOneByteFromKmerAtPosition(0, bytes, offset,
+		// preSize);
 
-        int byteIndex = bytesUsed - 1;
-        byte cacheByte = 0x00;
-        int posnInByte = 0;
+		int byteIndex = bytesUsed - 1;
+		byte cacheByte = 0x00;
+		int posnInByte = 0;
 
-        // copy rc of preKmer into high bytes
-        for (int i = preKmer.lettersInKmer - 1; i >= initialKmerSize - 1; i--) {
-            byte code = GeneCode.getPairedGeneCode(preKmer.getGeneCodeAtPosition(i));
-            cacheByte |= (byte) (code << posnInByte);
-            posnInByte += 2;
-            if (posnInByte == 8) {
-                bytes[byteIndex--] = cacheByte;
-                cacheByte = 0;
-                posnInByte = 0;
-            }
-        }
+		// copy rc of preKmer into high bytes
+		for (int i = preKmer.lettersInKmer - 1; i >= initialKmerSize - 1; i--) {
+			byte code = GeneCode.getPairedGeneCode(preKmer
+					.getGeneCodeAtPosition(i));
+			cacheByte |= (byte) (code << posnInByte);
+			posnInByte += 2;
+			if (posnInByte == 8) {
+				bytes[byteIndex--] = cacheByte;
+				cacheByte = 0;
+				posnInByte = 0;
+			}
+		}
 
-        // copy my kmer into low positions of bytes
-        for (int i = 0; i < preKmerLength; i++) {
-            // expanding the capacity makes this offset incorrect.  It's off by the # of additional bytes added.
-            int newposn = i + (bytesUsed - preSize) * 4;
-            byte code = geneCodeAtPosition(newposn);
-            cacheByte |= (byte) (code << posnInByte);
-            posnInByte += 2;
-            if (posnInByte == 8) {
-                bytes[byteIndex--] = cacheByte;
-                cacheByte = 0;
-                posnInByte = 0;
-            }
-        }
-        bytes[offset] = cacheByte;
-        clearLeadBit();
-    }
+		// copy my kmer into low positions of bytes
+		for (int i = 0; i < preKmerLength; i++) {
+			// expanding the capacity makes this offset incorrect. It's off by
+			// the # of additional bytes added.
+			int newposn = i + (bytesUsed - preSize) * 4;
+			byte code = geneCodeAtPosition(newposn);  // TODO: this evaluation may be reading from a place we just overwrote :( 
+			cacheByte |= (byte) (code << posnInByte);
+			posnInByte += 2;
+			if (posnInByte == 8) {
+				bytes[byteIndex--] = cacheByte;
+				cacheByte = 0;
+				posnInByte = 0;
+			}
+		}
+		if (posnInByte > 0)
+			bytes[offset] = cacheByte;
+		clearLeadBit();
+	}
 
-    /**
-     * 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);
+	/**
+	 * 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 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();
-    }
+		// 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 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);
+	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))));
-        }
-    }
+		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;
-    }
+	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;
-        }
-    }
+	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 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;
 
-    @Override
-    public void write(DataOutput out) throws IOException {
-        out.writeInt(lettersInKmer);
-        if (lettersInKmer > 0) {
-            out.write(bytes, offset, bytesUsed);
-        }
-    }
+			}
+			in.readFully(bytes, offset, bytesUsed);
+		}
+	}
 
-    @Override
-    public int hashCode() {
-        return super.hashCode() * 31 + this.lettersInKmer;
-    }
+	@Override
+	public void write(DataOutput out) throws IOException {
+		out.writeInt(lettersInKmer);
+		if (lettersInKmer > 0) {
+			out.write(bytes, offset, bytesUsed);
+		}
+	}
 
-    @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 int hashCode() {
+		return super.hashCode() * 31 + this.lettersInKmer;
+	}
 
-    @Override
-    public String toString() {
-        return KmerUtil.recoverKmerFrom(this.lettersInKmer, this.getBytes(), offset, this.getLength());
-    }
+	@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;
+	}
 
-    public static class Comparator extends WritableComparator {
-    	private static final int LEADING_BYTES = 4;
+	@Override
+	public String toString() {
+		return KmerUtil.recoverKmerFrom(this.lettersInKmer, this.getBytes(),
+				offset, this.getLength());
+	}
 
-        public Comparator() {
-            super(KmerBytesWritable.class);
-        }
+	public static class Comparator extends WritableComparator {
+		private static final int LEADING_BYTES = 4;
 
-        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;
-        }
-    }
+		public Comparator() {
+			super(KmerBytesWritable.class);
+		}
 
-    static { // register this comparator
-        WritableComparator.define(KmerBytesWritable.class, new Comparator());
-    }
+		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());
+	}
 
 }
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 cd982ef..0e26b77 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
@@ -46,7 +46,7 @@
 	 * Initialize as empty kmer
 	 */
 	public VKmerBytesWritable() {
-		this(EMPTY_BYTES, 0);
+		this(EMPTY_BYTES, HEADER_SIZE);
 	}
 
 	/**
@@ -54,12 +54,16 @@
 	 */
 	public VKmerBytesWritable(String kmer) {
 		bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(kmer.length())];
-		offset = 0;
+		offset = HEADER_SIZE;
 		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);
@@ -74,7 +78,7 @@
 		} else {
 			bytes = EMPTY_BYTES;
 		}
-		offset = 0;
+		offset = HEADER_SIZE;
 		setKmerLength(k);
 	}
 
@@ -97,21 +101,8 @@
 	public void setAsCopy(KmerBytesWritable other) {
 		reset(other.lettersInKmer);
 		if (lettersInKmer > 0) {
-			System.arraycopy(other.bytes, other.offset, bytes, this.offset
-					+ HEADER_SIZE, lettersInKmer);
-		}
-	}
-
-	/**
-	 * Deep copy of the given kmer
-	 * 
-	 * @param other
-	 */
-	public void setAsCopy(VKmerBytesWritable other) {
-		reset(other.lettersInKmer);
-		if (lettersInKmer > 0) {
-			System.arraycopy(other.bytes, other.offset + HEADER_SIZE, bytes,
-					this.offset + HEADER_SIZE, lettersInKmer);
+			System.arraycopy(other.bytes, other.offset, bytes, this.offset,
+					bytesUsed);
 		}
 	}
 
@@ -122,21 +113,7 @@
 	public void setAsCopy(String kmer) {
 		int k = kmer.length();
 		reset(k);
-		System.arraycopy(kmer.getBytes(), 0, bytes, offset + HEADER_SIZE, k);
-	}
-
-	/**
-	 * Deep copy of the given bytes data
-	 * 
-	 * @param k
-	 * @param newData
-	 *            : presumed NOT to have a header
-	 * @param offset
-	 */
-	@Override
-	public void setAsCopy(int k, byte[] newData, int offset) {
-		reset(k);
-		System.arraycopy(newData, offset, bytes, this.offset + HEADER_SIZE, k);
+		System.arraycopy(kmer.getBytes(), 0, bytes, offset, bytesUsed);
 	}
 
 	/**
@@ -149,8 +126,7 @@
 	public void setAsCopy(byte[] newData, int offset) {
 		int k = Marshal.getInt(newData, offset);
 		reset(k);
-		System.arraycopy(newData, offset + HEADER_SIZE, bytes, this.offset
-				+ HEADER_SIZE, k);
+		System.arraycopy(newData, offset + HEADER_SIZE, bytes, this.offset, bytesUsed);
 	}
 
 	/**
@@ -163,9 +139,9 @@
 	 */
 	public void setAsReference(byte[] newData, int offset) {
 		this.bytes = newData;
-		this.offset = offset;
+		this.offset = offset + HEADER_SIZE;
 		int kRequested = Marshal.getInt(newData, offset);
-		int bytesRequested = KmerUtil.getByteNumFromK(kRequested);
+		int bytesRequested = KmerUtil.getByteNumFromK(kRequested) + HEADER_SIZE;
 		if (newData.length - offset < bytesRequested) {
 			throw new IllegalArgumentException("Requested " + bytesRequested
 					+ " bytes (k=" + kRequested + ") but buffer has only "
@@ -176,164 +152,86 @@
 
 	@Override
 	public void setKmerLength(int k) {
-		this.bytesUsed = HEADER_SIZE + KmerUtil.getByteNumFromK(k);
+		this.bytesUsed = KmerUtil.getByteNumFromK(k);
 		this.lettersInKmer = k;
-		Marshal.putInt(k, bytes, offset);
+		Marshal.putInt(k, bytes, offset - HEADER_SIZE);
 	}
-
+	
 	@Override
-	public void setByRead(byte[] stringBytes, int start) {
-		offset += HEADER_SIZE;
-		super.setByRead(stringBytes, start);
-		offset -= HEADER_SIZE;
+	protected int getCapacity() {
+		return bytes.length - HEADER_SIZE;
 	}
-
+	
 	@Override
-	public void setByReadReverse(byte[] array, int start) {
-		offset += HEADER_SIZE;
-		super.setByReadReverse(array, start);
-		offset -= HEADER_SIZE;
+	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;
+		}
 	}
 
-	@Override
-	public byte shiftKmerWithNextCode(byte c) {
-		offset += HEADER_SIZE;
-		byte retval = super.shiftKmerWithNextCode(c);
-		offset -= HEADER_SIZE;
-		return retval;
-
-	}
-
-	@Override
-	public byte shiftKmerWithPreCode(byte c) {
-		offset += HEADER_SIZE;
-		byte retval = super.shiftKmerWithPreCode(c);
-		offset -= HEADER_SIZE;
-		return retval;
-	}
 
 	@Override
 	public void mergeWithFFKmer(int initialKmerSize, KmerBytesWritable kmer) {
-		offset += HEADER_SIZE;
 		super.mergeWithFFKmer(initialKmerSize, kmer);
-		offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
-	}
-
-	/**
-	 * Merge with kmer that's FF to me. See KmerBytesWritable.mergeWithFFKmer.
-	 */
-	public void mergeWithFFKmer(int initialKmerSize, VKmerBytesWritable kmer) {
-		offset += HEADER_SIZE;
-		kmer.offset += HEADER_SIZE;
-		super.mergeWithFFKmer(initialKmerSize, kmer);
-		offset -= HEADER_SIZE;
-		kmer.offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
+		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
 	}
 
 	@Override
 	public void mergeWithFRKmer(int initialKmerSize, KmerBytesWritable kmer) {
-		offset += HEADER_SIZE;
 		super.mergeWithFRKmer(initialKmerSize, kmer);
-		offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
-	}
-
-	/**
-	 * Merge with kmer that's FR to me. See KmerBytesWritable.mergeWithFRKmer.
-	 */
-	public void mergeWithFRKmer(int initialKmerSize, VKmerBytesWritable kmer) {
-		offset += HEADER_SIZE;
-		kmer.offset += HEADER_SIZE;
-		super.mergeWithFRKmer(initialKmerSize, kmer);
-		offset -= HEADER_SIZE;
-		kmer.offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
+		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
 	}
 
 	@Override
 	public void mergeWithRFKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-		offset += HEADER_SIZE;
 		super.mergeWithRFKmer(initialKmerSize, preKmer);
-		offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
-	}
-
-	/**
-	 * Merge with kmer that's RF to me. See KmerBytesWritable.mergeWithRFKmer.
-	 */
-	public void mergeWithRFKmer(int initialKmerSize, VKmerBytesWritable preKmer) {
-		offset += HEADER_SIZE;
-		preKmer.offset += HEADER_SIZE;
-		super.mergeWithRFKmer(initialKmerSize, preKmer);
-		offset -= HEADER_SIZE;
-		preKmer.offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
+		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
 	}
 
 	@Override
 	public void mergeWithRRKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-		offset += HEADER_SIZE;
 		super.mergeWithRRKmer(initialKmerSize, preKmer);
-		offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
-	}
-
-	/**
-	 * Merge with kmer that's RR to me. See KmerBytesWritable.mergeWithRRKmer.
-	 */
-	public void mergeWithRRKmer(int initialKmerSize, VKmerBytesWritable preKmer) {
-		offset += HEADER_SIZE;
-		preKmer.offset += HEADER_SIZE;
-		super.mergeWithRRKmer(initialKmerSize, preKmer);
-		offset -= HEADER_SIZE;
-		preKmer.offset -= HEADER_SIZE;
-		Marshal.putInt(lettersInKmer, bytes, offset);
-	}
-
-	@Override
-	protected void clearLeadBit() {
-		offset += HEADER_SIZE;
-		super.clearLeadBit();
-		offset -= HEADER_SIZE;
+		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
 	}
 
 	@Override
 	public void readFields(DataInput in) throws IOException {
 		lettersInKmer = in.readInt();
-		bytesUsed = HEADER_SIZE + KmerUtil.getByteNumFromK(lettersInKmer);
+		bytesUsed = KmerUtil.getByteNumFromK(lettersInKmer);
 		if (lettersInKmer > 0) {
-			if (this.bytes.length < this.bytesUsed) {
-				this.bytes = new byte[this.bytesUsed];
-				this.offset = 0;
+			if (getCapacity() < this.bytesUsed) {
+				this.bytes = new byte[this.bytesUsed + HEADER_SIZE];
+				this.offset = HEADER_SIZE;
 			}
-			in.readFully(bytes, offset + HEADER_SIZE, bytesUsed - HEADER_SIZE);
+			in.readFully(bytes, offset, bytesUsed);
 		}
-		Marshal.putInt(lettersInKmer, bytes, offset);
+		Marshal.putInt(lettersInKmer, bytes, offset - HEADER_SIZE);
 	}
 
 	@Override
 	public void write(DataOutput out) throws IOException {
-		out.writeInt(lettersInKmer);
-		if (lettersInKmer > 0) {
-			out.write(bytes, offset + HEADER_SIZE, bytesUsed - HEADER_SIZE);
-		}
+		out.write(bytes, offset - HEADER_SIZE, bytesUsed + HEADER_SIZE);
 	}
 
 	@Override
 	public boolean equals(Object right) {
 		if (right instanceof VKmerBytesWritable) {
-			return this.lettersInKmer == ((VKmerBytesWritable) right).lettersInKmer
-					&& super.equals(right);
+			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) {
-				// break early
+			if (lettersInKmer != rightKmer.lettersInKmer) { // check length
 				return false;
 			}
-			for (int i = 0; i < lettersInKmer; i++) {
+			for (int i = 0; i < lettersInKmer; i++) { // check letters
 				if (bytes[i + HEADER_SIZE] != rightKmer.bytes[i]) {
 					return false;
 				}
@@ -346,7 +244,7 @@
 	@Override
 	public String toString() {
 		return KmerUtil.recoverKmerFrom(this.lettersInKmer, this.getBytes(),
-				offset + HEADER_SIZE, this.getLength());
+				offset, this.getLength());
 	}
 
 	public static class Comparator extends WritableComparator {
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 3a8fb93..807ac13 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
@@ -229,14 +229,24 @@
         merge.mergeWithRFKmer(i, kmer2);
         Assert.assertEquals("GGCACAACAACCC", merge.toString());
         
-        String test1 = "CTA";
-        String test2 = "AGA";
-        KmerBytesWritable k1 = new KmerBytesWritable(3);
-        KmerBytesWritable k2 = new KmerBytesWritable(3);
-        k1.setByRead(test1.getBytes(), 0);
-        k2.setByRead(test2.getBytes(), 0);
-        k1.mergeWithRFKmer(3, k2);
-        Assert.assertEquals("CTAT", k1);
+//        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
     }
     
     
@@ -282,4 +292,22 @@
         }
     }
 
+    @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/VKmerBytesWritableTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/VKmerBytesWritableTest.java
new file mode 100644
index 0000000..0506a08
--- /dev/null
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/VKmerBytesWritableTest.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.genomix.data.test;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import edu.uci.ics.genomix.type.GeneCode;
+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;
+
+	@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");
+	}
+
+	@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);
+		}
+
+		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");
+
+		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");
+
+		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");
+	}
+
+	@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))));
+		}
+	}
+
+	@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 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());
+
+		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 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());
+				}
+			}
+		}
+	}
+
+	@Test
+	public void TestMergeFRKmer() {
+		int kmerSize = 3;
+		String result = "AAGCTAACAACC";
+		byte[] resultArray = result.getBytes();
+
+		String text1 = "AAGCTAA";
+		VKmerBytesWritable kmer1 = new VKmerBytesWritable(text1.length());
+		kmer1.setByRead(resultArray, 0);
+		Assert.assertEquals(text1, kmer1.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());
+
+		VKmerBytesWritable merge = new VKmerBytesWritable(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";
+		VKmerBytesWritable kmer1 = new VKmerBytesWritable(text1.length());
+		kmer1.setByRead(resultArray, 5);
+		Assert.assertEquals(text1, kmer1.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());
+
+		VKmerBytesWritable merge = new VKmerBytesWritable(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
+		// 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 ??
+
+		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
+	}
+
+	@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());
+
+		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());
+	}
+}
