diff --git a/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MergeTables.scala b/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MergeTables.scala
index f4e0946588d94fed1b9829ce1f66935a0530c532..fc9d6a053ff1218e147ac7ec5631861d3cf6dfae 100644
--- a/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MergeTables.scala
+++ b/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MergeTables.scala
@@ -77,3 +77,22 @@ class MergeTables(val root: Configurable) extends ToolCommandFunction {
       required("-o", output) +
       required("", repeat(inputTables), escape = false)
 }
+
+object MergeTables {
+  def apply(root: Configurable,
+            tables: List[File],
+            outputFile: File,
+            idCols: List[Int],
+            valCol: Int,
+            numHeaderLines: Int = 0,
+            fallback: String = "-"): MergeTables = {
+        val job = new MergeTables(root)
+        job.inputTables = tables
+        job.output = outputFile
+        job.idColumnIndices = idCols.map(_.toString)
+        job.valueColumnIndex = valCol
+        job.fallbackString = Option(fallback)
+        job.numHeaderLines = Option(numHeaderLines)
+        job
+      }
+}
\ No newline at end of file
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerExon.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerExon.scala
index 43f2a4806ffaac00099674b1f25ddaac4def9f88..d0feb6c8b2b9fc4c440d3ecfae601e5c3d9337a6 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerExon.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerExon.scala
@@ -8,4 +8,6 @@ import org.broadinstitute.gatk.queue.QScript
  */
 class BasesPerExon(val root: Configurable) extends QScript with Measurement {
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1), 2, numHeaderLines = 1, fallback = "0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerGene.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerGene.scala
index 599fb670c5c87914ef9c2210ad0450cd63404d15..d2650362f471088c2e8248974022dcb960a3e895 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerGene.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/BasesPerGene.scala
@@ -9,4 +9,6 @@ import org.broadinstitute.gatk.queue.QScript
 class BasesPerGene(val root: Configurable) extends QScript with Measurement {
   //TODO: splitting on strand if strandspecific
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1), 2, numHeaderLines = 1, fallback = "0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksBlind.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksBlind.scala
index f24e0ed80015150945c7c0b0f90b638734776b5b..705f1fd8c1969ab7342806ce3fae52d37f8e0b0d 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksBlind.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksBlind.scala
@@ -8,4 +8,6 @@ import org.broadinstitute.gatk.queue.QScript
  */
 class CufflinksBlind(val root: Configurable) extends QScript with Measurement {
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1, 7), 10, numHeaderLines = 1, fallback = "0.0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksGuided.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksGuided.scala
index a8b3e845a6a71b6bea18dad8e3cb223a5581ac00..ea17314019375aa166e6b23f275aa020c21a6e3f 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksGuided.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksGuided.scala
@@ -8,4 +8,6 @@ import org.broadinstitute.gatk.queue.QScript
  */
 class CufflinksGuided(val root: Configurable) extends QScript with Measurement {
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1, 7), 10, numHeaderLines = 1, fallback = "0.0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksStrict.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksStrict.scala
index 5fa3ce96f8c6ba8fcd6f0f792380672aa7489b4c..ceae31abe27ee68323c586060c5d330889ec4c51 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksStrict.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/CufflinksStrict.scala
@@ -8,4 +8,6 @@ import org.broadinstitute.gatk.queue.QScript
  */
 class CufflinksStrict(val root: Configurable) extends QScript with Measurement {
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1, 7), 10, numHeaderLines = 1, fallback = "0.0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerExon.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerExon.scala
index 1d1fbb56eee141744752a6528203e57beea32c20..6f1268fcc5b677ad77dff37d76a457097c53669d 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerExon.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerExon.scala
@@ -8,4 +8,6 @@ import org.broadinstitute.gatk.queue.QScript
  */
 class FragmentsPerExon(val root: Configurable) extends QScript with Measurement {
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1), 2, numHeaderLines = 1, fallback = "0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerGene.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerGene.scala
index 904fcde16b6d3b7f183e44d8799c80413b331a5b..26bf4dc1453ab90471b83c427614c0facbb7eb4c 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerGene.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/FragmentsPerGene.scala
@@ -8,4 +8,6 @@ import org.broadinstitute.gatk.queue.QScript
  */
 class FragmentsPerGene(val root: Configurable) extends QScript with Measurement {
   def bamToCountFile(id: String, bamFile: File): (String, File) = ???
+
+  def mergeArgs = MergeArgs(List(1), 2, numHeaderLines = 1, fallback = "0")
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/Measurement.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/Measurement.scala
index 37249c5934054783b6ce39c152e36f53101da262..3519056769ff6b7db1783a078a7c6259536bc510 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/Measurement.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/measures/Measurement.scala
@@ -2,6 +2,7 @@ package nl.lumc.sasc.biopet.pipelines.gentrap.measures
 
 import nl.lumc.sasc.biopet.core.Reference
 import nl.lumc.sasc.biopet.core.summary.SummaryQScript
+import nl.lumc.sasc.biopet.extensions.tools.MergeTables
 import org.broadinstitute.gatk.queue.QScript
 
 /**
@@ -19,6 +20,15 @@ trait Measurement extends SummaryQScript with Reference { qscript: QScript =>
 
   lazy val countFiles: Map[String, File] = bamFiles.map { case (id, bamFile) => bamToCountFile(id, bamFile) }
 
+  def mergedCountFile = new File(outputDir, s"$name.merged.tsv")
+
+  case class MergeArgs(idCols: List[Int],
+                       valCol: Int,
+                       numHeaderLines: Int = 0,
+                       fallback: String = "-")
+
+  def mergeArgs: MergeArgs
+
   /** Init for pipeline */
   def init(): Unit = {
     require(bamFiles.nonEmpty)
@@ -26,7 +36,8 @@ trait Measurement extends SummaryQScript with Reference { qscript: QScript =>
 
   /** Pipeline itself */
   def biopetScript(): Unit = {
-    //TODO: Merging
+    add(MergeTables(this, countFiles.values.toList, mergedCountFile,
+      mergeArgs.idCols, mergeArgs.valCol, mergeArgs.numHeaderLines, mergeArgs.fallback))
 
     //TODO: Heatmap
   }
@@ -40,5 +51,5 @@ trait Measurement extends SummaryQScript with Reference { qscript: QScript =>
   def summaryFiles: Map[String, File] = Map()
 
   /** Name of summary output file */
-  def summaryFile: File = new File(s"$name.summary.json")
+  def summaryFile: File = new File(outputDir, s"$name.summary.json")
 }