finish Mapper and start Reducer
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 00aa633..c5576f6 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
@@ -109,7 +109,23 @@
         return reverseReverseList;
     }
     
-    public KmerListWritable getListFromDir(byte dir) {
+	public void setFFList(KmerListWritable forwardForwardList) {
+		this.forwardForwardList = forwardForwardList;
+	}
+
+	public void setFRList(KmerListWritable forwardReverseList) {
+		this.forwardReverseList = forwardReverseList;
+	}
+
+	public void setRFList(KmerListWritable reverseForwardList) {
+		this.reverseForwardList = reverseForwardList;
+	}
+
+	public void setRRList(KmerListWritable reverseReverseList) {
+		this.reverseReverseList = reverseReverseList;
+	}
+
+	public KmerListWritable getListFromDir(byte dir) {
         switch (dir & DirectionFlag.DIR_MASK) {
             case DirectionFlag.DIR_FF:
                 return getFFList();
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 b0f0488..3316d62 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
@@ -82,20 +82,154 @@
             if (KMER_SIZE >= array.length) {
                 throw new IOException("short read");
             }
+            
+            /** first kmer **/
             curForwardKmer.setByRead(array, 0);
             curReverseKmer.set(kmerFactory.reverse(curForwardKmer));
-            if(curForwardKmer.compareTo(curReverseKmer) >= 0)
-                curKmerDir = KmerDir.FORWARD;
-            else
-                curKmerDir = KmerDir.REVERSE;
-            nodeId.set(mateId, readID, 0);
+            curKmerDir = curForwardKmer.compareTo(curReverseKmer) >= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
             setNextKmer(array[KMER_SIZE]);
+            //set value.nodeId
+            nodeId.set(mateId, readID, 1);
+            outputNode.setNodeId(nodeId);
+            //set value.edgeList
+            setEdgeListForNextKmer();
+            //output mapper result
+            setMapperOutput(output);
+            
+            /** middle kmer **/
+            for (int i = KMER_SIZE + 1; i < array.length; i++) {
+            	setPreKmerByOldCurKmer();
+            	setCurKmerByOldNextKmer();
+            	setNextKmer(array[i]);
+        	    //set value.nodeId
+                nodeId.set(mateId, readID, i - KMER_SIZE + 1);
+                outputNode.setNodeId(nodeId);
+                //set value.edgeList
+                setEdgeListForPreKmer();
+                setEdgeListForNextKmer();
+                //output mapper result
+                setMapperOutput(output);
+            }
+            
+            /** last kmer **/
+        	setPreKmerByOldCurKmer();
+        	setCurKmerByOldNextKmer();
+        	//set value.nodeId
+            nodeId.set(mateId, readID, array.length - KMER_SIZE + 1);
+            outputNode.setNodeId(nodeId);
+            //set value.edgeList
+            setEdgeListForPreKmer();
+            //output mapper result
+            setMapperOutput(output);
         }
     }
     
+    public void setEdgeListForPreKmer(){
+    	switch(curKmerDir){
+    		case FORWARD:
+    			switch(preKmerDir){
+    				case FORWARD:
+    					kmerList.reset();
+    					kmerList.append(preForwardKmer);
+    					outputNode.setRRList(kmerList);
+    					break;
+    				case REVERSE:
+    					kmerList.reset();
+    					kmerList.append(preReverseKmer);
+    					outputNode.setRFList(kmerList);
+    					break;
+    			}
+    			break;
+    		case REVERSE:
+    			switch(preKmerDir){
+    				case FORWARD:
+    					kmerList.reset();
+    					kmerList.append(nextForwardKmer);
+    					outputNode.setFRList(kmerList);
+    					break;
+    				case REVERSE:
+    					kmerList.reset();
+    					kmerList.append(nextReverseKmer);
+    					outputNode.setFFList(kmerList);
+    					break;
+    			}
+    			break;
+    	}
+    }
+    
+    public void setEdgeListForNextKmer(){
+    	switch(curKmerDir){
+    		case FORWARD:
+    			switch(nextKmerDir){
+    				case FORWARD:
+    					kmerList.reset();
+    					kmerList.append(nextForwardKmer);
+    					outputNode.setFFList(kmerList);
+    					break;
+    				case REVERSE:
+    					kmerList.reset();
+    					kmerList.append(nextReverseKmer);
+    					outputNode.setFRList(kmerList);
+    					break;
+    			}
+    			break;
+    		case REVERSE:
+    			switch(nextKmerDir){
+    				case FORWARD:
+    					kmerList.reset();
+    					kmerList.append(nextForwardKmer);
+    					outputNode.setRFList(kmerList);
+    					break;
+    				case REVERSE:
+    					kmerList.reset();
+    					kmerList.append(nextReverseKmer);
+    					outputNode.setRRList(kmerList);
+    					break;
+    			}
+    			break;
+    	}
+    }
+    
+    //set preKmer by shifting curKmer with preChar
+    public void setPreKmer(byte preChar){
+        preForwardKmer.set(curForwardKmer);
+        preForwardKmer.shiftKmerWithPreChar(preChar);
+        preReverseKmer.set(preForwardKmer);
+        preReverseKmer.set(kmerFactory.reverse(nextForwardKmer));
+        preKmerDir = preForwardKmer.compareTo(preReverseKmer) >= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
+    }
+    
+    //set nextKmer by shifting curKmer with nextChar
     public void setNextKmer(byte nextChar){
         nextForwardKmer.set(curForwardKmer);
         nextForwardKmer.shiftKmerWithNextChar(nextChar);
-        nextForwardKmer.set(kmerFactory.reverse(nextForwardKmer));
+        nextReverseKmer.set(nextForwardKmer);
+        nextReverseKmer.set(kmerFactory.reverse(nextForwardKmer));
+        nextKmerDir = nextForwardKmer.compareTo(nextReverseKmer) >= 0 ? KmerDir.FORWARD : KmerDir.REVERSE;
+    }
+    
+    //old curKmer becomes current preKmer
+    public void setPreKmerByOldCurKmer(){
+    	preKmerDir = curKmerDir;
+    	preForwardKmer.set(curForwardKmer);
+    	preReverseKmer.set(curReverseKmer);
+    }
+    
+    //old nextKmer becomes current curKmer
+    public void setCurKmerByOldNextKmer(){
+    	curKmerDir = nextKmerDir;
+    	curForwardKmer.set(nextForwardKmer);
+    	preReverseKmer.set(nextReverseKmer);
+    }
+    
+    public void setMapperOutput(OutputCollector<KmerBytesWritable, NodeWritable> output) throws IOException{
+    	switch(curKmerDir){
+    	case FORWARD:
+    		output.collect(curForwardKmer, outputNode);
+    		break;
+    	case REVERSE:
+    		output.collect(curReverseKmer, outputNode);
+    		break;
+    }
     }
 }
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixReducer.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixReducer.java
new file mode 100644
index 0000000..a710eca
--- /dev/null
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixReducer.java
@@ -0,0 +1,26 @@
+package edu.uci.ics.genomix.hadoop.contrailgraphbuilding;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.hadoop.mapred.MapReduceBase;
+import org.apache.hadoop.mapred.OutputCollector;
+import org.apache.hadoop.mapred.Reducer;
+import org.apache.hadoop.mapred.Reporter;
+
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.NodeWritable;
+
+@SuppressWarnings("deprecation")
+public class GenomixReducer extends MapReduceBase implements
+	Reducer<KmerBytesWritable, NodeWritable, KmerBytesWritable, NodeWritable>{
+
+	@Override
+	public void reduce(KmerBytesWritable key, Iterator<NodeWritable> values,
+			OutputCollector<KmerBytesWritable, NodeWritable> output,
+			Reporter reporter) throws IOException {
+		// TODO Auto-generated method stub
+		
+	}
+
+}