diff --git a/src/main/scala/leon/repair/Repairman.scala b/src/main/scala/leon/repair/Repairman.scala
index 221e8ddcec546ab9cf16e2ff93666cb2c4541a35..8cc1220bb2a7fc85abbf01654e34574e3f53bf78 100644
--- a/src/main/scala/leon/repair/Repairman.scala
+++ b/src/main/scala/leon/repair/Repairman.scala
@@ -35,7 +35,7 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
   private object VRes {
     trait VerificationResult
     case object Valid extends VerificationResult
-    case class NotValid(passing : List[Example], failing : List[Example]) extends VerificationResult
+    case class NotValid(passing : Seq[Example], failing : Seq[Example]) extends VerificationResult
   }
 
   def programSize(pgm: Program): Int = {
@@ -372,25 +372,26 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
     val timeoutMs = verifTimeoutMs.getOrElse(3000L)
     val solver = new TimeoutSolverFactory(SolverFactory.getFromSettings(ctx, prog), timeoutMs)
     val vctx = VerificationContext(ctx, prog, solver, reporter)
-    val vcs = AnalysisPhase.generateVerificationConditions(vctx, Some(List(fd.id.name)))
+    val vcs = AnalysisPhase.generateVCs(vctx, Some(List(fd.id.name)))
 
-    AnalysisPhase.checkVerificationConditions(
+    val report = AnalysisPhase.checkVCs(
       vctx, 
       vcs, 
       checkInParallel = true,
-      stopAfter = _.counterExample.isDefined
+      stopAfter = Some({ (vc, vr) => vr.isInvalid })
     )
 
-    val theVCs = vcs.getOrElse(fd, Nil)
-    
-    if(theVCs.forall{ _.value == Some(true) } ) {
+    val vrs = report.vrs
+
+    if(vrs.forall{ _._2.isValid }) {
       Valid
     } else { 
       NotValid(Nil, 
-        theVCs.flatMap { _.counterExample map { 
-          m => InExample(fd.params.map{vd => m(vd.id)})
+        vrs.collect { 
+          case (_, VCResult(VCStatus.Invalid(ex), _, _)) =>
+            InExample(fd.params.map{vd => ex(vd.id)})
         }
-      })
+      )
     }
   }
   
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
index bea2751115a30daaa040246047aadfb05a4c5084..47cebfd05e98c368be153873f30f9dde818da1e1 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
@@ -33,7 +33,7 @@ trait SMTLIBTarget {
   var out: java.io.FileWriter = _
 
   reporter.ifDebug { debug =>
-    val file = context.files.headOption.map(_.getName).getOrElse("NA")  
+    val file = context.files.headOption.map(_.getName).getOrElse("NA")
     val n    = VCNumbers.getNext(targetName+file)
 
     val dir = new java.io.File("vcs")
@@ -42,7 +42,7 @@ trait SMTLIBTarget {
       dir.mkdir
     }
 
-    out = new java.io.FileWriter(s"vcs/$targetName-$file-$n.smt2", true)
+    out = new java.io.FileWriter(s"vcs/$targetName-$file-$n.smt2", false)
   }
 
   def id2sym(id: Identifier): SSymbol = SSymbol(id.name+"!"+id.globalId)
diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala
index f902dbe07663dcb960c52896688e68f69176eaa5..476c7f07ab6907e9636afeeee7d74eb6e7926971 100644
--- a/src/main/scala/leon/synthesis/Synthesizer.scala
+++ b/src/main/scala/leon/synthesis/Synthesizer.scala
@@ -77,8 +77,8 @@ class Synthesizer(val context : LeonContext,
     val solverf = SolverFactory(() => (new FairZ3Solver(context, npr) with TimeoutSolver).setTimeout(timeoutMs))
 
     val vctx = VerificationContext(context, npr, solverf, context.reporter)
-    val vcs = generateVerificationConditions(vctx, Some(fds.map(_.id.name).toSeq))
-    val vcreport = checkVerificationConditions(vctx, vcs)
+    val vcs = generateVCs(vctx, Some(fds.map(_.id.name).toSeq))
+    val vcreport = checkVCs(vctx, vcs)
 
     if (vcreport.totalValid == vcreport.totalConditions) {
       (sol, true)
diff --git a/src/main/scala/leon/verification/AnalysisPhase.scala b/src/main/scala/leon/verification/AnalysisPhase.scala
index 056858e0da7e002bb0836eaad8df445f09662c51..8fe7ef69e5661c9f2b87c88f12865433c913a01b 100644
--- a/src/main/scala/leon/verification/AnalysisPhase.scala
+++ b/src/main/scala/leon/verification/AnalysisPhase.scala
@@ -21,16 +21,52 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
     LeonValueOptionDef("timeout",   "--timeout=T",       "Timeout after T seconds when trying to prove a verification condition.")
   )
 
-  def generateVerificationConditions(vctx: VerificationContext, filterFuns: Option[Seq[String]]): Map[FunDef, List[VerificationCondition]] = {
+  def run(ctx: LeonContext)(program: Program): VerificationReport = {
+    var filterFuns: Option[Seq[String]] = None
+    var timeout: Option[Int]             = None
+
+    val reporter = ctx.reporter
+
+    for(opt <- ctx.options) opt match {
+      case LeonValueOption("functions", ListValue(fs)) =>
+        filterFuns = Some(fs)
+
+
+      case v @ LeonValueOption("timeout", _) =>
+        timeout = v.asInt(ctx)
+
+      case _ =>
+    }
+
+    // Solvers selection and validation
+    val entrySolverFactory = SolverFactory.getFromSettings(ctx, program)
+
+    val mainSolverFactory = timeout match {
+      case Some(sec) =>
+        new TimeoutSolverFactory(entrySolverFactory, sec*1000L)
+      case None =>
+        entrySolverFactory
+    }
+
+    val vctx = VerificationContext(ctx, program, mainSolverFactory, reporter)
+
+    reporter.debug("Generating Verification Conditions...")
+
+    val vcs = generateVCs(vctx, filterFuns)
+
+    reporter.debug("Checking Verification Conditions...")
+
+    checkVCs(vctx, vcs)
+  }
+
+  def generateVCs(vctx: VerificationContext, filterFuns: Option[Seq[String]]): Seq[VC] = {
 
     import vctx.reporter
     import vctx.program
 
-    val defaultTactic = new DefaultTactic(vctx)
+    val defaultTactic   = new DefaultTactic(vctx)
     val inductionTactic = new InductionTactic(vctx)
 
-    var allVCs = Map[FunDef, List[VerificationCondition]]()
-
     def excludeByDefault(fd: FunDef): Boolean = {
       (fd.annotations contains "verified") || (fd.annotations contains "library")
     }
@@ -43,7 +79,7 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
 
     val toVerify = program.definedFunctions.filter(fdFilter).sortWith((fd1, fd2) => fd1.getPos < fd2.getPos)
 
-    for(funDef <- toVerify) {
+    val vcs = for(funDef <- toVerify) yield {
       if (excludeByDefault(funDef)) {
         reporter.warning("Forcing verification of "+funDef.id.name+" which was assumed verified")
       }
@@ -56,148 +92,93 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
         }
 
       if(funDef.body.isDefined) {
-        val funVCs = tactic.generateVCs(funDef)
-
-        allVCs += funDef -> funVCs.toList
+        tactic.generateVCs(funDef)
+      } else {
+        Nil
       }
     }
 
-    allVCs
+    vcs.flatten
   }
 
-  def checkVerificationConditions(
-      vctx: VerificationContext, 
-      vcs: Map[FunDef, List[VerificationCondition]], 
+  def checkVCs(
+      vctx: VerificationContext,
+      vcs: Seq[VC],
       checkInParallel: Boolean = false,
-      stopAfter : VerificationCondition => Boolean = { _ => false }
-  ) : VerificationReport = {
-    import vctx.reporter
-    import vctx.solverFactory
-    
+      stopAfter: Option[(VC, VCResult) => Boolean] = None
+  ): VerificationReport = {
     val interruptManager = vctx.context.interruptManager
 
-    def checkVC(vcInfo : VerificationCondition) = {
-      val funDef = vcInfo.funDef
-      val vc = vcInfo.condition
-
-      // Check if vc targets abstract methods
-      val targets = functionCallsOf(vc).map(_.tfd.fd)
-
-      val s = solverFactory.getNewSolver
-      try {
-        
-        reporter.synchronized {
-          reporter.info(s" - Now considering '${vcInfo.kind}' VC for ${funDef.id} @${vcInfo.getPos}...")
-          reporter.debug("Verification condition (" + vcInfo.kind + ") for ==== " + funDef.id + " ====")
-          reporter.debug(simplifyLets(vc).asString(vctx.context))
-          reporter.debug("Solving with: " + s.name)
-        }
-        
-        val t1 = System.nanoTime
-        s.assertCnstr(Not(vc))
-
-        val satResult = s.check
-        val counterexample: Map[Identifier, Expr] = if (satResult == Some(true)) s.getModel else Map()
-        val solverResult = satResult.map(!_)
-
-        val t2 = System.nanoTime
-        val dt = ((t2 - t1) / 1000000) / 1000.0
-        
-        reporter.synchronized {
-          def title(s : String) = s"   => $s"
-          solverResult match {
-            case _ if interruptManager.isInterrupted =>
-              reporter.warning(title("CANCELLED"))
-              vcInfo.time = Some(dt)
-              false
-  
-            case None =>
-              vcInfo.hasValue = true
-              reporter.warning(title("UNKNOWN"))
-              vcInfo.time = Some(dt)
-              false
-  
-            case Some(true) =>
-              reporter.info(title("VALID"))
-  
-              vcInfo.hasValue = true
-              vcInfo.value = Some(true)
-              vcInfo.solvedWith = Some(s)
-              vcInfo.time = Some(dt)
-              true
-  
-            case Some(false) =>
-              reporter.error(title("INVALID"))
-              reporter.error("Found counter-example : ")
-              reporter.error(counterexample.toSeq.sortBy(_._1.name).map(p => p._1 + " -> " + p._2).mkString("\n"))
-              vcInfo.hasValue = true
-              vcInfo.value = Some(false)
-              vcInfo.solvedWith = Some(s)
-              vcInfo.counterExample = Some(counterexample)
-              vcInfo.time = Some(dt)
-              true
-          }
-        }
-      } finally {
-        s.free()
-      }
-    }
-    
     var stop = false
-    
-    if (checkInParallel) {
-      val allVCsPar = (for {(_, vcs) <- vcs.toSeq; vcInfo <- vcs} yield vcInfo).par
-      for (vc <- allVCsPar if !stop) {
-        checkVC(vc)
+
+    val initMap: Map[VC, Option[VCResult]] = vcs.map(v => v -> None).toMap
+
+    val results = if (checkInParallel) {
+      for (vc <- vcs.par if !stop) yield {
+        val r = checkVC(vctx, vc)
         if (interruptManager.isInterrupted) interruptManager.recoverInterrupt()
-        stop = stopAfter(vc)
+        stop = stopAfter.map(f => f(vc, r)).getOrElse(false)
+        vc -> Some(r)
       }
     } else {
-      for {
-        (funDef, vcs) <- vcs.toSeq.sortWith((a,b) => a._1.getPos < b._1.getPos)
-        vc <- vcs if !interruptManager.isInterrupted && !stop
-      } {
-        checkVC(vc)
+      for (vc <- vcs.toSeq.sortWith((a,b) => a.fd.getPos < b.fd.getPos) if !interruptManager.isInterrupted && !stop) yield {
+        val r = checkVC(vctx, vc)
         if (interruptManager.isInterrupted) interruptManager.recoverInterrupt()
-        stop = stopAfter(vc)
+        stop = stopAfter.map(f => f(vc, r)).getOrElse(false)
+        vc -> Some(r)
       }
     }
-    
-    val report = new VerificationReport(vcs)
-    report
+
+    VerificationReport(initMap ++ results)
   }
 
-  def run(ctx: LeonContext)(program: Program) : VerificationReport = {
-    var filterFuns: Option[Seq[String]] = None
-    var timeout: Option[Int]             = None
+  def checkVC(vctx: VerificationContext, vc: VC): VCResult = {
+    import vctx.reporter
+    import vctx.solverFactory
 
-    val reporter = ctx.reporter
+    val interruptManager = vctx.context.interruptManager
 
-    for(opt <- ctx.options) opt match {
-      case LeonValueOption("functions", ListValue(fs)) =>
-        filterFuns = Some(fs)
+    val vcCond = vc.condition
 
+    val s = solverFactory.getNewSolver
 
-      case v @ LeonValueOption("timeout", _) =>
-        timeout = v.asInt(ctx)
+    try {
+      reporter.synchronized {
+        reporter.info(s" - Now considering '${vc.kind}' VC for ${vc.fd.id} @${vc.getPos}...")
+        reporter.debug(simplifyLets(vcCond).asString(vctx.context))
+        reporter.debug("Solving with: " + s.name)
+      }
 
-      case _ =>
-    }
+      val tStart = System.currentTimeMillis
 
-    // Solvers selection and validation
-    val entrySolverFactory = SolverFactory.getFromSettings(ctx, program)
+      s.assertCnstr(Not(vcCond))
 
-    val mainSolverFactory = timeout match {
-      case Some(sec) =>
-        new TimeoutSolverFactory(entrySolverFactory, sec*1000L)
-      case None =>
-        entrySolverFactory
-    }
+      val satResult = s.check
 
-    val vctx = VerificationContext(ctx, program, mainSolverFactory, reporter)
+      val dt = System.currentTimeMillis - tStart
 
-    reporter.debug("Running verification condition generation...")
-    val vcs = generateVerificationConditions(vctx, filterFuns)
-    checkVerificationConditions(vctx, vcs)
+      val res = satResult match {
+        case _ if interruptManager.isInterrupted =>
+          VCResult(VCStatus.Cancelled, Some(s), Some(dt))
+
+        case None =>
+          VCResult(VCStatus.Unknown, Some(s), Some(dt))
+
+        case Some(false) =>
+          VCResult(VCStatus.Valid, Some(s), Some(dt))
+
+        case Some(true) =>
+          VCResult(VCStatus.Invalid(s.getModel), Some(s), Some(dt))
+      }
+
+      reporter.synchronized {
+        res.report(vctx)
+      }
+
+      res
+
+    } finally {
+      s.free()
+    }
   }
 }
diff --git a/src/main/scala/leon/verification/DefaultTactic.scala b/src/main/scala/leon/verification/DefaultTactic.scala
index 06b35faddb3beb47ca35542a175bb1bfd72a87e1..e58cdc54668f4a367b34895be473f6155d55423c 100644
--- a/src/main/scala/leon/verification/DefaultTactic.scala
+++ b/src/main/scala/leon/verification/DefaultTactic.scala
@@ -10,20 +10,19 @@ import purescala.Constructors._
 
 class DefaultTactic(vctx: VerificationContext) extends Tactic(vctx) {
     val description = "Default verification condition generation approach"
-    override val shortDescription = "default"
 
-    def generatePostconditions(fd: FunDef): Seq[VerificationCondition] = {
+    def generatePostconditions(fd: FunDef): Seq[VC] = {
       (fd.postcondition, fd.body) match {
         case (Some(post), Some(body)) =>
           val vc = implies(precOrTrue(fd), application(post, Seq(body)))
 
-          Seq(new VerificationCondition(vc, fd, VCPostcondition, this).setPos(post))
+          Seq(VC(vc, fd, VCKinds.Postcondition, this).setPos(post))
         case _ =>
           Nil
       }
     }
   
-    def generatePreconditions(fd: FunDef): Seq[VerificationCondition] = {
+    def generatePreconditions(fd: FunDef): Seq[VC] = {
       fd.body match {
         case Some(body) =>
           val calls = collectWithPC {
@@ -35,7 +34,7 @@ class DefaultTactic(vctx: VerificationContext) extends Tactic(vctx) {
               val pre2 = replaceFromIDs((tfd.params.map(_.id) zip args).toMap, pre)
               val vc = implies(and(precOrTrue(fd), path), pre2)
 
-              new VerificationCondition(vc, fd, VCPrecondition, this).setPos(fi)
+              VC(vc, fd, VCKinds.Precondition, this).setPos(fi)
           }
 
         case None =>
@@ -43,36 +42,36 @@ class DefaultTactic(vctx: VerificationContext) extends Tactic(vctx) {
       }
     }
 
-    def generateCorrectnessConditions(fd: FunDef): Seq[VerificationCondition] = {
+    def generateCorrectnessConditions(fd: FunDef): Seq[VC] = {
       fd.body match {
         case Some(body) =>
           val calls = collectWithPC {
             case e @ Error(_, "Match is non-exhaustive") =>
-              (e, VCExhaustiveMatch, BooleanLiteral(false))
+              (e, VCKinds.ExhaustiveMatch, BooleanLiteral(false))
 
             case e @ Error(_, _) =>
-              (e, VCAssert, BooleanLiteral(false))
+              (e, VCKinds.Assert, BooleanLiteral(false))
 
             case a @ Assert(cond, Some(err), _) => 
               val kind = if (err.startsWith("Map ")) {
-                VCMapUsage
+                VCKinds.MapUsage
               } else if (err.startsWith("Array ")) {
-                VCArrayUsage
+                VCKinds.ArrayUsage
               } else {
-                VCAssert
+                VCKinds.Assert
               }
 
               (a, kind, cond)
-            case a @ Assert(cond, None, _) => (a, VCAssert, cond)
+            case a @ Assert(cond, None, _) => (a, VCKinds.Assert, cond)
             // Only triggered for inner ensurings, general postconditions are handled by generatePostconditions
-            case a @ Ensuring(body, post) => (a, VCAssert, application(post, Seq(body)))
+            case a @ Ensuring(body, post) => (a, VCKinds.Assert, application(post, Seq(body)))
           }(body)
 
           calls.map {
             case ((e, kind, errorCond), path) =>
               val vc = implies(and(precOrTrue(fd), path), errorCond)
 
-              new VerificationCondition(vc, fd, kind, this).setPos(e)
+              VC(vc, fd, kind, this).setPos(e)
           }
 
         case None =>
diff --git a/src/main/scala/leon/verification/InductionTactic.scala b/src/main/scala/leon/verification/InductionTactic.scala
index 4420428a78c00893ba33881ff8f4783bd66e208b..21efc5453e12d4f25465ae2fa1273357321e83d0 100644
--- a/src/main/scala/leon/verification/InductionTactic.scala
+++ b/src/main/scala/leon/verification/InductionTactic.scala
@@ -11,7 +11,6 @@ import purescala.Constructors._
 
 class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) {
   override val description = "Induction tactic for suitable functions"
-  override val shortDescription = "induction"
 
   val reporter = vctx.reporter
 
@@ -28,7 +27,7 @@ class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) {
     }
   }
 
-  override def generatePostconditions(fd: FunDef): Seq[VerificationCondition] = {
+  override def generatePostconditions(fd: FunDef): Seq[VC] = {
     (fd.body, firstAbsClassDef(fd.params), fd.postcondition) match {
       case (Some(body), Some((parentType, arg)), Some(post)) =>
         for (cct <- parentType.knownCCDescendents) yield {
@@ -45,7 +44,7 @@ class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) {
             implies(andJoin(subCases), application(post, Seq(body)))
           )
 
-          new VerificationCondition(vc, fd, VCPostcondition, this).setPos(fd)
+          VC(vc, fd, VCKinds.Info(VCKinds.Postcondition, s"ind. on ${arg.id} / ${cct.classDef.id}"), this).setPos(fd)
         }
 
       case (body, _, post) =>
@@ -56,7 +55,7 @@ class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) {
     }
   }
 
-  override def generatePreconditions(fd: FunDef): Seq[VerificationCondition] = {
+  override def generatePreconditions(fd: FunDef): Seq[VC] = {
     (fd.body, firstAbsClassDef(fd.params)) match {
       case (Some(b), Some((parentType, arg))) =>
         val body = b
@@ -78,7 +77,7 @@ class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) {
 
               val vc = implies(and(CaseClassInstanceOf(cct, arg.toVariable), precOrTrue(fd), path), implies(andJoin(subCases), replace((tfd.params.map(_.toVariable) zip args).toMap, pre)))
 
-              new VerificationCondition(vc, fd, VCPrecondition, this).setPos(fi)
+              VC(vc, fd, VCKinds.Info(VCKinds.Precondition, "ind. on $arg / ${cct.classDef.id}"), this).setPos(fi)
             }
         }
 
diff --git a/src/main/scala/leon/verification/Tactic.scala b/src/main/scala/leon/verification/Tactic.scala
index 92bf550b4397d08338c1701e50531240e759230e..d6f955257530fd153649ba96862a48553748b186 100644
--- a/src/main/scala/leon/verification/Tactic.scala
+++ b/src/main/scala/leon/verification/Tactic.scala
@@ -9,9 +9,8 @@ import purescala.ExprOps._
 
 abstract class Tactic(vctx: VerificationContext) {
   val description : String
-  val shortDescription : String
 
-  def generateVCs(fdUnsafe: FunDef): Seq[VerificationCondition] = {
+  def generateVCs(fdUnsafe: FunDef): Seq[VC] = {
     val fd = fdUnsafe.duplicate
     fd.fullBody = matchToIfThenElse(fd.fullBody)
     generatePostconditions(fd) ++
@@ -19,10 +18,9 @@ abstract class Tactic(vctx: VerificationContext) {
     generateCorrectnessConditions(fd)
   }
 
-  def generatePostconditions(function: FunDef): Seq[VerificationCondition]
-  def generatePreconditions(function: FunDef): Seq[VerificationCondition]
-  def generateCorrectnessConditions(function: FunDef): Seq[VerificationCondition]
-
+  def generatePostconditions(function: FunDef): Seq[VC]
+  def generatePreconditions(function: FunDef): Seq[VC]
+  def generateCorrectnessConditions(function: FunDef): Seq[VC]
 
   // Helper functions
   protected def precOrTrue(fd: FunDef): Expr = fd.precondition match {
diff --git a/src/main/scala/leon/verification/VerificationCondition.scala b/src/main/scala/leon/verification/VerificationCondition.scala
index e174830946f07b16113f62bb37ac6a6a2872f275..75618fbbaca4ea436d922a966465e243d1f39883 100644
--- a/src/main/scala/leon/verification/VerificationCondition.scala
+++ b/src/main/scala/leon/verification/VerificationCondition.scala
@@ -10,45 +10,75 @@ import leon.utils.Positioned
 import leon.solvers._
 
 /** This is just to hold some history information. */
-class VerificationCondition(val condition: Expr, val funDef: FunDef, val kind: VCKind, val tactic: Tactic, val info: String = "") extends Positioned {
-  // None = still unknown
-  // Some(true) = valid
-  // Some(false) = invalid
-  var hasValue = false
-  var value : Option[Boolean] = None
-  var solvedWith : Option[Solver] = None
-  var time : Option[Double] = None
-  var counterExample : Option[Map[Identifier, Expr]] = None
-
-  def status : String = value match {
-    case None => "unknown"
-    case Some(true) => "valid"
-    case Some(false) => "invalid"
+case class VC(condition: Expr, fd: FunDef, kind: VCKind, tactic: Tactic) extends Positioned {
+  override def toString = {
+    fd.id.name +" - " +kind.toString
   }
+}
 
-  def tacticStr = tactic.shortDescription match {
-    case "default" => ""
-    case s => s
-  }
+abstract class VCKind(val name: String, val abbrv: String) {
+  override def toString = name
 
-  def solverStr = solvedWith match {
-    case Some(s) => s.name
-    case None => ""
-  }
+  def underlying = this
+}
 
-  override def toString = {
-    kind.toString + " in function " + funDef.id.name + "\n" +
-    condition.toString
+object VCKinds {
+  case class Info(k: VCKind, info: String) extends VCKind(k.abbrv+" ("+info+")", k.abbrv) {
+    override def underlying = k
   }
 
+  case object Precondition    extends VCKind("precondition", "precond.")
+  case object Postcondition   extends VCKind("postcondition", "postcond.")
+  case object Assert          extends VCKind("body assertion", "assert.")
+  case object ExhaustiveMatch extends VCKind("match exhaustiveness", "match.")
+  case object MapUsage        extends VCKind("map usage", "map use")
+  case object ArrayUsage      extends VCKind("array usage", "arr. use")
 }
 
-abstract class VCKind(val name: String, val abbrv: String) {
+case class VCResult(status: VCStatus, solvedWith: Option[Solver], timeMs: Option[Long]) {
+  def isValid   = status == VCStatus.Valid
+  def isInvalid = status.isInstanceOf[VCStatus.Invalid]
+  def isInconclusive = !isValid && !isInvalid
+
+  def report(vctx: VerificationContext) {
+    import vctx.reporter
+    import vctx.context
+
+    status match {
+      case VCStatus.Valid =>
+        reporter.info(" => VALID")
+
+      case VCStatus.Invalid(cex) =>
+        reporter.error(" => INVALID")
+        reporter.error("Found counter-example:")
+
+        val strings = cex.toSeq.sortBy(_._1.name).map {
+          case (id, v) => (id.asString(context), v.asString(context))
+        }
+
+        if (strings.nonEmpty) {
+          val max = strings.map(_._1.size).max
+
+          for ((id, v) <- strings) {
+            reporter.error(("  %-"+max+"s -> %s").format(id, v))
+          }
+        } else {
+          reporter.error(f"  (Empty counter-example)")
+        }
+      case _ =>
+        reporter.warning(" => "+status.name.toUpperCase)
+    }
+  }
+}
+
+sealed abstract class VCStatus(val name: String) {
   override def toString = name
 }
-case object VCPrecondition    extends VCKind("precondition", "precond.")
-case object VCPostcondition   extends VCKind("postcondition", "postcond.")
-case object VCAssert          extends VCKind("body assertion", "assert.")
-case object VCExhaustiveMatch extends VCKind("match exhaustiveness", "match.")
-case object VCMapUsage        extends VCKind("map usage", "map use")
-case object VCArrayUsage      extends VCKind("array usage", "arr. use")
+
+object VCStatus {
+  case class  Invalid(cex: Map[Identifier, Expr]) extends VCStatus("invalid")
+  case object Valid extends VCStatus("valid")
+  case object Unknown extends VCStatus("unknown")
+  case object Timeout extends VCStatus("timeout")
+  case object Cancelled extends VCStatus("cancelled")
+}
diff --git a/src/main/scala/leon/verification/VerificationReport.scala b/src/main/scala/leon/verification/VerificationReport.scala
index 2683ff2509cd401f3803b12bf628e27f03d3df2e..8db22ff699d58b79fda144303f28761eeda07acb 100644
--- a/src/main/scala/leon/verification/VerificationReport.scala
+++ b/src/main/scala/leon/verification/VerificationReport.scala
@@ -3,36 +3,39 @@
 package leon
 package verification
 
+import VCKinds._
+import VCStatus._
+
 import purescala.Definitions.FunDef
 
-class VerificationReport(val fvcs: Map[FunDef, List[VerificationCondition]]) {
+case class VerificationReport(val results: Map[VC, Option[VCResult]]) {
   import scala.math.Ordering.Implicits._
-  val conditions : Seq[VerificationCondition] = fvcs.flatMap(_._2).toSeq.sortBy(vc => (vc.funDef.id.name, vc.kind.toString))
-
-  lazy val totalConditions : Int = conditions.size
 
-  lazy val totalTime : Double = conditions.foldLeft(0.0d)((t,c) => t + c.time.getOrElse(0.0d))
+  val vrs: Seq[(VC, VCResult)] = results.toSeq.sortBy { case (vc, _) => (vc.fd.id.name, vc.kind.toString) }.map {
+    case (vc, or) => (vc, or.getOrElse(VCResult(Unknown, None, None)))
+  }
 
-  lazy val totalValid : Int = conditions.count(_.value == Some(true))
+  lazy val totalConditions : Int = vrs.size
 
-  lazy val totalInvalid : Int = conditions.count(_.value == Some(false))
+  lazy val totalTime: Long = vrs.map(_._2.timeMs.getOrElse(0l)).sum
 
-  lazy val totalUnknown : Int = conditions.count(_.value == None)
+  lazy val totalValid: Int   = vrs.count(_._2.isValid)
+  lazy val totalInvalid: Int = vrs.count(_._2.isInvalid)
+  lazy val totalUnknown: Int = vrs.count(_._2.isInconclusive)
 
   def summaryString : String = if(totalConditions >= 0) {
     import utils.ASCIIHelpers._
 
     var t = Table("Verification Summary")
 
-    t ++= conditions.map { vc =>
-      val timeStr = vc.time.map(t => f"$t%-3.3f").getOrElse("")
+    t ++= vrs.map { case (vc, vr) =>
+      val timeStr = vr.timeMs.map(t => f"${t/1000d}%-3.3f").getOrElse("")
       Row(Seq(
-        Cell(vc.funDef.id.toString),
+        Cell(vc.fd.id.toString),
         Cell(vc.kind.name),
         Cell(vc.getPos),
-        Cell(vc.status),
-        Cell(vc.tacticStr),
-        Cell(vc.solverStr),
+        Cell(vr.status),
+        Cell(vr.solvedWith.map(_.name).getOrElse("")),
         Cell(timeStr, align = Right)
       ))
     }
@@ -40,8 +43,8 @@ class VerificationReport(val fvcs: Map[FunDef, List[VerificationCondition]]) {
     t += Separator
 
     t += Row(Seq(
-      Cell(f"total: $totalConditions%-4d   valid: $totalValid%-4d   invalid: $totalInvalid%-4d   unknown $totalUnknown%-4d", 6),
-      Cell(f"$totalTime%7.3f", align = Right)
+      Cell(f"total: $totalConditions%-4d   valid: $totalValid%-4d   invalid: $totalInvalid%-4d   unknown $totalUnknown%-4d", 5),
+      Cell(f"${totalTime/1000d}%7.3f", align = Right)
     ))
 
     t.render
diff --git a/src/main/scala/leon/xlang/XLangAnalysisPhase.scala b/src/main/scala/leon/xlang/XLangAnalysisPhase.scala
index 2198605ee66d800f2b09a3ed5c6acb6992fa5a21..75b16415530a8686c582fa9b08d1ba9b4553a9ad 100644
--- a/src/main/scala/leon/xlang/XLangAnalysisPhase.scala
+++ b/src/main/scala/leon/xlang/XLangAnalysisPhase.scala
@@ -11,8 +11,10 @@ object XLangAnalysisPhase extends LeonPhase[Program, VerificationReport] {
   val name = "xlang analysis"
   val description = "apply analysis on xlang"
 
-  case object VCInvariantPost extends VCKind("invariant postcondition", "inv. post.")
-  case object VCInvariantInd  extends VCKind("invariant inductive",     "inv. ind.")
+  object VCXLangKinds {
+    case object InvariantPost extends VCKind("invariant postcondition", "inv. post.")
+    case object InvariantInd  extends VCKind("invariant inductive",     "inv. ind.")
+  }
 
   def run(ctx: LeonContext)(pgm: Program): VerificationReport = {
 
@@ -59,34 +61,34 @@ object XLangAnalysisPhase extends LeonPhase[Program, VerificationReport] {
   }
 
   def completeVerificationReport(vr: VerificationReport, functionWasLoop: FunDef => Boolean): VerificationReport = {
-    val vcs = vr.conditions
 
     //this is enough to convert invariant postcondition and inductive conditions. However the initial validity
     //of the invariant (before entering the loop) will still appear as a regular function precondition
     //To fix this, we need some information in the VCs about which function the precondtion refers to
     //although we could arguably say that the term precondition is general enough to refer both to a loop invariant
     //precondition and a function invocation precondition
-    var freshFtoVcs = Map[FunDef, List[VerificationCondition]]()
-
-    for (vc <- vcs) {
-      val funDef = vc.funDef
-      if(functionWasLoop(funDef)) {
-        val freshVc = new VerificationCondition(
-          vc.condition, 
-          funDef.owner match { case Some(fd : FunDef) => fd; case _ => funDef }, 
-          if(vc.kind == VCPostcondition) VCInvariantPost else if(vc.kind == VCPrecondition) VCInvariantInd else vc.kind,
-          vc.tactic,
-          vc.info).setPos(funDef)
-        freshVc.value = vc.value
-        freshVc.solvedWith = vc.solvedWith
-        freshVc.time = vc.time
-        freshFtoVcs += freshVc.funDef -> (freshVc :: freshFtoVcs.getOrElse(freshVc.funDef, List()))
+
+    val newResults = for ((vc, ovr) <- vr.results) yield {
+      if(functionWasLoop(vc.fd)) {
+        val nvc = VC(vc.condition, 
+                     vc.fd.owner match {
+                       case Some(fd: FunDef) => fd
+                       case _ => vc.fd
+                     },
+                     vc.kind.underlying match {
+                       case VCKinds.Postcondition => VCXLangKinds.InvariantPost
+                       case VCKinds.Precondition => VCXLangKinds.InvariantInd
+                       case _ => vc.kind
+                     },
+                     vc.tactic)
+
+        nvc -> ovr
       } else {
-        freshFtoVcs += vc.funDef -> (vc :: freshFtoVcs.getOrElse(vc.funDef, List()))
+        vc -> ovr
       }
     }
 
-    new VerificationReport(freshFtoVcs)
+    VerificationReport(newResults)
   }
 
 }
diff --git a/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala b/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
index 55902fa9e6e0a863c6fa6ef49443e2b56cd14d84..bc1f0257739b9550dfc50a5eddcb199299bc9f71 100644
--- a/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
+++ b/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
@@ -45,8 +45,8 @@ class PureScalaVerificationRegression extends VerificationRegression {
   
   forEachFileIn("valid") { output =>
     val Output(report, reporter) = output
-    for (vc <- report.conditions) {
-      if (vc.value != Some(true)) {
+    for ((vc, vr) <- report.vrs) {
+      if (!vr.isValid) {
         fail("The following verification condition was invalid: " + vc.toString + " @" + vc.getPos)
       }
     }