diff --git a/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/bcftools/BcftoolsCall.scala b/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/bcftools/BcftoolsCall.scala
index 537cd377daa4c3f731541717e5378159a9f4cdc7..8b721d36ae3125e416c1ecc53905d5ec8d70760d 100644
--- a/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/bcftools/BcftoolsCall.scala
+++ b/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/bcftools/BcftoolsCall.scala
@@ -22,28 +22,66 @@ import org.broadinstitute.gatk.utils.commandline.{ Input, Output }
 
 /** This extension is based on bcftools 1.1-134 */
 class BcftoolsCall(val root: Configurable) extends Bcftools {
-  @Input(doc = "Input File")
+  @Input(doc = "Input File", required = false)
   var input: File = _
 
-  @Output(doc = "output File")
+  @Output(doc = "output File", required = false)
   var output: File = _
 
-  var O: String = null
-  var v: Boolean = config("v", default = true)
+  var O: Option[String] = None
+  var v: Boolean = config("v", default = false)
   var c: Boolean = config("c", default = false)
   var m: Boolean = config("m", default = false)
+  var r: Option[String] = config("r")
+  @Input(required = false)
+  var R: Option[String] = config("R")
+  var s: Option[String] = config("s")
+  @Input(required = false)
+  var S: Option[File] = config("S")
+  var t: Option[String] = config("t")
+  @Input(required = false)
+  var T: Option[String] = config("T")
+  var A: Boolean = config("A", default = false)
+  var f: List[String] = config("f", default = Nil)
+  var g: Option[Int] = config("g")
+  var i: Boolean = config("i", default = false)
+  var M: Boolean = config("M", default = false)
+  var V: Option[String] = config("V")
+  var C: Option[String] = config("C")
+  var n: Option[Float] = config("n")
+  var p: Option[Float] = config("p")
+  var P: Option[Float] = config("P")
+  var X: Boolean = config("X", default = false)
+  var Y: Boolean = config("Y", default = false)
 
   override def beforeGraph(): Unit = {
     require(c != m)
   }
 
-  def cmdBase = required(executable) +
+  def cmdLine = required(executable) +
     required("call") +
     optional("-O", O) +
     conditional(v, "-v") +
     conditional(c, "-c") +
-    conditional(m, "-m")
-  def cmdPipeInput = cmdBase + "-"
-  def cmdPipe = cmdBase + input
-  def cmdLine = cmdPipe + " > " + required(output)
+    conditional(m, "-m") +
+    optional("-r", r) +
+    optional("-R", R) +
+    optional("-s", s) +
+    optional("-S", S) +
+    optional("-t", t) +
+    optional("-T", T) +
+    conditional(A, "-A") +
+    repeat("-f", f) +
+    optional("-g", g) +
+    conditional(i, "-i") +
+    conditional(M, "-M") +
+    optional("-V", V) +
+    optional("-C", C) +
+    optional("-n", n) +
+    optional("-p", p) +
+    optional("-P", P) +
+    conditional(X, "-X") +
+    conditional(Y, "-Y") +
+    (if (outputAsStsout) "" else required("-o", output)) +
+    (if (inputAsStdin) "-" else required(input))
 }
diff --git a/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/samtools/SamtoolsMpileup.scala b/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/samtools/SamtoolsMpileup.scala
index 449b49cf0fbc3e1620a804347ce3d61790210183..02ded651d249c432c585349bab230329ccd45dee 100644
--- a/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/samtools/SamtoolsMpileup.scala
+++ b/public/biopet-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/samtools/SamtoolsMpileup.scala
@@ -47,7 +47,7 @@ class SamtoolsMpileup(val root: Configurable) extends Samtools with Reference {
     reference = referenceFasta()
   }
 
-  def cmdBase = required(executable) +
+  def cmdLine = required(executable) +
     required("mpileup") +
     optional("-f", reference) +
     optional("-l", intervalBed) +
@@ -56,12 +56,9 @@ class SamtoolsMpileup(val root: Configurable) extends Samtools with Reference {
     optional("-d", depth) +
     conditional(outputMappingQuality, "-s") +
     conditional(disableBaq, "-B") +
-    conditional(u, "-u")
-  def cmdPipeInput = cmdBase + "-"
-  def cmdPipe = cmdBase + repeat(input)
-
-  /** Returns command to execute */
-  def cmdLine = cmdPipe + " > " + required(output)
+    conditional(u, "-u") +
+    (if (outputAsStsout) "" else required("-o", output)) +
+    (if (inputAsStdin) "-" else repeat(input))
 }
 
 object SamtoolsMpileup {
diff --git a/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MpileupToVcf.scala b/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MpileupToVcf.scala
index 60797ce9ca7f491a9dff0cf3a2379570cc6d91f5..27e7ce903e57fe0fd8c633b722ca560291a853c6 100644
--- a/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MpileupToVcf.scala
+++ b/public/biopet-tools-extensions/src/main/scala/nl/lumc/sasc/biopet/extensions/tools/MpileupToVcf.scala
@@ -47,12 +47,9 @@ class MpileupToVcf(val root: Configurable) extends ToolCommandFuntion with Refer
 
   override def defaultCoreMemory = 3.0
 
-  override def defaults = ConfigUtils.mergeMaps(Map("samtoolsmpileup" -> Map("disable_baq" -> true, "min_map_quality" -> 1)),
-    super.defaults)
-
   override def beforeGraph() {
     super.beforeGraph()
-    reference = referenceFasta().getAbsolutePath
+    if (reference == null) reference = referenceFasta().getAbsolutePath
     val samtoolsMpileup = new SamtoolsMpileup(this)
   }
 
@@ -66,20 +63,12 @@ class MpileupToVcf(val root: Configurable) extends ToolCommandFuntion with Refer
     }
   }
 
-  override def cmdLine = {
-    (if (inputMpileup == null) {
-      val samtoolsMpileup = new SamtoolsMpileup(this)
-      samtoolsMpileup.reference = referenceFasta()
-      samtoolsMpileup.input = List(inputBam)
-      samtoolsMpileup.cmdPipe + " | "
-    } else "") +
-      super.cmdLine +
-      required("-o", output) +
-      optional("--minDP", minDP) +
-      optional("--minAP", minAP) +
-      optional("--homoFraction", homoFraction) +
-      optional("--ploidy", ploidy) +
-      required("--sample", sample) +
-      (if (inputBam == null) required("-I", inputMpileup) else "")
-  }
+  override def cmdLine = super.cmdLine +
+    required("-o", output) +
+    optional("--minDP", minDP) +
+    optional("--minAP", minAP) +
+    optional("--homoFraction", homoFraction) +
+    optional("--ploidy", ploidy) +
+    required("--sample", sample) +
+    (if (inputAsStdin) "" else required("-I", inputMpileup))
 }
diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/extensions/CustomVarScan.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/extensions/CustomVarScan.scala
index 8871f481f3075d7eef52784583ccb5aadaa5b715..f2f11a03e775ebe5a7fa4161813a0157c8f7976a 100644
--- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/extensions/CustomVarScan.scala
+++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/extensions/CustomVarScan.scala
@@ -48,6 +48,7 @@ class CustomVarScan(val root: Configurable) extends BiopetCommandLineFunction wi
     disableBaq = true
     depth = Option(1000000)
     outputMappingQuality = true
+
   }
 
   private def fixMpileup = new PythonCommandLineFunction {
@@ -96,7 +97,6 @@ class CustomVarScan(val root: Configurable) extends BiopetCommandLineFunction wi
   def cmdLine: String = {
     // FIXME: manual trigger of commandLine for version retrieval
     mpileup.commandLine
-    mpileup.cmdPipe + " | " + fixMpileup.commandLine + " | " + removeEmptyPile().commandLine + " | " +
-      varscan.commandLine + " && " + compress.commandLine + " && " + index.commandLine
+    (mpileup | fixMpileup | removeEmptyPile() | varscan).commandLine + " && " + compress.commandLine + " && " + index.commandLine
   }
 }
diff --git a/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaVariantcallingTrait.scala b/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaVariantcallingTrait.scala
index cdf358e9734f2268f29ada961c191d487ba790ea..985d758791df536d10781f5b39c7ffe208f29bee 100644
--- a/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaVariantcallingTrait.scala
+++ b/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaVariantcallingTrait.scala
@@ -48,6 +48,8 @@ trait ShivaVariantcallingTrait extends SummaryQScript with SampleLibraryTag with
     }
   }
 
+  override def defaults = Map("bcftoolscall" -> Map("f" -> List("GQ")))
+
   /** Executed before script */
   def init(): Unit = {
   }
@@ -165,20 +167,11 @@ trait ShivaVariantcallingTrait extends SummaryQScript with SampleLibraryTag with
       mp.reference = referenceFasta()
 
       val bt = new BcftoolsCall(qscript)
-      bt.O = "z"
+      bt.O = Some("z")
       bt.v = true
       bt.c = true
 
-      //TODO: add proper class with piping support, see also issue #114
-      add(new CommandLineFunction {
-        @Input
-        var input = inputBams
-
-        @Output
-        var output = outputFile
-
-        def commandLine: String = mp.cmdPipe + " | " + bt.cmdPipeInput + " > " + outputFile + " && tabix -p vcf " + outputFile
-      })
+      add(mp | bt > outputFile)
     }
   }
 
@@ -195,27 +188,16 @@ trait ShivaVariantcallingTrait extends SummaryQScript with SampleLibraryTag with
         val mp = new SamtoolsMpileup(qscript)
         mp.input :+= inputBam
         mp.u = true
-        //TODO: proper piping should be implemented
         mp.reference = referenceFasta()
 
         val bt = new BcftoolsCall(qscript)
-        bt.O = "z"
+        bt.O = Some("z")
         bt.v = true
         bt.c = true
+        bt.output = new File(outputDir, inputBam.getName + ".vcf.gz")
 
-        val sampleVcf = new File(outputDir, inputBam.getName + ".vcf.gz")
-
-        //TODO: add proper class with piping support, see also issue #114
-        add(new CommandLineFunction {
-          @Input
-          var input = inputBam
-
-          @Output
-          var output = sampleVcf
-
-          def commandLine: String = mp.cmdPipe + " | " + bt.cmdPipeInput + " > " + output + " && tabix -p vcf " + output
-        })
-        sampleVcf
+        add(mp | bt)
+        bt.output
       }
 
       val cv = new CombineVariants(qscript)
@@ -238,10 +220,16 @@ trait ShivaVariantcallingTrait extends SummaryQScript with SampleLibraryTag with
 
     def addJobs() {
       val rawFiles = inputBams.map(bamFile => {
+        val mp = new SamtoolsMpileup(qscript) {
+          override def configName = "samtoolsmpileup"
+          override def defaults = Map("samtoolsmpileup" -> Map("disable_baq" -> true, "min_map_quality" -> 1))
+        }
+        mp.input :+= bamFile
+
         val m2v = new MpileupToVcf(qscript)
         m2v.inputBam = bamFile
         m2v.output = new File(outputDir, bamFile.getName.stripSuffix(".bam") + ".raw.vcf")
-        add(m2v)
+        add(mp | m2v)
 
         val vcfFilter = new VcfFilter(qscript) {
           override def configName = "vcffilter"