Refactor KmerBytesWritable to use internal length
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..b2ba461 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
@@ -68,7 +68,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 +78,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 +90,7 @@
     }
 
     public void setKmer(KmerBytesWritable right) {
-        this.kmer.set(right);
+        this.kmer.setAsCopy(right);
     }
 
     public void reset(int kmerSize) {
@@ -163,7 +163,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 95bcaf8..b42b8f0 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
@@ -25,6 +25,7 @@
 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;
 
 /**
@@ -33,92 +34,92 @@
  * Thus the kmerByteSize of bytes doesn't change either.
  */
 public class KmerBytesWritable extends BinaryComparable implements Serializable, WritableComparable<BinaryComparable> {
-    /**
-	 * 
-	 */
+
     private static final long serialVersionUID = 1L;
-    private static final byte[] EMPTY_BYTES = {};
+    private static final byte[] EMPTY_BYTES = { 0, 0, 0, 0 }; // int indicating 0 length
+    private static final int HEADER_SIZE = 4; // number of bytes for header info
 
-    public int kmerByteSize;
-    protected byte[] bytes;
-    protected int offset;
-    protected int kmerlength;
+    private int lettersInKmer;
+    private int bytesUsed;
+    private byte[] bytes;
+    private int offset;
 
+    /**
+     * Initialize as empty kmer
+     */
     public KmerBytesWritable() {
-        this(0, EMPTY_BYTES, 0);
-    }
-
-    public KmerBytesWritable(int k, byte[] storage, int offset) {
-        setNewReference(k, storage, offset);
-    }
-
-    public KmerBytesWritable(int k, String kmer) {
-        setNewReference(kmer.length(), kmer.getBytes(), 0);
+        this(EMPTY_BYTES, 0);
     }
 
     /**
-     * Initial Kmer space by kmerlength
-     * 
-     * @param k
-     *            kmerlengthz
+     * Copy contents of kmer string
+     */
+    public KmerBytesWritable(String kmer) {
+        bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(kmer.length())];
+        setAsCopy(kmer);
+    }
+
+    /**
+     * Set as reference to given data
+     */
+    public KmerBytesWritable(byte[] storage, int offset) {
+        setAsReference(storage, offset);
+    }
+
+    /**
+     * Reserve space for k letters
      */
     public KmerBytesWritable(int k) {
-        this.kmerlength = k;
-        this.kmerByteSize = KmerUtil.getByteNumFromK(kmerlength);
         if (k > 0) {
-            this.bytes = new byte[this.kmerByteSize];
+            this.bytes = new byte[HEADER_SIZE + KmerUtil.getByteNumFromK(k)];
         } else {
             this.bytes = EMPTY_BYTES;
         }
         this.offset = 0;
+        setKmerLength(k);
     }
 
-    public KmerBytesWritable(KmerBytesWritable right) {
-        this(right.kmerlength);
-        set(right);
+    /**
+     * copy kmer in other
+     * 
+     * @param other
+     */
+    public KmerBytesWritable(KmerBytesWritable other) {
+        this(other.lettersInKmer);
+        setAsCopy(other);
     }
 
     /**
      * Deep copy of the given kmer
      * 
-     * @param newData
+     * @param other
      */
-    public void set(KmerBytesWritable newData) {
-        if (newData == null) {
-            this.set(0, EMPTY_BYTES, 0);
-        } else {
-            this.set(newData.kmerlength, newData.bytes, newData.getOffset());
+    public void setAsCopy(KmerBytesWritable other) {
+        reset(other.lettersInKmer);
+        if (lettersInKmer > 0) {
+            System.arraycopy(other.bytes, other.offset + HEADER_SIZE, bytes, this.offset + HEADER_SIZE, lettersInKmer);
         }
     }
 
     /**
+     * set from String kmer
+     */
+    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
-     * It will not change the kmerlength
      * 
      * @param newData
      * @param offset
      */
-    public void set(byte[] newData, int offset) {
-        if (kmerlength > 0) {
-            System.arraycopy(newData, offset, bytes, this.offset, kmerByteSize);
-        }
-    }
-
-    /**
-     * Deep copy of the given data, and also set to new kmerlength
-     * 
-     * @param k
-     *            : new kmer length
-     * @param newData
-     *            : data storage
-     * @param offset
-     *            : start offset
-     */
-    public void set(int k, byte[] newData, int offset) {
+    public void setAsCopy(byte[] newData, int offset) {
+        int k = Marshal.getInt(newData, offset);
         reset(k);
-        if (k > 0) {
-            System.arraycopy(newData, offset, bytes, this.offset, kmerByteSize);
-        }
+        System.arraycopy(newData, offset + HEADER_SIZE, bytes, this.offset + HEADER_SIZE, k);
     }
 
     /**
@@ -127,47 +128,36 @@
      * @param k
      */
     public void reset(int k) {
-        this.kmerlength = k;
-        setSize(KmerUtil.getByteNumFromK(k));
+        setKmerLength(k);
+        setSize(bytesUsed);
         clearLeadBit();
     }
 
     /**
      * Point this datablock to the given bytes array
      * It works like the pointer to new datablock.
-     * kmerlength will not change
+     * NOTE: kmerlength is NOT updated
      * 
      * @param newData
      * @param offset
      */
-    public void setNewReference(byte[] newData, int offset) {
+    public void setAsReference(byte[] newData, int offset) {
         this.bytes = newData;
         this.offset = offset;
-        if (newData.length - offset < kmerByteSize) {
-            throw new IllegalArgumentException("Not given enough space");
+        int kRequested = Marshal.getInt(newData, offset);
+        int bytesRequested = KmerUtil.getByteNumFromK(kRequested);
+        if (newData.length - offset < bytesRequested) {
+            throw new IllegalArgumentException("Requested " + bytesRequested + " bytes (k=" + kRequested
+                    + ") but buffer has only " + (newData.length - offset) + " bytes");
         }
-    }
-
-    /**
-     * Point this datablock to the given bytes array
-     * It works like the pointer to new datablock.
-     * It also set the new kmerlength
-     * 
-     * @param k
-     * @param newData
-     * @param offset
-     */
-    public void setNewReference(int k, byte[] newData, int offset) {
-        this.kmerlength = k;
-        this.kmerByteSize = KmerUtil.getByteNumFromK(k);
-        setNewReference(newData, offset);
+        setKmerLength(kRequested);
     }
 
     protected void setSize(int size) {
         if (size > getCapacity()) {
             setCapacity((size * 3 / 2));
         }
-        this.kmerByteSize = size;
+        this.bytesUsed = size;
     }
 
     protected int getCapacity() {
@@ -177,11 +167,11 @@
     protected void setCapacity(int new_cap) {
         if (new_cap != getCapacity()) {
             byte[] new_data = new byte[new_cap];
-            if (new_cap < kmerByteSize) {
-                kmerByteSize = new_cap;
+            if (new_cap < bytesUsed) {
+                bytesUsed = new_cap;
             }
-            if (kmerByteSize != 0) {
-                System.arraycopy(bytes, offset, new_data, 0, kmerByteSize);
+            if (bytesUsed != 0) {
+                System.arraycopy(bytes, offset, new_data, 0, bytesUsed);
             }
             bytes = new_data;
             offset = 0;
@@ -196,21 +186,27 @@
      * @return
      */
     public byte getGeneCodeAtPosition(int pos) {
-        if (pos >= kmerlength) {
+        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 + kmerByteSize - 1 - posByte] >> shift) & 0x3);
+        return (byte) ((bytes[offset + bytesUsed - 1 - posByte] >> shift) & 0x3);
     }
-    
+
+    public void setKmerLength(int k) {
+        this.bytesUsed = HEADER_SIZE + KmerUtil.getByteNumFromK(k);
+        this.lettersInKmer = k;
+        Marshal.putInt(k, bytes, offset);
+    }
+
     public int getKmerLength() {
-        return this.kmerlength;
+        return lettersInKmer;
     }
 
     @Override
@@ -224,7 +220,7 @@
 
     @Override
     public int getLength() {
-        return kmerByteSize;
+        return bytesUsed;
     }
 
     /**
@@ -232,25 +228,26 @@
      * [0x000G, 0xATAA]
      * 
      * @param k
-     * @param array
+     * @param stringBytes
+     *            : byte array from a _string_. Meaning there's no header
      * @param start
      */
-    public void setByRead(byte[] array, int start) {
+    public void setByRead(byte[] stringBytes, int start) {
         byte l = 0;
         int bytecount = 0;
-        int bcount = this.kmerByteSize - 1;
-        for (int i = start; i < start + kmerlength && i < array.length; i++) {
-            byte code = GeneCode.getCodeFromSymbol(array[i]);
+        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;
+                bytes[offset + HEADER_SIZE + bcount--] = l;
                 l = 0;
                 bytecount = 0;
             }
         }
         if (bcount >= 0) {
-            bytes[offset] = l;
+            bytes[offset + HEADER_SIZE] = l;
         }
     }
 
@@ -272,20 +269,20 @@
     public void setByReadReverse(byte[] array, int start) {
         byte l = 0;
         int bytecount = 0;
-        int bcount = kmerByteSize - 1;
-//        for (int i = start + kmerlength - 1; i >= 0 && i < array.length; i--) {
-        for (int i = start + kmerlength - 1; i >= start && i < array.length; i--) {
+        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;
+                bytes[offset + HEADER_SIZE + bcount--] = l;
                 l = 0;
                 bytecount = 0;
             }
         }
         if (bcount >= 0) {
-            bytes[offset] = l;
+            bytes[offset + HEADER_SIZE] = l;
         }
     }
 
@@ -313,14 +310,14 @@
      * @return the shift out gene, in gene code format
      */
     public byte shiftKmerWithNextCode(byte c) {
-        byte output = (byte) (bytes[offset + kmerByteSize - 1] & 0x03);
-        for (int i = kmerByteSize - 1; i > 0; i--) {
-            byte in = (byte) (bytes[offset + i - 1] & 0x03);
-            bytes[offset + i] = (byte) (((bytes[offset + i] >>> 2) & 0x3f) | (in << 6));
+        byte output = (byte) (bytes[offset + HEADER_SIZE + bytesUsed - 1] & 0x03);
+        for (int i = bytesUsed - 1; i > 0; i--) {
+            byte in = (byte) (bytes[offset + HEADER_SIZE + i - 1] & 0x03);
+            bytes[offset + HEADER_SIZE + i] = (byte) (((bytes[offset + HEADER_SIZE + i] >>> 2) & 0x3f) | (in << 6));
         }
-        int pos = ((kmerlength - 1) % 4) << 1;
+        int pos = ((lettersInKmer - 1) % 4) << 1;
         byte code = (byte) (c << pos);
-        bytes[offset] = (byte) (((bytes[offset] >>> 2) & 0x3f) | code);
+        bytes[offset + HEADER_SIZE] = (byte) (((bytes[offset + HEADER_SIZE] >>> 2) & 0x3f) | code);
         clearLeadBit();
         return output;
     }
@@ -344,13 +341,13 @@
      * @return the shiftout gene, in gene code format
      */
     public byte shiftKmerWithPreCode(byte c) {
-        int pos = ((kmerlength - 1) % 4) << 1;
-        byte output = (byte) ((bytes[offset] >> pos) & 0x03);
-        for (int i = 0; i < kmerByteSize - 1; i++) {
-            byte in = (byte) ((bytes[offset + i + 1] >> 6) & 0x03);
-            bytes[offset + i] = (byte) ((bytes[offset + i] << 2) | in);
+        int pos = ((lettersInKmer - 1) % 4) << 1;
+        byte output = (byte) ((bytes[offset + HEADER_SIZE] >> pos) & 0x03);
+        for (int i = 0; i < bytesUsed - 1; i++) {
+            byte in = (byte) ((bytes[offset + HEADER_SIZE + i + 1] >> 6) & 0x03);
+            bytes[offset + HEADER_SIZE + i] = (byte) ((bytes[offset + HEADER_SIZE + i] << 2) | in);
         }
-        bytes[offset + kmerByteSize - 1] = (byte) ((bytes[offset + kmerByteSize - 1] << 2) | c);
+        bytes[offset + HEADER_SIZE + bytesUsed - 1] = (byte) ((bytes[offset + HEADER_SIZE + bytesUsed - 1] << 2) | c);
         clearLeadBit();
         return output;
     }
@@ -366,16 +363,16 @@
      *            : the next kmer
      */
     public void mergeWithFFKmer(int initialKmerSize, KmerBytesWritable kmer) {
-        int preKmerLength = kmerlength;
-        int preSize = kmerByteSize;
-        this.kmerlength += kmer.kmerlength - initialKmerSize + 1;
-        setSize(KmerUtil.getByteNumFromK(kmerlength));
+        int preKmerLength = lettersInKmer;
+        int preSize = bytesUsed;
+        lettersInKmer += kmer.lettersInKmer - initialKmerSize + 1;
+        setSize(KmerUtil.getByteNumFromK(lettersInKmer));
         for (int i = 1; i <= preSize; i++) {
-            bytes[offset + kmerByteSize - i] = bytes[offset + preSize - i];
+            bytes[offset + HEADER_SIZE + 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, kmerByteSize);
+            appendOneByteAtPosition(preKmerLength + k - initialKmerSize + 1, onebyte, bytes, offset + HEADER_SIZE, bytesUsed);
         }
         clearLeadBit();
     }
@@ -384,8 +381,7 @@
      * 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~
+     * A merge B => A B~
      * 
      * @param initialKmerSize
      *            : the initial kmerSize
@@ -393,31 +389,31 @@
      *            : the next kmer
      */
     public void mergeWithFRKmer(int initialKmerSize, KmerBytesWritable kmer) {
-        int preSize = kmerByteSize;
-        int preKmerLength = kmerlength;
-        this.kmerlength += kmer.kmerlength - initialKmerSize + 1;
-        setSize(KmerUtil.getByteNumFromK(kmerlength));
+        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 + kmerByteSize - i] = bytes[offset + preSize - i];
+            bytes[offset + HEADER_SIZE + bytesUsed - i] = bytes[offset + HEADER_SIZE + preSize - i];
         }
 
         int bytecount = (preKmerLength % 4) * 2;
-        int bcount = kmerByteSize - preSize - bytecount / 8; // may overlap previous kmer
-        byte l = bcount == kmerByteSize - preSize ? bytes[offset + bcount] : 0x00;
+        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.kmerlength - initialKmerSize; i >= 0; i--) {
+        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;
+                bytes[offset + HEADER_SIZE + bcount--] = l;
                 l = 0;
                 bytecount = 0;
             }
         }
         if (bcount >= 0) {
-            bytes[offset] = l;
+            bytes[offset + HEADER_SIZE] = l;
         }
     }
 
@@ -432,18 +428,18 @@
      *            : the previous kmer
      */
     public void mergeWithRFKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-        int preKmerLength = kmerlength;
-        int preSize = kmerByteSize;
-        this.kmerlength += preKmer.kmerlength - initialKmerSize + 1;
-        setSize(KmerUtil.getByteNumFromK(kmerlength));
+        int preKmerLength = lettersInKmer;
+        int preSize = bytesUsed;
+        lettersInKmer += preKmer.lettersInKmer - initialKmerSize + 1;
+        setSize(KmerUtil.getByteNumFromK(lettersInKmer));
         //        byte cacheByte = getOneByteFromKmerAtPosition(0, bytes, offset, preSize);
 
-        int byteIndex = kmerByteSize - 1;
+        int byteIndex = bytesUsed - 1;
         byte cacheByte = 0x00;
         int posnInByte = 0;
 
         // copy rc of preKmer into high bytes
-        for (int i = preKmer.kmerlength - 1; i >= initialKmerSize - 1; i--) {
+        for (int i = preKmer.lettersInKmer - 1; i >= initialKmerSize - 1; i--) {
             byte code = GeneCode.getPairedGeneCode(preKmer.getGeneCodeAtPosition(i));
             cacheByte |= (byte) (code << posnInByte);
             posnInByte += 2;
@@ -453,11 +449,11 @@
                 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 + (kmerByteSize - preSize) * 4;
+            // 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;
@@ -467,7 +463,7 @@
                 posnInByte = 0;
             }
         }
-        bytes[offset] = cacheByte;
+        bytes[offset + HEADER_SIZE] = cacheByte;
         clearLeadBit();
     }
 
@@ -482,31 +478,32 @@
      *            : the previous kmer
      */
     public void mergeWithRRKmer(int initialKmerSize, KmerBytesWritable preKmer) {
-        int preKmerLength = kmerlength;
-        int preSize = kmerByteSize;
-        this.kmerlength += preKmer.kmerlength - initialKmerSize + 1;
-        setSize(KmerUtil.getByteNumFromK(kmerlength));
+        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.kmerlength - initialKmerSize + 1; k += 4) {
-            byte onebyte = getOneByteFromKmerAtPosition(k, preKmer.bytes, preKmer.offset, preKmer.kmerByteSize);
-            appendOneByteAtPosition(k, onebyte, bytes, offset, kmerByteSize);
+        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 + HEADER_SIZE, bytesUsed);
         }
 
         // copy current kmer
         int k = 4;
         for (; k < preKmerLength; k += 4) {
             byte onebyte = getOneByteFromKmerAtPosition(k, bytes, offset, preSize);
-            appendOneByteAtPosition(preKmer.kmerlength - initialKmerSize + k - 4 + 1, cacheByte, bytes, offset, kmerByteSize);
+            appendOneByteAtPosition(preKmer.lettersInKmer - initialKmerSize + k - 4 + 1, cacheByte, bytes, offset + HEADER_SIZE,
+                    bytesUsed);
             cacheByte = onebyte;
         }
-        appendOneByteAtPosition(preKmer.kmerlength - initialKmerSize + k - 4 + 1, cacheByte, bytes, offset, kmerByteSize);
+        appendOneByteAtPosition(preKmer.lettersInKmer - initialKmerSize + k - 4 + 1, cacheByte, bytes, offset + HEADER_SIZE, bytesUsed);
         clearLeadBit();
     }
-    
+
     public void mergeWithKmerInDir(byte dir, int initialKmerSize, KmerBytesWritable kmer) {
-        switch(dir & DirectionFlag.DIR_MASK) {
+        switch (dir & DirectionFlag.DIR_MASK) {
             case DirectionFlag.DIR_FF:
                 mergeWithFFKmer(initialKmerSize, kmer);
                 break;
@@ -520,7 +517,7 @@
                 mergeWithRRKmer(initialKmerSize, kmer);
                 break;
             default:
-                throw new RuntimeException("Direciotn not recognized: " + dir);
+                throw new RuntimeException("Direction not recognized: " + dir);
         }
     }
 
@@ -552,61 +549,62 @@
     }
 
     protected void clearLeadBit() {
-        if (kmerlength % 4 != 0) {
-            bytes[offset] &= (1 << ((kmerlength % 4) << 1)) - 1;
+        if (lettersInKmer % 4 != 0) {
+            bytes[offset + HEADER_SIZE] &= (1 << ((lettersInKmer % 4) << 1)) - 1;
         }
     }
 
     @Override
     public void readFields(DataInput in) throws IOException {
-        this.kmerlength = in.readInt();
-        this.kmerByteSize = KmerUtil.getByteNumFromK(kmerlength);
-        if (this.kmerlength > 0) {
-            if (this.bytes.length < this.kmerByteSize) {
-                this.bytes = new byte[this.kmerByteSize];
+        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, kmerByteSize);
+            in.readFully(bytes, offset + HEADER_SIZE, bytesUsed - HEADER_SIZE);
         }
+        Marshal.putInt(lettersInKmer, bytes, offset);
     }
 
     @Override
     public void write(DataOutput out) throws IOException {
-        out.writeInt(kmerlength);
-        if (kmerlength > 0) {
-            out.write(bytes, offset, kmerByteSize);
+        out.writeInt(lettersInKmer);
+        if (lettersInKmer > 0) {
+            out.write(bytes, offset + HEADER_SIZE, bytesUsed - HEADER_SIZE);
         }
     }
 
     @Override
     public int hashCode() {
-        return super.hashCode() * 31 + this.kmerlength;
+        return super.hashCode() * 31 + this.lettersInKmer;
     }
 
     @Override
     public boolean equals(Object right_obj) {
         if (right_obj instanceof KmerBytesWritable)
-            return this.kmerlength == ((KmerBytesWritable) right_obj).kmerlength && super.equals(right_obj);
+            return this.lettersInKmer == ((KmerBytesWritable) right_obj).lettersInKmer && super.equals(right_obj);
         return false;
     }
 
     @Override
     public String toString() {
-        return KmerUtil.recoverKmerFrom(this.kmerlength, this.getBytes(), offset, this.getLength());
+        return KmerUtil.recoverKmerFrom(this.lettersInKmer, this.getBytes(), offset + HEADER_SIZE, this.getLength());
     }
 
     public static class Comparator extends WritableComparator {
-        public final int LEAD_BYTES = 4;
 
         public Comparator() {
             super(KmerBytesWritable.class);
         }
 
         public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
-            int kmerlength1 = readInt(b1, s1);
-            int kmerlength2 = readInt(b2, s2);
+            int kmerlength1 = Marshal.getInt(b1, s1);
+            int kmerlength2 = Marshal.getInt(b2, s2);
             if (kmerlength1 == kmerlength2) {
-                return compareBytes(b1, s1 + LEAD_BYTES, l1 - LEAD_BYTES, b2, s2 + LEAD_BYTES, l2 - LEAD_BYTES);
+                return compareBytes(b1, s1 + HEADER_SIZE, l1 - HEADER_SIZE, b2, s2 + HEADER_SIZE, l2 - HEADER_SIZE);
             }
             return kmerlength1 - kmerlength2;
         }
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 d2e3a94..f805610 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
@@ -64,7 +64,7 @@
             return null;
         }
         if (lastK == kmerChain.getKmerLength()) {
-            kmer.set(kmerChain);
+            kmer.setAsCopy(kmerChain);
             return kmer;
         }
         kmer.reset(lastK);
@@ -100,7 +100,7 @@
             return null;
         }
         if (firstK == kmerChain.getKmerLength()) {
-            kmer.set(kmerChain);
+            kmer.setAsCopy(kmerChain);
             return kmer;
         }
         kmer.reset(firstK);
@@ -124,7 +124,7 @@
             return null;
         }
         if (startK == 0 && kSize == kmerChain.getKmerLength()) {
-            kmer.set(kmerChain);
+            kmer.setAsCopy(kmerChain);
             return kmer;
         }
         kmer.reset(kSize);
@@ -256,7 +256,7 @@
      * @return new created kmer that shifted by afterCode, the K will not change
      */
     public KmerBytesWritable shiftKmerWithNextCode(final KmerBytesWritable kmer, byte afterCode) {
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
         this.kmer.shiftKmerWithNextCode(afterCode);
         return this.kmer;
     }
@@ -274,7 +274,7 @@
      * @return new created kmer that shifted by preCode, the K will not change
      */
     public KmerBytesWritable shiftKmerWithPreCode(final KmerBytesWritable kmer, byte preCode) {
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
         this.kmer.shiftKmerWithPreCode(preCode);
         return this.kmer;
     }
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 88bb79c..e434989 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
@@ -116,7 +116,7 @@
         if (i >= valueCount) {
             throw new ArrayIndexOutOfBoundsException("No such positions");
         }
-        posIter.setNewReference(kmerlength, storage, offset + i * kmerByteSize);
+        posIter.setAsReference(kmerlength, storage, offset + i * kmerByteSize);
         return posIter;
     }
     
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 efa87f7..98e37dc 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
@@ -63,7 +63,7 @@
         this.forwardReverseList.set(FRList);
         this.reverseForwardList.set(RFList);
         this.reverseReverseList.set(RRList);
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
     }
 
     public void reset(int kmerSize) {
@@ -90,7 +90,7 @@
     }
 
     public void setKmer(KmerBytesWritable kmer) {
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
     }
     
     public int getKmerlength() {
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 b4361ac..3a8fb93 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
@@ -131,7 +131,7 @@
         Assert.assertEquals(text1 + text2.substring(kmerSize - 1), merge.toString());
 
         for (int i = 1; i < 8; i++) {
-            merge.set(kmer1);
+            merge.setAsCopy(kmer1);
             merge.mergeWithFFKmer(i, kmer2);
             Assert.assertEquals(text1 + text2.substring(i - 1), merge.toString());
         }
@@ -147,7 +147,7 @@
                 Assert.assertEquals(text1, kmer1.toString());
                 Assert.assertEquals(text2, kmer2.toString());
                 for (int x = 1; x < jk; x++) {
-                    merge.set(kmer1);
+                    merge.setAsCopy(kmer1);
                     merge.mergeWithFFKmer(x, kmer2);
                     Assert.assertEquals(text1 + text2.substring(x - 1), merge.toString());
                 }
@@ -177,17 +177,17 @@
         Assert.assertEquals(result, merge.toString());
         
         int i = 1;
-        merge.set(kmer1);
+        merge.setAsCopy(kmer1);
         merge.mergeWithFRKmer(i, kmer2);
         Assert.assertEquals("AAGCTAAAACAACC", merge.toString());
         
         i = 2;
-        merge.set(kmer1);
+        merge.setAsCopy(kmer1);
         merge.mergeWithFRKmer(i, kmer2);
         Assert.assertEquals("AAGCTAAACAACC", merge.toString());
         
         i = 3;
-        merge.set(kmer1);
+        merge.setAsCopy(kmer1);
         merge.mergeWithFRKmer(i, kmer2);
         Assert.assertEquals("AAGCTAACAACC", merge.toString());
     }
@@ -215,17 +215,17 @@
         Assert.assertEquals(result, merge.toString());
         
         int i = 1;
-        merge.set(kmer1);
+        merge.setAsCopy(kmer1);
         merge.mergeWithRFKmer(i, kmer2);
         Assert.assertEquals("GGCACAAAACAACCC", merge.toString());
         
         i = 2;
-        merge.set(kmer1);
+        merge.setAsCopy(kmer1);
         merge.mergeWithRFKmer(i, kmer2);
         Assert.assertEquals("GGCACAAACAACCC", merge.toString());
         
         i = 3;
-        merge.set(kmer1);
+        merge.setAsCopy(kmer1);
         merge.mergeWithRFKmer(i, kmer2);
         Assert.assertEquals("GGCACAACAACCC", merge.toString());
         
@@ -258,7 +258,7 @@
         Assert.assertEquals(text1 + text2.substring(kmerSize - 1), merge.toString());
 
         for (int i = 1; i < 8; i++) {
-            merge.set(kmer2);
+            merge.setAsCopy(kmer2);
             merge.mergeWithRRKmer(i, kmer1);
             Assert.assertEquals(text1.substring(0, text1.length() - i + 1) + text2, merge.toString());
         }
@@ -274,7 +274,7 @@
                 Assert.assertEquals(text1, kmer1.toString());
                 Assert.assertEquals(text2, kmer2.toString());
                 for (int x = 1; x < ik; x++) {
-                    merge.set(kmer2);
+                    merge.setAsCopy(kmer2);
                     merge.mergeWithRRKmer(x, kmer1);
                     Assert.assertEquals(text1.substring(0, text1.length() - x + 1) + text2, merge.toString());
                 }
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java
index 98f561f..1ad6cf0 100644
--- a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java
@@ -201,7 +201,7 @@
     
     //set preKmer by shifting curKmer with preChar
     public void setPreKmer(byte preChar){
-        preForwardKmer.set(curForwardKmer);
+        preForwardKmer.setAsCopy(curForwardKmer);
         preForwardKmer.shiftKmerWithPreChar(preChar);
         preReverseKmer.setByReadReverse(preForwardKmer.toString().getBytes(), preForwardKmer.getOffset());
         preKmerDir = preForwardKmer.compareTo(preReverseKmer) <= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
@@ -209,7 +209,7 @@
     
     //set nextKmer by shifting curKmer with nextChar
     public void setNextKmer(byte nextChar){
-        nextForwardKmer.set(curForwardKmer);
+        nextForwardKmer.setAsCopy(curForwardKmer);
         nextForwardKmer.shiftKmerWithNextChar(nextChar);
         nextReverseKmer.setByReadReverse(nextForwardKmer.toString().getBytes(), nextForwardKmer.getOffset());
         nextKmerDir = nextForwardKmer.compareTo(nextReverseKmer) <= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
@@ -218,15 +218,15 @@
     //old curKmer becomes current preKmer
     public void setPreKmerByOldCurKmer(){
     	preKmerDir = curKmerDir;
-    	preForwardKmer.set(curForwardKmer);
-    	preReverseKmer.set(curReverseKmer);
+    	preForwardKmer.setAsCopy(curForwardKmer);
+    	preReverseKmer.setAsCopy(curReverseKmer);
     }
     
     //old nextKmer becomes current curKmer
     public void setCurKmerByOldNextKmer(){
     	curKmerDir = nextKmerDir;
-    	curForwardKmer.set(nextForwardKmer);
-    	curReverseKmer.set(nextReverseKmer);
+    	curForwardKmer.setAsCopy(nextForwardKmer);
+    	curReverseKmer.setAsCopy(nextReverseKmer);
     }
     
     public void setMapperOutput(OutputCollector<KmerBytesWritable, NodeWritable> output) throws IOException{
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/graphclean/removetips/RemoveTips.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/graphclean/removetips/RemoveTips.java
index 83fe200..f1bfec6 100644
--- a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/graphclean/removetips/RemoveTips.java
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/graphclean/removetips/RemoveTips.java
@@ -60,7 +60,7 @@
                 // kill this node by NOT mapping it.  Update my neighbors with a suicide note
                 //TODO: update neighbors by removing me from its list
             } else {
-                outputValue.set(MergeMessageFlag.MSG_SELF, curNode);
+                outputValue.setAsCopy(MergeMessageFlag.MSG_SELF, curNode);
                 output.collect(key, value);
             }
         }
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/velvetgraphbuilding/PositionListAndKmerWritable.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/velvetgraphbuilding/PositionListAndKmerWritable.java
index 943b505..550cc7c 100644
--- a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/velvetgraphbuilding/PositionListAndKmerWritable.java
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/velvetgraphbuilding/PositionListAndKmerWritable.java
@@ -54,12 +54,12 @@
     public void set(PositionListAndKmerWritable right) {
         this.countOfKmer = right.countOfKmer;
         this.vertexIDList.set(right.vertexIDList);
-        this.kmer.set(right.kmer);
+        this.kmer.setAsCopy(right.kmer);
     }
 
     public void set(PositionListWritable list, KmerBytesWritable kmer) {
         this.vertexIDList.set(list);
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
     }
     
     @Override
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/AggregateKmerAggregateFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/AggregateKmerAggregateFactory.java
index d9efd75..d14405e 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/AggregateKmerAggregateFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/AggregateKmerAggregateFactory.java
@@ -88,7 +88,7 @@
                 reverseForwardList.reset(kmerSize);
                 reverseReverseList.reset(kmerSize);
                 
-                kmer.set(accessor.getBuffer().array(), getOffSet(accessor, tIndex, 1));//??从1算起??
+                kmer.setAsCopy(accessor.getBuffer().array(), getOffSet(accessor, tIndex, 1));//??从1算起??
                 nodeIdList.setNewReference(1, accessor.getBuffer().array(), getOffSet(accessor, tIndex, 2));
                 int ffCount = Marshal.getInt(accessor.getBuffer().array(), getOffSet(accessor, tIndex, 3));//??
                 forwardForwardList.setNewReference(ffCount, accessor.getBuffer().array(), getOffSet(accessor, tIndex, 4));
@@ -100,7 +100,7 @@
                 reverseForwardList.setNewReference(rrCount, accessor.getBuffer().array(), getOffSet(accessor, tIndex, 10));
                 nodeAggreter.set(nodeIdList, forwardForwardList, forwardReverseList, reverseForwardList, reverseForwardList, kmer);
                 
-                inputVal.getKmer().set(kmer);
+                inputVal.getKmer().setAsCopy(kmer);
                 inputVal.getNodeIdList().appendList(nodeIdList);
                 inputVal.getFFList().appendList(forwardForwardList);
                 inputVal.getFRList().appendList(forwardReverseList);
@@ -115,7 +115,7 @@
             public void aggregate(IFrameTupleAccessor accessor, int tIndex, IFrameTupleAccessor stateAccessor,
                     int stateTupleIndex, AggregateState state) throws HyracksDataException {
                 NodeWritable inputVal = (NodeWritable) state.state;
-                kmer.set(accessor.getBuffer().array(), getOffSet(accessor, tIndex, 1));//??从1算起??
+                kmer.setAsCopy(accessor.getBuffer().array(), getOffSet(accessor, tIndex, 1));//??从1算起??
                 nodeIdList.setNewReference(1, accessor.getBuffer().array(), getOffSet(accessor, tIndex, 2));
                 int ffCount = Marshal.getInt(accessor.getBuffer().array(), getOffSet(accessor, tIndex, 3));//??
                 forwardForwardList.setNewReference(ffCount, accessor.getBuffer().array(), getOffSet(accessor, tIndex, 4));
@@ -127,7 +127,7 @@
                 reverseForwardList.setNewReference(rrCount, accessor.getBuffer().array(), getOffSet(accessor, tIndex, 10));
                 nodeAggreter.set(nodeIdList, forwardForwardList, forwardReverseList, reverseForwardList, reverseForwardList, kmer);
                 
-                inputVal.getKmer().set(kmer);
+                inputVal.getKmer().setAsCopy(kmer);
                 inputVal.getNodeIdList().appendList(nodeIdList);
                 inputVal.getFFList().appendList(forwardForwardList);
                 inputVal.getFRList().appendList(forwardReverseList);
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/ReadsKeyValueParserFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/ReadsKeyValueParserFactory.java
index 7280dff..3adf8a0 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/ReadsKeyValueParserFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/contrail/graph/ReadsKeyValueParserFactory.java
@@ -150,10 +150,10 @@
                 }
                 /** first kmer **/
                 curForwardKmer.setByRead(array, 0);
-                curReverseKmer.set(kmerFactory.reverse(curForwardKmer));
+                curReverseKmer.setAsCopy(kmerFactory.reverse(curForwardKmer));
                 curKmerDir = curForwardKmer.compareTo(curReverseKmer) >= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
                 setNextKmer(array[kmerSize]);
-                readId.set(mateId, readID);
+                readId.setAsCopy(mateId, readID);
                 outputNode.setreadId(readId);
                 setEdgeListForNextKmer();
                 switch (curKmerDir) {
@@ -170,7 +170,7 @@
                     setCurKmerByOldNextKmer();
                     setNextKmer(array[i]);
                     //set value.readId
-                    readId.set(mateId, readID);
+                    readId.setAsCopy(mateId, readID);
                     outputNode.setreadId(readId);
                     //set value.edgeList
                     setEdgeListForPreKmer();
@@ -189,7 +189,7 @@
                 setPreKmerByOldCurKmer();
                 setCurKmerByOldNextKmer();
                 //set value.readId
-                readId.set(mateId, readID);
+                readId.setAsCopy(mateId, readID);
                 outputNode.setreadId(readId);
                 //set value.edgeList
                 setEdgeListForPreKmer();
@@ -205,32 +205,32 @@
             }
 
             public void setPreKmer(byte preChar){
-                preForwardKmer.set(curForwardKmer);
+                preForwardKmer.setAsCopy(curForwardKmer);
                 preForwardKmer.shiftKmerWithPreChar(preChar);
-                preReverseKmer.set(preForwardKmer);
-                preReverseKmer.set(kmerFactory.reverse(nextForwardKmer));
+                preReverseKmer.setAsCopy(preForwardKmer);
+                preReverseKmer.setAsCopy(kmerFactory.reverse(nextForwardKmer));
                 preKmerDir = preForwardKmer.compareTo(preReverseKmer) >= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
             }
             
             public void setNextKmer(byte nextChar) {
-                nextForwardKmer.set(curForwardKmer);
+                nextForwardKmer.setAsCopy(curForwardKmer);
                 nextForwardKmer.shiftKmerWithNextChar(nextChar);
-                nextReverseKmer.set(nextForwardKmer);
-                nextReverseKmer.set(kmerFactory.reverse(nextForwardKmer));
+                nextReverseKmer.setAsCopy(nextForwardKmer);
+                nextReverseKmer.setAsCopy(kmerFactory.reverse(nextForwardKmer));
                 nextKmerDir = nextForwardKmer.compareTo(nextReverseKmer) >= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
             }
 
             public void setPreKmerByOldCurKmer() {
                 preKmerDir = curKmerDir;
-                preForwardKmer.set(curForwardKmer);
-                preReverseKmer.set(curReverseKmer);
+                preForwardKmer.setAsCopy(curForwardKmer);
+                preReverseKmer.setAsCopy(curReverseKmer);
             }
 
             //old nextKmer becomes current curKmer
             public void setCurKmerByOldNextKmer() {
                 curKmerDir = nextKmerDir;
-                curForwardKmer.set(nextForwardKmer);
-                preReverseKmer.set(nextReverseKmer);
+                curForwardKmer.setAsCopy(nextForwardKmer);
+                preReverseKmer.setAsCopy(nextReverseKmer);
             }
 
             public void setEdgeListForNextKmer() {
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/MapReadToNodeOperator.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/MapReadToNodeOperator.java
index 0f0aa29..f376f71 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/MapReadToNodeOperator.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/MapReadToNodeOperator.java
@@ -186,7 +186,7 @@
                 throw new IllegalArgumentException("kmer kmerByteSize is invalid");
             }
             offset += INT_LENGTH;
-            kmer.set(buffer.array(), offset);
+            kmer.setAsCopy(buffer.array(), offset);
         }
 
         private void connect(NodeReference curNode, NodeReference nextNode) {
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerSequenceWriterFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerSequenceWriterFactory.java
index f6c2cf9..aabdb3f 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerSequenceWriterFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerSequenceWriterFactory.java
@@ -70,7 +70,7 @@
                 if (reEnterKey.getLength() > tuple.getFieldLength(InputKmerField)) {
                     throw new IllegalArgumentException("Not enough kmer bytes");
                 }
-                reEnterKey.setNewReference(tuple.getFieldData(InputKmerField), tuple.getFieldStart(InputKmerField));
+                reEnterKey.setAsReference(tuple.getFieldData(InputKmerField), tuple.getFieldStart(InputKmerField));
                 int countOfPos = tuple.getFieldLength(InputPositionListField) / PositionWritable.LENGTH;
                 if (tuple.getFieldLength(InputPositionListField) % PositionWritable.LENGTH != 0) {
                     throw new IllegalArgumentException("Invalid count of position byte");
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerTextWriterFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerTextWriterFactory.java
index e7526ed..91f10be 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerTextWriterFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/KMerTextWriterFactory.java
@@ -49,7 +49,7 @@
                 if (kmer.getLength() > tuple.getFieldLength(KMerSequenceWriterFactory.InputKmerField)) {
                     throw new IllegalArgumentException("Not enough kmer bytes");
                 }
-                kmer.setNewReference(tuple.getFieldData(KMerSequenceWriterFactory.InputKmerField),
+                kmer.setAsReference(tuple.getFieldData(KMerSequenceWriterFactory.InputKmerField),
                         tuple.getFieldStart(KMerSequenceWriterFactory.InputKmerField));
                 int countOfPos = tuple.getFieldLength(KMerSequenceWriterFactory.InputPositionListField)
                         / PositionWritable.LENGTH;
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeSequenceWriterFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeSequenceWriterFactory.java
index 77efcf8..1651d4a 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeSequenceWriterFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeSequenceWriterFactory.java
@@ -94,7 +94,7 @@
             node.getRRList().setNewReference(tuple.getFieldLength(InputRRField) / PositionWritable.LENGTH,
                     tuple.getFieldData(InputRRField), tuple.getFieldStart(InputRRField));
 
-            node.getKmer().setNewReference(
+            node.getKmer().setAsReference(
                     Marshal.getInt(tuple.getFieldData(NodeSequenceWriterFactory.InputCountOfKmerField),
                             tuple.getFieldStart(NodeSequenceWriterFactory.InputCountOfKmerField)),
                     tuple.getFieldData(InputKmerBytesField), tuple.getFieldStart(InputKmerBytesField));
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeTextWriterFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeTextWriterFactory.java
index dffd3a9..3ca4a9d 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeTextWriterFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/dataflow/io/NodeTextWriterFactory.java
@@ -69,7 +69,7 @@
                         tuple.getFieldData(NodeSequenceWriterFactory.InputRRField),
                         tuple.getFieldStart(NodeSequenceWriterFactory.InputRRField));
 
-                node.getKmer().setNewReference(
+                node.getKmer().setAsReference(
                         Marshal.getInt(tuple.getFieldData(NodeSequenceWriterFactory.InputCountOfKmerField),
                                 tuple.getFieldStart(NodeSequenceWriterFactory.InputCountOfKmerField)),
                         tuple.getFieldData(NodeSequenceWriterFactory.InputKmerBytesField),
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenCheckReader.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenCheckReader.java
index c3ec3c7..07d16f8 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenCheckReader.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenCheckReader.java
@@ -89,7 +89,7 @@
                                             .getFieldLength(ReadsKeyValueParserFactory.OutputKmerField)) {
                                         throw new IllegalArgumentException("Not enough kmer bytes");
                                     }
-                                    kmer.setNewReference(
+                                    kmer.setAsReference(
                                             tuple.getFieldData(ReadsKeyValueParserFactory.OutputKmerField),
                                             tuple.getFieldStart(ReadsKeyValueParserFactory.OutputKmerField));
                                     pos.setNewReference(tuple.getFieldData(ReadsKeyValueParserFactory.OutputPosition),
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenGroupbyReadID.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenGroupbyReadID.java
index 559060a..fa5360c 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenGroupbyReadID.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenGroupbyReadID.java
@@ -121,7 +121,7 @@
                                                     throw new IllegalArgumentException("kmerlength is invalid");
                                                 }
                                                 fieldOffset += 4;
-                                                kmer.setNewReference(buffer, fieldOffset);
+                                                kmer.setAsReference(buffer, fieldOffset);
                                                 fieldOffset += kmer.getLength();
                                                 kmerString = kmer.toString();
                                             }
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenMapKmerToRead.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenMapKmerToRead.java
index e9aede5..09b1680 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenMapKmerToRead.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/job/JobGenMapKmerToRead.java
@@ -93,7 +93,7 @@
                                                 .getFieldLength(MapKmerPositionToReadOperator.OutputKmerField)) {
                                             throw new IllegalArgumentException("Not enough kmer bytes");
                                         }
-                                        kmer.setNewReference(
+                                        kmer.setAsReference(
                                                 tuple.getFieldData(MapKmerPositionToReadOperator.OutputKmerField),
                                                 tuple.getFieldStart(MapKmerPositionToReadOperator.OutputKmerField));
                                         kmerString = kmer.toString();
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java
index 1b123f1..22b2ae7 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java
@@ -169,7 +169,7 @@
             }
             
             public void setNextKmer(byte nextChar){
-                nextForwardKmer.set(curForwardKmer);
+                nextForwardKmer.setAsCopy(curForwardKmer);
                 nextForwardKmer.shiftKmerWithNextChar(nextChar);
                 nextReverseKmer.setByReadReverse(nextForwardKmer.toString().getBytes(), nextForwardKmer.getOffset());
                 nextKmerDir = nextForwardKmer.compareTo(nextReverseKmer) <= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
@@ -177,14 +177,14 @@
             
             public void setPreKmerByOldCurKmer(){
                 preKmerDir = curKmerDir;
-                preForwardKmer.set(curForwardKmer);
-                preReverseKmer.set(curReverseKmer);
+                preForwardKmer.setAsCopy(curForwardKmer);
+                preReverseKmer.setAsCopy(curReverseKmer);
             }
 
             public void setCurKmerByOldNextKmer(){
                 curKmerDir = nextKmerDir;
-                curForwardKmer.set(nextForwardKmer);
-                curReverseKmer.set(nextReverseKmer);
+                curForwardKmer.setAsCopy(nextForwardKmer);
+                curReverseKmer.setAsCopy(nextReverseKmer);
             }
             
             public void writeToFrame(IFrameWriter writer) {
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/job/JobGenCheckReader.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/job/JobGenCheckReader.java
index 6026ac1..6d64cfd 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/job/JobGenCheckReader.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/job/JobGenCheckReader.java
@@ -88,10 +88,10 @@
                                         throw new IllegalArgumentException("Not enough kmer bytes");
                                     }
                                     //kemr
-                                    kmer.setNewReference(
+                                    kmer.setAsReference(
                                             tuple.getFieldData(ReadsKeyValueParserFactory.OutputKmerField),
                                             tuple.getFieldStart(ReadsKeyValueParserFactory.OutputKmerField));
-                                    kmerList.setNewReference(tuple.getFieldLength(ReadsKeyValueParserFactory.OutputNodeIdField), 
+                                    kmerList.setAsReference(tuple.getFieldLength(ReadsKeyValueParserFactory.OutputNodeIdField), 
                                             tuple.getFieldData(ReadsKeyValueParserFactory.OutputNodeIdField), 
                                             tuple.getFieldStart(ReadsKeyValueParserFactory.OutputNodeIdField));
 //                                    //nodeId
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/GraphCleanInputFormat.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/GraphCleanInputFormat.java
index e36e344..e8a72ce 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/GraphCleanInputFormat.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/GraphCleanInputFormat.java
@@ -60,7 +60,7 @@
             /**
              * set the src vertex id
              */
-            vertexId.set(getRecordReader().getCurrentKey());
+            vertexId.setAsCopy(getRecordReader().getCurrentKey());
             vertex.setVertexId(vertexId);
             /**
              * set the vertex value
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/InitialGraphCleanInputFormat.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/InitialGraphCleanInputFormat.java
index 0d685de..5c8f9c2 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/InitialGraphCleanInputFormat.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/InitialGraphCleanInputFormat.java
@@ -64,7 +64,7 @@
             /**
              * set the src vertex id
              */
-            vertexId.set(getRecordReader().getCurrentKey());
+            vertexId.setAsCopy(getRecordReader().getCurrentKey());
             vertex.setVertexId(vertexId);
             /**
              * set the vertex value
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MergeBubbleMessageWritable.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MergeBubbleMessageWritable.java
index c3b4710..c3e02a0 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MergeBubbleMessageWritable.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MergeBubbleMessageWritable.java
@@ -42,7 +42,7 @@
         }
         if (chainVertexId != null) {
             checkMessage |= CheckMessage.CHAIN;
-            this.chainVertexId.set(msg.getChainVertexId());
+            this.chainVertexId.setAsCopy(msg.getChainVertexId());
         }
         if (neighberNode != null) {
             checkMessage |= CheckMessage.NEIGHBER;
@@ -63,7 +63,7 @@
         }
         if (chainVertexId != null) {
             checkMessage |= CheckMessage.CHAIN;
-            this.chainVertexId.set(chainVertexId);
+            this.chainVertexId.setAsCopy(chainVertexId);
         }
         if (neighberNode != null) {
             checkMessage |= CheckMessage.NEIGHBER;
@@ -101,7 +101,7 @@
     public void setChainVertexId(KmerBytesWritable chainVertexId) {
         if (chainVertexId != null) {
             checkMessage |= CheckMessage.CHAIN;
-            this.chainVertexId.set(chainVertexId);
+            this.chainVertexId.setAsCopy(chainVertexId);
         }
     }
     
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MessageWritable.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MessageWritable.java
index 1c5f325..ea91144 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MessageWritable.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/MessageWritable.java
@@ -49,11 +49,11 @@
         checkMessage = 0;
         if (sourceVertexId != null) {
             checkMessage |= CheckMessage.SOURCE;
-            this.sourceVertexId.set(msg.getSourceVertexId());
+            this.sourceVertexId.setAsCopy(msg.getSourceVertexId());
         }
         if (kmer != null) {
             checkMessage |= CheckMessage.CHAIN;
-            this.kmer.set(msg.getKmer());
+            this.kmer.setAsCopy(msg.getKmer());
         }
         if (neighberNode != null) {
             checkMessage |= CheckMessage.NEIGHBER;
@@ -68,11 +68,11 @@
         checkMessage = 0;
         if (sourceVertexId != null) {
             checkMessage |= CheckMessage.SOURCE;
-            this.sourceVertexId.set(sourceVertexId);
+            this.sourceVertexId.setAsCopy(sourceVertexId);
         }
         if (chainVertexId != null) {
             checkMessage |= CheckMessage.CHAIN;
-            this.kmer.set(chainVertexId);
+            this.kmer.setAsCopy(chainVertexId);
         }
         if (neighberNode != null) {
             checkMessage |= CheckMessage.NEIGHBER;
@@ -102,7 +102,7 @@
     public void setSourceVertexId(KmerBytesWritable sourceVertexId) {
         if (sourceVertexId != null) {
             checkMessage |= CheckMessage.SOURCE;
-            this.sourceVertexId.set(sourceVertexId);
+            this.sourceVertexId.setAsCopy(sourceVertexId);
         }
     }
     
@@ -113,7 +113,7 @@
     public void setChainVertexId(KmerBytesWritable chainVertexId) {
         if (chainVertexId != null) {
             checkMessage |= CheckMessage.CHAIN;
-            this.kmer.set(chainVertexId);
+            this.kmer.setAsCopy(chainVertexId);
         }
     }
     
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
index 5d06234..d472fd1 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
@@ -74,7 +74,7 @@
         this.outgoingList.setForwardList(forwardForwardList);
         this.outgoingList.setReverseList(forwardReverseList);
         this.state = state;
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
     }
     
     public void set(VertexValueWritable value) {
@@ -157,7 +157,7 @@
     }
 
     public void setKmer(KmerBytesWritable kmer) {
-        this.kmer.set(kmer);
+        this.kmer.setAsCopy(kmer);
     }
     
     public KmerBytesWritable getMergeDest() {
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/LogAlgorithmLogFormatter.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/LogAlgorithmLogFormatter.java
index 5f6440f..27e2683 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/LogAlgorithmLogFormatter.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/LogAlgorithmLogFormatter.java
@@ -32,8 +32,8 @@
     public void set(long step, KmerBytesWritable sourceVertexId, KmerBytesWritable destVertexId,
             MessageWritable msg, byte state) {
         this.step = step;
-        this.sourceVertexId.set(sourceVertexId);
-        this.destVertexId.set(destVertexId);
+        this.sourceVertexId.setAsCopy(sourceVertexId);
+        this.destVertexId.setAsCopy(destVertexId);
         this.msg = msg;
         this.state = state;
         this.operation = 0;
@@ -42,15 +42,15 @@
     public void setMergeChain(long step, KmerBytesWritable sourceVertexId, KmerBytesWritable mergeChain) {
         this.reset();
         this.step = step;
-        this.sourceVertexId.set(sourceVertexId);
-        this.mergeChain.set(mergeChain);
+        this.sourceVertexId.setAsCopy(sourceVertexId);
+        this.mergeChain.setAsCopy(mergeChain);
         this.operation = 2;
     }
 
     public void setVotoToHalt(long step, KmerBytesWritable sourceVertexId) {
         this.reset();
         this.step = step;
-        this.sourceVertexId.set(sourceVertexId);
+        this.sourceVertexId.setAsCopy(sourceVertexId);
         this.operation = 3;
     }
 
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/NaiveAlgorithmLogFormatter.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/NaiveAlgorithmLogFormatter.java
index 4a5850a..6b23074 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/NaiveAlgorithmLogFormatter.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/log/NaiveAlgorithmLogFormatter.java
@@ -15,8 +15,8 @@
 
     public void set(long step, KmerBytesWritable sourceVertexId, KmerBytesWritable destVertexId) {
         this.step = step;
-        this.sourceVertexId.set(sourceVertexId);
-        this.destVertexId.set(destVertexId);
+        this.sourceVertexId.setAsCopy(sourceVertexId);
+        this.destVertexId.setAsCopy(destVertexId);
     }
 
     public String format(LogRecord record) {
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/BasicPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/BasicPathMergeVertex.java
index 937fa42..9acba97 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/BasicPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/BasicPathMergeVertex.java
@@ -128,12 +128,12 @@
     public void sendMsgToAllNextNodes(VertexValueWritable value) {
         posIterator = value.getFFList().iterator(); // FFList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getFRList().iterator(); // FRList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
     }
@@ -144,12 +144,12 @@
     public void sendMsgToAllPreviousNodes(VertexValueWritable value) {
         posIterator = value.getRFList().iterator(); // RFList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getRRList().iterator(); // RRList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
     }
@@ -160,22 +160,22 @@
     public void sendMsgToAllNeighborNodes(VertexValueWritable value){
         posIterator = value.getFFList().iterator(); // FFList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getFRList().iterator(); // FRList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getFFList().iterator(); // FFList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getFRList().iterator(); // FRList
         while(posIterator.hasNext()){
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
     }
@@ -188,14 +188,14 @@
         while(posIterator.hasNext()){
             outgoingMsg.setFlag(AdjMessage.FROMFF);
             outgoingMsg.setSourceVertexId(getVertexId());
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getFRList().iterator(); // FRList
         while(posIterator.hasNext()){
             outgoingMsg.setFlag(AdjMessage.FROMFR);
             outgoingMsg.setSourceVertexId(getVertexId());
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
     }
@@ -208,14 +208,14 @@
         while(posIterator.hasNext()){
             outgoingMsg.setFlag(AdjMessage.FROMRF);
             outgoingMsg.setSourceVertexId(getVertexId());
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
         posIterator = value.getRRList().iterator(); // RRList
         while(posIterator.hasNext()){
             outgoingMsg.setFlag(AdjMessage.FROMRR);
             outgoingMsg.setSourceVertexId(getVertexId());
-            destVertexId.set(posIterator.next());
+            destVertexId.setAsCopy(posIterator.next());
             sendMsg(destVertexId, outgoingMsg);
         }
     }
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/LogAlgorithmForPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/LogAlgorithmForPathMergeVertex.java
index 7185616..feb22aa 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/LogAlgorithmForPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/LogAlgorithmForPathMergeVertex.java
@@ -67,7 +67,7 @@
         //send wantToMerge to next
         tempPostition = getNextDestVertexIdAndSetFlag(getVertexValue());
         if(tempPostition != null){
-            destVertexId.set(tempPostition);
+            destVertexId.setAsCopy(tempPostition);
             outgoingMsg.setFlag(outFlag);
             outgoingMsg.setSourceVertexId(getVertexId());
             sendMsg(destVertexId, outgoingMsg);
@@ -76,7 +76,7 @@
         ////send wantToMerge to prev
         tempPostition = getPreDestVertexIdAndSetFlag(getVertexValue());
         if(tempPostition != null){
-            destVertexId.set(tempPostition);
+            destVertexId.setAsCopy(tempPostition);
             outgoingMsg.setFlag(outFlag);
             outgoingMsg.setSourceVertexId(getVertexId());
             sendMsg(destVertexId, outgoingMsg);
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/NaiveAlgorithmForPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/NaiveAlgorithmForPathMergeVertex.java
index a65f556..ac43c62 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/NaiveAlgorithmForPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/NaiveAlgorithmForPathMergeVertex.java
@@ -184,7 +184,7 @@
      */
     public void mergeChainVertex() {
         //merge chain
-        lastKmer.set(kmerFactory.getLastKmerFromChain(incomingMsg.getLengthOfChain() - kmerSize + 1,
+        lastKmer.setAsCopy(kmerFactory.getLastKmerFromChain(incomingMsg.getLengthOfChain() - kmerSize + 1,
                 incomingMsg.getKmer()));
         getVertexValue().setKmer(kmerFactory.mergeTwoKmer(getVertexValue().getKmer(), lastKmer));
         getVertexValue().setOutgoingList(incomingMsg.getNeighberNode());
@@ -225,7 +225,7 @@
         outgoingMsg.setChainVertexId(getVertexValue().getKmer());
         if (getVertexValue().getState() == State.IS_HEAD)//is_tail
             outgoingMsg.setFlag(Message.STOP);
-        destVertexId.set(incomingMsg.getSourceVertexId());
+        destVertexId.setAsCopy(incomingMsg.getSourceVertexId());
         sendMsg(destVertexId, outgoingMsg);
     }
 
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P3ForPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P3ForPathMergeVertex.java
index f2bb3db..fd3a1db 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P3ForPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P3ForPathMergeVertex.java
@@ -230,7 +230,7 @@
      * merge chain vertex
      */
     public void mergeChainVertex(){
-        lastKmer.set(kmerFactory.getLastKmerFromChain(incomingMsg.getLengthOfChain() - kmerSize + 1,
+        lastKmer.setAsCopy(kmerFactory.getLastKmerFromChain(incomingMsg.getLengthOfChain() - kmerSize + 1,
                 incomingMsg.getKmer()));
         getVertexValue().setKmer(
                 kmerFactory.mergeTwoKmer(getVertexValue().getKmer(), 
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P4ForPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P4ForPathMergeVertex.java
index 94428ca..e6c5f34 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P4ForPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P4ForPathMergeVertex.java
@@ -111,12 +111,12 @@
      */
     protected boolean setNextInfo(VertexValueWritable value) {
         if (value.getFFList().getCountOfPosition() > 0) {
-            nextKmer.set(value.getFFList().getPosition(0));
+            nextKmer.setAsCopy(value.getFFList().getPosition(0));
             nextHead = isNodeRandomHead(nextKmer);
             return true;
         }
         if (value.getFRList().getCountOfPosition() > 0) {
-            nextKmer.set(value.getFRList().getPosition(0));
+            nextKmer.setAsCopy(value.getFRList().getPosition(0));
             nextHead = isNodeRandomHead(nextKmer);
             return true;
         }
@@ -128,12 +128,12 @@
      */
     protected boolean setPrevInfo(VertexValueWritable value) {
         if (value.getRRList().getCountOfPosition() > 0) {
-            prevKmer.set(value.getRRList().getPosition(0));
+            prevKmer.setAsCopy(value.getRRList().getPosition(0));
             prevHead = isNodeRandomHead(prevKmer);
             return true;
         }
         if (value.getRFList().getCountOfPosition() > 0) {
-            prevKmer.set(value.getRFList().getPosition(0));
+            prevKmer.setAsCopy(value.getRFList().getPosition(0));
             prevHead = isNodeRandomHead(prevKmer);
             return true;
         }
@@ -156,7 +156,7 @@
             setStateAsNoMerge();
             
             // only PATH vertices are present. Find the ID's for my neighbors
-            curKmer.set(getVertexId());
+            curKmer.setAsCopy(getVertexId());
             
             curHead = isNodeRandomHead(curKmer);
             
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P5ForPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P5ForPathMergeVertex.java
index 8a2a301..7f8a832 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P5ForPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P5ForPathMergeVertex.java
@@ -113,12 +113,12 @@
      */
     protected boolean setNextInfo(VertexValueWritable value) {
         if (value.getFFList().getCountOfPosition() > 0) {
-            nextID.set(value.getFFList().getPosition(0));
+            nextID.setAsCopy(value.getFFList().getPosition(0));
             nextHead = isNodeRandomHead(nextID);
             return true;
         }
         if (value.getFRList().getCountOfPosition() > 0) {
-            nextID.set(value.getFRList().getPosition(0));
+            nextID.setAsCopy(value.getFRList().getPosition(0));
             nextHead = isNodeRandomHead(nextID);
             return true;
         }
@@ -130,12 +130,12 @@
      */
     protected boolean setPrevInfo(VertexValueWritable value) {
         if (value.getRRList().getCountOfPosition() > 0) {
-            prevID.set(value.getRRList().getPosition(0));
+            prevID.setAsCopy(value.getRRList().getPosition(0));
             prevHead = isNodeRandomHead(prevID);
             return true;
         }
         if (value.getRFList().getCountOfPosition() > 0) {
-            prevID.set(value.getRFList().getPosition(0));
+            prevID.setAsCopy(value.getRFList().getPosition(0));
             prevHead = isNodeRandomHead(prevID);
             return true;
         }
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/tipremove/TipRemoveVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/tipremove/TipRemoveVertex.java
index 7141ae7..9b83d19 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/tipremove/TipRemoveVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/tipremove/TipRemoveVertex.java
@@ -71,7 +71,7 @@
             		else if(getVertexValue().getFRList().getCountOfPosition() > 0)
             			outgoingMsg.setFlag(AdjMessage.FROMFR);
             		outgoingMsg.setSourceVertexId(getVertexId());
-            		destVertexId.set(getNextDestVertexId(getVertexValue()));
+            		destVertexId.setAsCopy(getNextDestVertexId(getVertexValue()));
             		sendMsg(destVertexId, outgoingMsg);
             		deleteVertex(getVertexId());
             	}
@@ -83,7 +83,7 @@
                     else if(getVertexValue().getRRList().getCountOfPosition() > 0)
                         outgoingMsg.setFlag(AdjMessage.FROMRR);
                     outgoingMsg.setSourceVertexId(getVertexId());
-                    destVertexId.set(getPreDestVertexId(getVertexValue()));
+                    destVertexId.setAsCopy(getPreDestVertexId(getVertexValue()));
                     sendMsg(destVertexId, outgoingMsg);
                     deleteVertex(getVertexId());
                 }