diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 1f2af51..96cc43e 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -11,6 +11,7 @@
       <entry name="!?*.flex" />
       <entry name="!?*.kt" />
       <entry name="!?*.clj" />
+      <entry name="!?*.aj" />
     </wildcardResourcePatterns>
     <annotationProcessing>
       <profile default="true" name="Default" enabled="false">
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 97626ba..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Encoding">
-    <file url="PROJECT" charset="UTF-8" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 7ac24c7..fe72da5 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -3,8 +3,9 @@
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
-        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="distributionType" value="LOCAL" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleHome" value="C:\Program Files\Android\Android Studio\gradle\gradle-2.14.1" />
         <option name="modules">
           <set>
             <option value="$PROJECT_DIR$" />
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 62fabb1..5d19981 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -37,26 +37,10 @@
     <ConfirmationsSetting value="0" id="Add" />
     <ConfirmationsSetting value="0" id="Remove" />
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">
     <option name="id" value="Android" />
   </component>
-  <component name="masterDetails">
-    <states>
-      <state key="ProjectJDKs.UI">
-        <settings>
-          <last-edited>Android API 10 Platform</last-edited>
-          <splitter-proportions>
-            <option name="proportions">
-              <list>
-                <option value="0.2" />
-              </list>
-            </option>
-          </splitter-proportions>
-        </settings>
-      </state>
-    </states>
-  </component>
 </project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+    <mapping directory="" vcs="Git" />
   </component>
 </project>
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 604b5f6..12ce42a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -43,4 +43,7 @@ dependencies {
     }
 
 
+    testCompile 'junit:junit:4.12'
+    testCompile 'org.mockito:mockito-core:1.10.19'
+
 }
diff --git a/app/src/main/assets/desc.json b/app/src/main/assets/desc.json
index 72e152b..1e936f0 100644
--- a/app/src/main/assets/desc.json
+++ b/app/src/main/assets/desc.json
@@ -94,6 +94,16 @@
       "<a href='https://github.com/naman14/AlgorithmVisualizer-Android/blob/master/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java'>SortingVisualizer</a>"
     ]
   },
+  "merge_sort": {
+    "Merge Sort": "Merge Sort is a Divide and Conquer algorithm. It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves",
+    "Complexity": {
+      "Time": "worst O(n log(n)), best O(n log(n)), average O(n log(n))",
+      "Space": "worst O(n) auxiliary"
+    },
+    "References": [
+      "<a href='https://en.wikipedia.org/wiki/Merge_sort'>Wikipedia<a/><br>"
+    ]
+  },
   "linked_list": {
     "Singly linked list": "A Linked List is a linear collection of data elements, called nodes, each pointing to the next node by means of a pointer. It is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a reference (in other words, a link) to the next node in the sequence. ",
     "Complexity": {
diff --git a/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java b/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java
index a810f86..f74f931 100644
--- a/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java
+++ b/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java
@@ -65,6 +65,42 @@ public class AlgorithmCode {
             " addLog(\"Array has been sorted\");\n" +
             " completed();";
 
+    public static final String CODE_MERGE_SORT = "" +
+            "public void mergeSort(int start, int end){\n" +
+            "   if (start >= end){\n" +
+            "       return;\n" +
+            "   }\n" +
+            "   int middle = (start + end)/2;\n" +
+            "   mergeSort(start,middle);\n" +
+            "   mergeSort(middle+1,end);\n" +
+            "   merge(start,middle,middle+1,end);\n" +
+            "}\n" +
+            "public void merge(int start1, int end1, int start2, int end2){\n" +
+            "   List<Integer> sortedList = new ArrayList<Integer>();\n" +
+            "   List<Integer> indexes = new ArrayList<Integer>();\n" +
+            "   int s0 = start1;\n" +
+            "   while(start1 <= end1){\n" +
+            "       if (start2 > end2){\n" +
+            "           sortedList.add(array[start1]);\n" +
+            "               start1+=1;\n" +
+            "               continue;\n" +
+            "       }\n" +
+            "       if (array[start1] <= array[start2]){\n" +
+            "           sortedList.add(array[start1]);\n" +
+            "           start1+=1;\n" +
+            "       }\n" +
+            "       else{\n" +
+            "           sortedList.add(array[start2]);\n" +
+            "           start2+=1;\n" +
+            "       }\n" +
+            "   }\n" +
+            "   int i = 0;\n" +
+            "   for (int number:sortedList) {\n" +
+            "       array[s0+i]=number;\n" +
+            "       i+=1;\n" +
+            "   }\n" +
+            "}";
+
     public static final String CODE_BST_SEARCH = " int id = DataUtils.getRandomKeyFromBST();\n" +
             " addLog(\"Searching for \" + String.valueOf(id));\n" +
             " BinarySearchTree.Node current = b.getRoot();\n" +
diff --git a/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java b/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java
index bc3eb40..f443f07 100644
--- a/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java
+++ b/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java
@@ -67,6 +67,9 @@ public void setCode(String key) {
                 case Algorithm.SELECTION_SORT:
                     addCodeItem(AlgorithmCode.CODE_SELECTION_SORT,"Selection sort");
                     break;
+                case Algorithm.MERGE_SORT:
+                    addCodeItem(AlgorithmCode.CODE_MERGE_SORT, "Merge sort");
+                    break;
                 case Algorithm.BST_SEARCH:
                     addCodeItem(AlgorithmCode.CODE_BST_SEARCH, "BST Search");
                     break;
diff --git a/app/src/main/java/com/naman14/algovisualizer/MainActivity.java b/app/src/main/java/com/naman14/algovisualizer/MainActivity.java
index 391868c..1dc72b5 100644
--- a/app/src/main/java/com/naman14/algovisualizer/MainActivity.java
+++ b/app/src/main/java/com/naman14/algovisualizer/MainActivity.java
@@ -93,6 +93,10 @@ public boolean onChildClick(ExpandableListView expandableListView, View view, in
                                 break;
                             case 2:
                                 algoFragment.setupFragment(Algorithm.SELECTION_SORT);
+                                break;
+                            case 3:
+                                algoFragment.setupFragment(Algorithm.MERGE_SORT);
+                                break;
                         }
                         break;
                     case 2:
@@ -208,6 +212,7 @@ private void prepareListData() {
         heading2.add("Bubble Sort");
         heading2.add("Insertion Sort");
         heading2.add("Selection Sort");
+        heading2.add("Merge Sort");
         List<String> heading3 = new ArrayList<String>();
         heading3.add("BST Search");
         heading3.add("BST Insert");
diff --git a/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java b/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java
index d6756d0..dd1243d 100644
--- a/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java
+++ b/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java
@@ -41,6 +41,7 @@
 import com.naman14.algovisualizer.algorithm.search.LinearSearch;
 import com.naman14.algovisualizer.algorithm.sorting.BubbleSort;
 import com.naman14.algovisualizer.algorithm.sorting.InsertionSort;
+import com.naman14.algovisualizer.algorithm.sorting.MergeSort;
 import com.naman14.algovisualizer.algorithm.sorting.SelectionSort;
 import com.naman14.algovisualizer.algorithm.tree.bst.BSTAlgorithm;
 import com.naman14.algovisualizer.visualizer.AlgorithmVisualizer;
@@ -190,6 +191,12 @@ public void setupFragment(String algorithmKey) {
                 algorithm = new SelectionSort((SortingVisualizer) visualizer, getActivity(), logFragment);
                 ((SelectionSort) algorithm).setData(DataUtils.createRandomArray(15));
                 break;
+            case Algorithm.MERGE_SORT:
+                visualizer = new SortingVisualizer(getActivity());
+                appBarLayout.addView(visualizer);
+                algorithm = new MergeSort((SortingVisualizer)visualizer, getActivity(), logFragment);
+                ((MergeSort)algorithm).setData(DataUtils.createRandomArray(15));
+                break;
             case Algorithm.BST_SEARCH:
                 visualizer = new BSTVisualizer(getActivity());
                 appBarLayout.addView(visualizer);
diff --git a/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java b/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java
index 349452a..080db75 100644
--- a/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java
+++ b/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java
@@ -42,6 +42,7 @@ public class Algorithm extends HandlerThread {
     public static final String DFS = "dfs";
     public static final String DIJKSTRA = "dijkstra";
     public static final String BELLMAN_FORD = "bellman_ford";
+    public static final String MERGE_SORT = "merge_sort";
 
 
     public LogFragment logFragment;
diff --git a/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/MergeSort.java b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/MergeSort.java
new file mode 100644
index 0000000..328807a
--- /dev/null
+++ b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/MergeSort.java
@@ -0,0 +1,99 @@
+package com.naman14.algovisualizer.algorithm.sorting;
+
+import android.app.Activity;
+
+import com.naman14.algovisualizer.LogFragment;
+import com.naman14.algovisualizer.algorithm.Algorithm;
+import com.naman14.algovisualizer.algorithm.DataHandler;
+import com.naman14.algovisualizer.visualizer.SortingVisualizer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by sergio on 02/01/17.
+ */
+
+public class MergeSort extends SortAlgorithm implements DataHandler {
+
+    private int[] array;
+
+    public MergeSort(SortingVisualizer visualizer, Activity activity, LogFragment logFragment) {
+        this.visualizer = visualizer;
+        this.activity = activity;
+        this.logFragment = logFragment;
+    }
+
+    private void sort(){
+        logArray("Original array - " ,array);
+        mergeSort(0,array.length-1);
+        completed();
+    }
+
+    public void mergeSort(int start, int end){
+        addLog("Sorting array between " + start + " and " + end);
+        if (start >= end){
+            return;
+        }
+        int middle = (start + end)/2;
+        highlightInterval(start,middle);
+        sleep();
+        mergeSort(start,middle);
+        highlightInterval(middle+1,end);
+        sleep();
+        mergeSort(middle+1,end);
+        highlightInterval(start,end);
+        sleep();
+        merge(start,middle,middle+1,end);
+    }
+
+    public void merge(int start1, int end1, int start2, int end2){
+        addLog("merging sub-array " + start1 + " to " + end1 + " and subarray " + start2 + " to " +
+        end2);
+        List<Integer> sortedList = new ArrayList<Integer>();
+        int s0 = start1;
+        while(start1 <= end1){
+            if (start2 > end2){
+                sortedList.add(array[start1]);
+                start1+=1;
+                continue;
+            }
+            if (array[start1] <= array[start2]){
+                sortedList.add(array[start1]);
+                start1+=1;
+            }
+            else{
+                sortedList.add(array[start2]);
+                start2+=1;
+            }
+        }
+        int i = 0;
+        for (int number:sortedList) {
+            array[s0+i]=number;
+            i+=1;
+        }
+        sleep();
+    }
+
+    @Override
+    public void run() {
+        super.run();
+    }
+
+    @Override
+    public void onDataRecieved(Object data) {
+        super.onDataRecieved(data);
+        this.array = (int[])data;
+
+    }
+
+    @Override
+    public void onMessageReceived(String message) {
+        super.onMessageReceived(message);
+        if(message.equals(Algorithm.COMMAND_START_ALGORITHM)){
+            startExecution();
+            sort();
+        }
+
+    }
+}
diff --git a/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java
index 3b4b3cb..b804e7c 100644
--- a/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java
+++ b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java
@@ -52,6 +52,24 @@ public void run() {
         });
     }
 
+    public void highlightInterval(final int start, final int end){
+        activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                visualizer.highlightInterval(start,end);
+            }
+        });
+    }
+
+    public void resetInterval(){
+        activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                visualizer.highlightInterval(-1,-1);
+            }
+        });
+    }
+
     @Override
     public void onDataRecieved(Object data) {
 
diff --git a/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java b/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java
index 709c948..4bebf38 100644
--- a/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java
+++ b/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java
@@ -32,6 +32,8 @@ public class SortingVisualizer extends AlgorithmVisualizer {
     int highlightPositionOne = -1, highlightPositionTwo = -1;
     int highlightPosition = -1;
     int lineStrokeWidth = getDimensionInPixel(10);
+    int startInterval, endInterval = -1;
+
 
     public SortingVisualizer(Context context) {
         super(context);
@@ -72,14 +74,23 @@ protected void onDraw(Canvas canvas) {
             for (int i = 0; i < array.length; i++) {
 
                 if (i == highlightPositionOne || i == highlightPositionTwo) {
-                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()), xPos, getHeight(), highlightPaintSwap);
+                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+                            xPos, getHeight(), highlightPaintSwap);
                 } else if (i == highlightPosition)
-                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()), xPos, getHeight(), highlightPaintTrace);
+                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+                            xPos, getHeight(), highlightPaintTrace);
+                else if (startInterval >= 0 && endInterval >= startInterval &&
+                        i >= startInterval && i <= endInterval) {
+                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+                            xPos, getHeight(), highlightPaintTrace);
+                }
                 else {
-                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()), xPos, getHeight(), paint);
+                    canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+                            xPos, getHeight(), paint);
                 }
 
-                canvas.drawText(String.valueOf(array[i]), xPos - lineStrokeWidth / 3, getHeight() - (float) ((array[i] / 10.0) * getHeight()) - 30, textPaint);
+                canvas.drawText(String.valueOf(array[i]), xPos - lineStrokeWidth / 3,
+                        getHeight() - (float) ((array[i] / 10.0) * getHeight()) - 30, textPaint);
 
                 xPos += margin + 30;
             }
@@ -111,11 +122,23 @@ public void highlightTrace(int position) {
         invalidate();
     }
 
+    public void highlightInterval(int start, int end){
+        this.startInterval = start;
+        this.endInterval = end;
+        invalidate();
+    }
+
+    public void resetHighlightInterval(){
+        highlightInterval(-1,-1);
+    }
+
     @Override
     public void onCompleted() {
         this.highlightPosition = -1;
         this.highlightPositionTwo = -1;
         this.highlightPositionOne = -1;
+        this.startInterval = -1;
+        this.endInterval = -1;
         invalidate();
     }
 }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index eb96b43..e75c5cd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,4 +2,6 @@
     <string name="app_name">AlgorithmVisualizer</string>
     <string name="action_settings">Settings</string>
     <string name="report_bugs">Report any bugs <u> here </u></string>
+    <string name="fabric_api_key">key</string>
+    <string name="play_billing_license_key">key</string>
 </resources>
diff --git a/app/src/test/java/com/naman14/algovisualizer/MergeSortTest.java b/app/src/test/java/com/naman14/algovisualizer/MergeSortTest.java
new file mode 100644
index 0000000..7b6dd51
--- /dev/null
+++ b/app/src/test/java/com/naman14/algovisualizer/MergeSortTest.java
@@ -0,0 +1,87 @@
+package com.naman14.algovisualizer;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.test.mock.MockContext;
+
+import com.naman14.algovisualizer.algorithm.sorting.MergeSort;
+import com.naman14.algovisualizer.visualizer.SortingVisualizer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+/**
+ * Created by sergio on 02/01/17.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class MergeSortTest {
+
+    @Mock
+    private SortingVisualizer mSortVisualizer;
+    @Mock
+    private Activity mActivity;
+    @Mock
+    private LogFragment mLogFragment;
+
+    private MergeSort mergeSort;
+
+    public MergeSortTest(){
+
+    }
+
+    @Before
+    public void before(){
+        mergeSort = new MergeSort(mSortVisualizer, mActivity,mLogFragment);
+    }
+
+    @Test
+    public void mergeSort() throws Exception {
+        int [] array = new int[] {4,1,2,4,6,8,7,10,9};
+        int [] sortedArray = new int [] {1,2,4,4,6,7,8,9,10};
+
+        mergeSort.onDataRecieved(array);
+        mergeSort.mergeSort(0,array.length-1);
+
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i],sortedArray[i]);
+        }
+    }
+
+    @Test
+    public void mergeSort_empty_array() throws Exception{
+        int [] array = new int[]{};
+        mergeSort.onDataRecieved(array);
+        mergeSort.mergeSort(0,array.length-1);
+        assertEquals(array.length,0);
+    }
+
+    @Test
+    public void mergeSort_one_element_array() throws Exception{
+        int [] array = new int[]{1};
+        mergeSort.onDataRecieved(array);
+        mergeSort.mergeSort(0,array.length-1);
+        assertEquals(array.length,1);
+        assertEquals(array[0],1);
+    }
+
+    @Test
+    public void merge() throws Exception {
+
+        int [] array = new int[] {1,5,6,7,1,2,3,10};
+        int [] mergedArray = new int[] {1,1,2,3,5,6,7,10};
+        mergeSort.onDataRecieved(array);
+        mergeSort.merge(1,3,4,6);
+
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i],mergedArray[i]);
+        }
+    }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index e5fbd9f..efa7225 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
         maven { url 'https://maven.fabric.io/public' }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.1.0'
+        classpath 'com.android.tools.build:gradle:2.2.3'
         classpath 'io.fabric.tools:gradle:1.+'
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c25cec5..625e6f2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Oct 21 11:34:03 PDT 2015
+#Mon Jan 02 13:25:43 GMT 2017
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip