diff --git a/src/funcheck/AnalysisComponent.scala b/src/funcheck/AnalysisComponent.scala
index a442828b4925363a2155e5a1acfed524971894a9..8aa227deb89cc8115bfc0a604888b6132b8be94d 100644
--- a/src/funcheck/AnalysisComponent.scala
+++ b/src/funcheck/AnalysisComponent.scala
@@ -6,7 +6,7 @@ import scalacheck._
 
 class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin) extends PluginComponent
   with CodeExtraction
-  with ScalaCheckIntegrator[AnalysisComponent]
+  with ScalaCheckIntegrator
 {
   import global._
 
@@ -47,6 +47,7 @@ class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin)
       val (genDef, arbDef) = createGeneratorDefDefs(unit)
     
       injectGenDefDefs(genDef ::: arbDef, unit)
+      forAllTransform(unit)
 
 //      if(pluginInstance.stopAfterAnalysis) {
 //        println("Analysis complete. Now terminating the compiler process.")
diff --git a/src/funcheck/scalacheck/FilterGeneratorAnnotations.scala b/src/funcheck/scalacheck/FilterGeneratorAnnotations.scala
index 00748c5dc781faea830c3b784c7e1d3f8da9cdf2..65498dee190419c311c05470ba22a074176abab9 100644
--- a/src/funcheck/scalacheck/FilterGeneratorAnnotations.scala
+++ b/src/funcheck/scalacheck/FilterGeneratorAnnotations.scala
@@ -1,6 +1,6 @@
 package funcheck.scalacheck
 
-import scala.tools.nsc.{Global, SubComponent}
+import scala.tools.nsc.Global
 
 /** 
  * A tree traverser which filter the trees elements that contain the 
@@ -20,7 +20,8 @@ import scala.tools.nsc.{Global, SubComponent}
  * 
  * where <code>unit</code> is the current Compilation Unit.
  */
-trait FilterGeneratorAnnotations[T <: SubComponent] { self: T =>
+trait FilterGeneratorAnnotations { 
+  val global: Global
   // [[INFO]] "hasAttribute" is "hasAnnotation" in future compiler release 2.8
   import global._
   
diff --git a/src/funcheck/scalacheck/ScalaCheck.scala b/src/funcheck/scalacheck/ScalaCheck.scala
index bae8bd0ee21f04215ec6048b97f377c0f4dd07f2..b1e57db4779775ed7737e52f0886cd63736dcb7d 100644
--- a/src/funcheck/scalacheck/ScalaCheck.scala
+++ b/src/funcheck/scalacheck/ScalaCheck.scala
@@ -1,12 +1,15 @@
 package funcheck.scalacheck
 
-import scala.tools.nsc.{Global, SubComponent}
+import scala.tools.nsc.Global
+import funcheck.util.FreshNameCreator
 
 /**
  * Utilitarity class that is used as a factory for creating Tree nodes for method 
  * calls of classes and modules in the <code>org.scalacheck</code> package. 
  */
-trait ScalaCheck[T <: SubComponent] {self: T =>
+trait ScalaCheck extends FreshNameCreator {
+  val global: Global
+  
   import global._
   
   
@@ -19,7 +22,7 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
   
   /** Module for creating scalac Tree nodes for calling methods of the 
    * <code>org.scalacheck.Gen</code> class and module.*/
-  trait Gen {
+  object Gen {
   
     /** Symbol for the <code>org.scalacheck.Gen</code> module definition. */
     private lazy val moduleGenSym = definitions.getModule("org.scalacheck.Gen")
@@ -97,35 +100,165 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
     
     
     
+     /** 
+     * Map that stores for each @generator annotated ClassDef or DefDef the automatically  
+     * generated DefDef for creating instances of the <code>org.scalacheck.Gen</code> class.
+     * The <code>Type</code> that is associated to the DefDef is either the type of the 
+     * ClassDef or the returning type of the DefDef.
+     */
+    private val tpe2listGen = scala.collection.mutable.Map.empty[Type, List[DefDef]]
+    private val tpe2listGenSym = scala.collection.mutable.Map.empty[Type, List[Symbol]]
+    
+     /** 
+     * Add the <code>gen</code> generator DefDef declaration to the list of 
+     * generators for <code>tpe</code>.
+     * 
+     * @param tpe The type of elements generated by the <code>gen</code>.
+     * @param gen The DefDef declaration for the generator method.
+     */
+    def +[T](map: collection.mutable.Map[Type, List[T]], key: Type, value: T): Unit = map.get(key) match {
+      case None         => map += key -> List(value)
+      case Some(values) => map += key -> (value :: values)
+    }
    
+    /** List of generator DefDef symbols for a given type <code>tpe</code>*/
+    def genSymbolsForType(tpe: Type): List[Symbol] = tpe2listGenSym.get(tpe) match {
+      case None => Nil
+      case Some(symbols) => symbols
+    } 
+    
+    /** 
+     * Second Pass: Create symbols for the generator DefDef that will be created
+     * durind the Third Pass.
+     */
+    def createGenDefDef(klasses: List[ClassDef], defs: List[DefDef]): List[DefDef] = {
+      val generable: List[(Symbol,Tree)] = createGenDefSyms(klasses, defs)
+      
+      for { (genSym, genTree) <- generable } genTree match {
+        case cd: ClassDef => 
+          val tpe = cd.symbol.tpe
+          Gen + (tpe2listGen, tpe, Gen.createGenDef(cd, genSym))
+        
+        case d: DefDef =>
+          val tpe = d.tpt.symbol.tpe
+          val generated = DefDef(genSym, Modifiers(0), List(), rhsGenDef(Ident(d.name))(d)(genSym))
+          Gen + (tpe2listGen, tpe, generated)
+      }
+      
+      // flatten into single list values of Gen.tpe2listGen
+      (List[DefDef]() /: Gen.tpe2listGen.values) {
+        case (xs, xss) => xs ::: xss
+      }
+    }
+    
+    
+    /** 
+     * Create method symbols for each <code>@generator</code> annotated ClassDef
+     * and DefDef.
+     */
+    private def createGenDefSyms(klasses: List[ClassDef], defs: List[DefDef]): List[(Symbol, Tree)] = {
+    
+      val genKlasses: List[(Symbol, ClassDef)] = for(klass <- klasses) yield {
+        val genName = fresh.newName("gen"+klass.name)
+        val tpe = klass.symbol.tpe
+        val genSym = createGenDefSymbol(klass.symbol.enclClass.owner, genName, tpe)
+        
+        Gen + (tpe2listGenSym, tpe, genSym)
+        
+        (genSym, klass)
+      }
+    
+      val genDefs: List[(Symbol, DefDef)] = for(d <- defs) yield {
+        val genName = fresh.newName("gen"+d.name)
+        val tpe = d.tpt.symbol.tpe
+        val genSym = createGenDefSymbol(d.symbol.owner, genName, tpe)
+        
+        Gen + (tpe2listGenSym, tpe, genSym)
+        
+        (genSym, d)
+      }
+    
+      genKlasses ::: genDefs
+    }
+    
+    
     
-//    def buildGenDefDef(cd: ClassDef, genDefSym: Symbol): DefDef = {
-//      val constructorSym = constructorDecl(cd.symbol.asInstanceOf[ClassSymbol])
-//      val paramss = constructorSym.typeParams
-//       
-//      assert(paramss.size <= 1, "currying is not supported. Change signature of "+constructorSym)
-//      
-//      
-//      if(cd.symbol.hasFlag(scala.tools.nsc.symtab.Flags.ABSTRACT)) {
-//        val generators = constructorSym.children.toList.map(s => genForTpe(s.tpe)).flatMap(v=>v)
-//        DefDef(genDefSym, Modifiers(0), List(), Gen.oneOf(generators))
-//      } 
-//      else {
-//        
-//        val constrObj = resetAttrs(d.tpt.duplicate)
-//        val instance = Select(New(constrObj), nme.CONSTRUCTOR)
-//        
-//        if(paramss.isEmpty) {
-//          DefDef(genDefSym, Modifiers(0), List(), Gen.value(Apply(instance, Nil)))
-//        } 
-//        else {
-//          //should use Tree.duplicate instead!!
-//          val body = rhsGenDef(instance)(d)(genDef)
-//        
-//          DefDef(genDef, Modifiers(0), List(), body)
-//        }
-//      }
-//    }
+    def createGenDef(cd: ClassDef, genDef: Symbol): DefDef = {
+      val d: DefDef = getConstructorOf(cd)
+      val DefDef(_,_,_,vparamss,retTpe,_) = d 
+      assert(vparamss.size <= 1, "currying is not supported. Change signature of "+cd.symbol)
+      
+      
+      if(cd.symbol.hasFlag(scala.tools.nsc.symtab.Flags.ABSTRACT)) {
+        val generators = retTpe.symbol.children.toList.map(s => genSymbolsForType(s.tpe)).flatMap(v=>v)
+        DefDef(genDef, Modifiers(0), List(), Gen.oneOf(generators))
+      } 
+      else {
+        
+        val constrObj = resetAttrs(d.tpt.duplicate)
+        val instance = Select(New(constrObj), nme.CONSTRUCTOR)
+        
+        assert(d.tpt.isInstanceOf[TypeTree])
+        
+        val body = rhsGenDef(instance)(d)(genDef)
+        DefDef(genDef, Modifiers(0), List(), body)
+      }
+    }
+    
+    
+     /** <code>base</code> is either 
+     *       - Select(New(tpe),constructor) [constructor] 
+     *       - Ident(name)   [method call]
+     */
+    private def rhsGenDef(base: Tree)(d: DefDef)(extOwner: Symbol): Tree = {
+      val DefDef(_,name,_,vparamss,retTpe,_) = d
+      assert(vparamss.size <= 1, "currying is not supported. Change signature of "+d.symbol)
+      
+      if(vparamss.head.isEmpty)
+        Gen.value(Apply(base, Nil))
+      
+      else {
+        var owner = extOwner
+      
+        val paramssTpe: List[ValDef] = vparamss.flatMap(v=>v).map(p => 
+          ValDef(Modifiers(0), fresh.newName("v"), resetAttrs(p.tpt.duplicate), EmptyTree))
+      
+      
+        var last = true
+      
+      
+        val z :Tree = Apply(base, paramssTpe.map(p => Ident(p.name)))
+        val body = (paramssTpe :\ z) {
+          case (param,apply) => {
+            val body = Function(List(param), apply)
+            body.symbol.owner = owner
+            owner = body.symbol
+            //XXX: it is not flatMap in general. fix this!!
+            if(last) {
+              last = false
+              Gen.map(Arbitrary.arbitrary(param.tpt.asInstanceOf[TypeTree]), body)
+            } else
+              Gen.flatMap(Arbitrary.arbitrary(param.tpt.asInstanceOf[TypeTree]), body)
+          }
+        }
+      
+        body
+      }
+    }
+   
+    
+    
+    private def getConstructorOf(cd: ClassDef): DefDef = {
+      val Template(parents, self, body) = cd.impl
+      var dd: DefDef  = null
+      for { b <- body } b match {
+        case d @ DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => dd = d
+        case _ => ;
+      }
+      dd
+    } ensuring (res => res != null)
+
+  
     
   }
   
@@ -133,7 +266,7 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
   
   /** Module for creating scalac Tree nodes for calling methods of the 
    * <code>org.scalacheck.Arbitrary</code> class and module.*/
-  trait Arbitrary {
+  object Arbitrary {
    
     /** Symbol for the <code>org.scalacheck.Arbitrary</code> module definition. */
     private val moduleArbitrarySym = definitions.getModule("org.scalacheck.Arbitrary")
@@ -184,16 +317,16 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
     
     
     /** Map that stores <code>org.scalacheck.Arbitrary.arbitrary[Type]</code> calls. */
-    protected val tpe2arbApp    = scala.collection.mutable.Map.empty[Type,Apply]
+    protected val tpe2arbApp    = scala.collection.mutable.Map.empty[Type,Tree]
     
     // initialize map with ScalaCheck built-in types that are part of our PureScala language
-    tpe2arbApp += definitions.IntClass.typeConstructor       -> applyArbitrary(arbInt)
-    tpe2arbApp += definitions.BooleanClass.typeConstructor   -> applyArbitrary(arbBool)
-    tpe2arbApp += definitions.LongClass.typeConstructor      -> applyArbitrary(arbLong)
-    tpe2arbApp += definitions.ThrowableClass.typeConstructor -> applyArbitrary(arbThrowable)
-    tpe2arbApp += definitions.DoubleClass.typeConstructor    -> applyArbitrary(arbDouble)
-    tpe2arbApp += definitions.CharClass.typeConstructor      -> applyArbitrary(arbChar)
-    tpe2arbApp += definitions.StringClass.typeConstructor    -> applyArbitrary(arbString)
+    tpe2arbApp += definitions.IntClass.typeConstructor       -> arbInt
+    tpe2arbApp += definitions.BooleanClass.typeConstructor   -> arbBool
+    tpe2arbApp += definitions.LongClass.typeConstructor      -> arbLong
+    tpe2arbApp += definitions.ThrowableClass.typeConstructor -> arbThrowable
+    tpe2arbApp += definitions.DoubleClass.typeConstructor    -> arbDouble
+    tpe2arbApp += definitions.CharClass.typeConstructor      -> arbChar
+    tpe2arbApp += definitions.StringClass.typeConstructor    -> arbString
     
     /**
      * Apply <code>polyTpe</code> to the polymorphic type <code>org.scalacheck.Arbitrary</code>.
@@ -214,6 +347,8 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
     def apply(generator: Tree): Tree = 
       Apply(Select(Ident(moduleArbitrarySym),symDecl(moduleArbitrarySym, "apply")), List(generator))
     
+    def arbitrary(tpe: Type): Tree = tpe2arbApp.get(tpe).get
+    
     /**
      * 
      */
@@ -221,12 +356,38 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
       val symbol = polyTpe.symbol
       val tpe = symbol.tpe
       tpe2arbApp.get(tpe) match {
-        case Some(appliedArbitrary) => appliedArbitrary
+        case Some(arb) => applyArbitrary(arb)
         case None => arbitrary(symbol)
       }
     }
     
-    protected def arbitrary(tpeSym: Symbol): Apply 
+    /** Map that stores not built-in <code>org.scalacheck.Arbitrary</code> DefDef definitions. */
+    private val tpe2arbDefDef = scala.collection.mutable.Map.empty[Type,DefDef]
+    
+    def getArbitraryDefDefs: List[DefDef] = tpe2arbDefDef.values.toList
+    
+    def arbitrary(tpeSym: Symbol): Apply = {
+      require(tpe2arbApp.get(tpeSym.tpe).isEmpty, "Arbitrary.arbitrary["+tpeSym.tpe+"] is already in the map")
+      
+      val owner = tpeSym.toplevelClass
+      val arbName = fresh.newName("arb"+tpeSym.name)
+      val tpe = tpeSym.tpe
+      
+      val arbDef = createArbitraryDefSymbol(owner, arbName, tpe)
+      
+            
+      val genNames = Gen.genSymbolsForType(tpe)
+      
+      
+      val generated = DefDef(arbDef, Modifiers(0), List(), Arbitrary(Gen.oneOf(genNames)))
+      tpe2arbDefDef += tpe -> generated  
+      
+      val result = applyArbitrary(Ident(arbDef))
+      tpe2arbApp += tpe -> Ident(arbDef)
+        
+      result
+            
+    }
     
                                   
     protected def applyArbitrary(param: Tree): Apply =
@@ -254,4 +415,226 @@ trait ScalaCheck[T <: SubComponent] {self: T =>
       arbDef
     }
   }
+  
+  object Prop {
+    
+    private lazy val modulePropSym: Symbol = definitions.getModule("org.scalacheck.Prop")
+    
+    /** Transform string name in method symbols from the <code>symDecl</code> 
+     * class symbol. 
+     */
+    private def decl(name: String) = modulePropSym.tpe.decl(name)
+    
+    private def moduleApply(method: String, args: List[Tree]): Apply = 
+      Apply(Select(Ident(modulePropSym), decl(method)), args)
+    
+    def forAll(props: List[Tree]): Apply = 
+      moduleApply("forAll", props)
+    
+    def forAll(prop: Tree): Apply = forAll(List(prop))
+    
+    
+    def propBoolean(ident: Tree): Apply = 
+      moduleApply("propBoolean", List(ident))
+  }
+  
+  
+  object Shrink {
+    private def select(instance: Symbol, method: String): Select = 
+      Select(Ident(instance), symDecl(instance,method))
+    
+    /** Symbol for the <code>org.scalacheck.Shrink</code> module definition. */
+    private val moduleShrinkSym = definitions.getModule("org.scalacheck.Shrink")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkInt</code> method definition. */
+    private val shrinkInt          =  select(moduleShrinkSym, "shrinkInt")    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkString</code> method definition. */
+    private val shrinkString       =  select(moduleShrinkSym, "shrinkString")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkOption</code> method definition. */
+    private val shrinkOption       =  select(moduleShrinkSym, "shrinkOption")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkList</code> method definition. */
+    private val shrinkList         =  select(moduleShrinkSym, "shrinkList")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkSet</code> method definition. */
+    private val shrinkSet          =  select(moduleShrinkSym, "shrinkSet")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple2</code> method definition. */
+    private val shrinkTuple2       =  select(moduleShrinkSym, "shrinkTuple2")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple3</code> method definition. */
+    private val shrinkTuple3       =  select(moduleShrinkSym, "shrinkTuple3")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple4</code> method definition. */
+    private val shrinkTuple4       =  select(moduleShrinkSym, "shrinkTuple4")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple5</code> method definition. */
+    private val shrinkTuple5       =  select(moduleShrinkSym, "shrinkTuple5")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple6</code> method definition. */
+    private val shrinkTuple6       =  select(moduleShrinkSym, "shrinkTuple6")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple7</code> method definition. */
+    private val shrinkTuple7       =  select(moduleShrinkSym, "shrinkTuple7")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple8</code> method definition. */
+    private val shrinkTuple8       =  select(moduleShrinkSym, "shrinkTuple8")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkTuple9</code> method definition. */
+    private val shrinkTuple9       =  select(moduleShrinkSym, "shrinkTuple9")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkIntList</code> method definition. */
+    private val shrinkIntList      =  select(moduleShrinkSym, "shrinkIntList")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkBooleanList</code> method definition. */
+    private val shrinkBooleanList  =  select(moduleShrinkSym, "shrinkBooleanList")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkDoubleList</code> method definition. */
+    private val shrinkDoubleList   =  select(moduleShrinkSym, "shrinkDoubleList")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkStringList</code> method definition. */
+    private val shrinkStringList   =  select(moduleShrinkSym, "shrinkStringList")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkIntSet</code> method definition. */
+    private val shrinkIntSet       =  select(moduleShrinkSym, "shrinkIntSet")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkBooleanSet</code> method definition. */
+    private val shrinkBooleanSet   =  select(moduleShrinkSym, "shrinkBooleanSet")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkDoubleSet</code> method definition. */
+    private val shrinkDoubleSet    =  select(moduleShrinkSym, "shrinkDoubleSet")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkStringSet</code> method definition. */
+    private val shrinkStringSet    =  select(moduleShrinkSym, "shrinkStringSet")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkIntOption</code> method definition. */
+    private val shrinkIntOption    =  select(moduleShrinkSym, "shrinkIntOption")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkBooleanOption</code> method definition. */
+    private val shrinkBooleanOption=  select(moduleShrinkSym, "shrinkBooleanOption")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkDoubleOption</code> method definition. */
+    private val shrinkDoubleOption =  select(moduleShrinkSym, "shrinkDoubleOption")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkStringOption</code> method definition. */
+    private val shrinkStringOption =  select(moduleShrinkSym, "shrinkStringOption")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkIntTuple2</code> method definition. */
+    private val shrinkIntTuple2    =  select(moduleShrinkSym, "shrinkIntTuple2")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkBooleanTuple2</code> method definition. */
+    private val shrinkBooleanTuple2=  select(moduleShrinkSym, "shrinkBooleanTuple2")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkDoubleTuple2</code> method definition. */
+    private val shrinkDoubleTuple2 =  select(moduleShrinkSym, "shrinkDoubleTuple2")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkStringTuple2</code> method definition. */
+    private val shrinkStringTuple2 =  select(moduleShrinkSym, "shrinkStringTuple2")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkIntTuple3</code> method definition. */
+    private val shrinkIntTuple3    =  select(moduleShrinkSym, "shrinkIntTuple3")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkBooleanTuple3</code> method definition. */
+    private val shrinkBooleanTuple3=  select(moduleShrinkSym, "shrinkBooleanTuple3")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkDoubleTuple3</code> method definition. */
+    private val shrinkDoubleTuple3 =  select(moduleShrinkSym, "shrinkDoubleTuple3")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkStringTuple3</code> method definition. */
+    private val shrinkStringTuple3 =  select(moduleShrinkSym, "shrinkStringTuple3")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkIntTuple4</code> method definition. */
+    private val shrinkIntTuple4    =  select(moduleShrinkSym, "shrinkIntTuple4")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkBooleanTuple4</code> method definition. */
+    private val shrinkBooleanTuple4=  select(moduleShrinkSym, "shrinkBooleanTuple4")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkDoubleTuple4</code> method definition. */
+    private val shrinkDoubleTuple4 =  select(moduleShrinkSym, "shrinkDoubleTuple4")
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkStringTuple4</code> method definition. */
+    private val shrinkStringTuple4 =  select(moduleShrinkSym, "shrinkStringTuple4")
+    
+    /** Symbol for the <code>org.scalacheck.Shrink.shrinkAny</code> method definition.
+     *  This is a generic shrinker which does not shrink whatever object is passed to it.
+     */
+    private val shrinkAny          =  select(moduleShrinkSym, "shrinkAny")
+    
+    def shrinker(tpe: Type): Select = tpe2shrinker.getOrElse(tpe, shrinkAny)
+    
+    private val tpe2shrinker: Map[Type, Select] = {
+      import definitions._
+      val SetClass: Symbol = definitions.getClass("scala.collection.immutable.Set")
+      
+      def apply(container: Type)(parametric: Type): Type = 
+        appliedType(container, List(parametric))
+        
+      def listOf(tpe: Type): Type = apply(ListClass.typeConstructor)(tpe) 
+      def setOf(tpe: Type): Type = apply(SetClass.typeConstructor)(tpe)
+      def optionOf(tpe: Type): Type = apply(OptionClass.typeConstructor)(tpe)
+      def tupleOf(arity: Int, tpe: Type): Type = apply(TupleClass(arity).typeConstructor)(tpe)
+      
+      val IntListTpe     = listOf(IntClass.typeConstructor)
+      val BooleanListTpe = listOf(BooleanClass.typeConstructor)
+      val DoubleListTpe  = listOf(DoubleClass.typeConstructor)
+      val StringListTpe  = listOf(StringClass.typeConstructor)
+      
+      val IntSetTpe      = setOf(IntClass.typeConstructor)
+      val BooleanSetTpe  = setOf(BooleanClass.typeConstructor)
+      val DoubleSetTpe   = setOf(DoubleClass.typeConstructor)
+      val StringSetTpe   = setOf(StringClass.typeConstructor)
+      
+      val IntOptionTpe     = optionOf(IntClass.typeConstructor)
+      val BooleanOptionTpe = optionOf(BooleanClass.typeConstructor)
+      val DoubleOptionTpe  = optionOf(DoubleClass.typeConstructor)
+      val StringOptionTpe  = optionOf(StringClass.typeConstructor)
+      
+      val IntTuple2Tpe     = tupleOf(2, IntClass.typeConstructor)
+      val BooleanTuple2Tpe = tupleOf(2, BooleanClass.typeConstructor)
+      val DoubleTuple2Tpe  = tupleOf(2, DoubleClass.typeConstructor)
+      val StringTuple2Tpe  = tupleOf(2, StringClass.typeConstructor)
+      
+      val IntTuple3Tpe     = tupleOf(3, IntClass.typeConstructor)
+      val BooleanTuple3Tpe = tupleOf(3, BooleanClass.typeConstructor)
+      val DoubleTuple3Tpe  = tupleOf(3, DoubleClass.typeConstructor)
+      val StringTuple3Tpe  = tupleOf(3, StringClass.typeConstructor)
+      
+      val IntTuple4Tpe     = tupleOf(4, IntClass.typeConstructor)
+      val BooleanTuple4Tpe = tupleOf(4, BooleanClass.typeConstructor)
+      val DoubleTuple4Tpe  = tupleOf(4, DoubleClass.typeConstructor)
+      val StringTuple4Tpe  = tupleOf(4, StringClass.typeConstructor)
+      
+      Map(IntClass.typeConstructor -> shrinkInt,
+          StringClass.typeConstructor     -> shrinkString, 
+          OptionClass.typeConstructor     -> shrinkOption,
+          ListClass.typeConstructor       -> shrinkList,
+          SetClass.typeConstructor        -> shrinkSet,
+          TupleClass(2).typeConstructor   -> shrinkTuple2,
+          TupleClass(3).typeConstructor   -> shrinkTuple3,
+          TupleClass(4).typeConstructor   -> shrinkTuple4,
+          TupleClass(5).typeConstructor   -> shrinkTuple5,
+          TupleClass(6).typeConstructor   -> shrinkTuple6,
+          TupleClass(7).typeConstructor   -> shrinkTuple7,
+          TupleClass(8).typeConstructor   -> shrinkTuple8,
+          TupleClass(9).typeConstructor   -> shrinkTuple9,
+          IntListTpe                      -> shrinkIntList,
+          BooleanListTpe                  -> shrinkBooleanList,
+          DoubleListTpe                   -> shrinkDoubleList,
+          StringListTpe                   -> shrinkStringList,
+          IntSetTpe                       -> shrinkIntSet,
+          BooleanSetTpe                   -> shrinkBooleanSet,
+          DoubleSetTpe                    -> shrinkDoubleSet,
+          StringSetTpe                    -> shrinkStringSet,
+          IntOptionTpe                    -> shrinkIntOption,
+          BooleanOptionTpe                -> shrinkBooleanOption,
+          DoubleOptionTpe                 -> shrinkDoubleOption,
+          StringOptionTpe                 -> shrinkStringOption,
+          IntTuple2Tpe                    -> shrinkIntTuple2,
+          BooleanTuple2Tpe                -> shrinkBooleanTuple2,
+          DoubleTuple2Tpe                 -> shrinkDoubleTuple2,
+          StringTuple2Tpe                 -> shrinkStringTuple2,
+          IntTuple3Tpe                    -> shrinkIntTuple3,
+          BooleanTuple3Tpe                -> shrinkBooleanTuple3,
+          DoubleTuple3Tpe                 -> shrinkDoubleTuple3,
+          StringTuple3Tpe                 -> shrinkStringTuple3,
+          IntTuple4Tpe                    -> shrinkIntTuple4,
+          BooleanTuple4Tpe                -> shrinkBooleanTuple4,
+          DoubleTuple4Tpe                 -> shrinkDoubleTuple4,
+          StringTuple4Tpe                 -> shrinkStringTuple4
+      )
+    }
+  }
+  
+  
+  object ConsoleReporter {
+    /** Symbol for the <code>org.scalacheck.ConsoleReporter</code> module definition. */
+    private val moduleConsoleReporterSym = definitions.getModule("org.scalacheck.ConsoleReporter")
+    
+    def testStatsEx(testRes: Tree): Tree = testStatsEx("", testRes)
+                                                       
+    def testStatsEx(msg: String, testRes: Tree): Tree = 
+      Apply(Select(Ident(moduleConsoleReporterSym), symDecl(moduleConsoleReporterSym, "testStatsEx")), List(Literal(msg), testRes))
+  }
+  
+  object Test {
+    /** Symbol for the <code>org.scalacheck.Test</code> module definition. */
+    private val moduleTestSym = definitions.getModule("org.scalacheck.Test")
+    
+    def check(prop: Tree): Tree = 
+      Apply(Select(Ident(moduleTestSym), symDecl(moduleTestSym, "check")), List(prop))
+  }
 }
diff --git a/src/funcheck/scalacheck/ScalaCheckIntegrator.scala b/src/funcheck/scalacheck/ScalaCheckIntegrator.scala
index 5b7514efe42aa4de9ff869aed4183a33c6945996..c212589ad9acaad69f4cf98d6f018c95a110db73 100644
--- a/src/funcheck/scalacheck/ScalaCheckIntegrator.scala
+++ b/src/funcheck/scalacheck/ScalaCheckIntegrator.scala
@@ -1,14 +1,14 @@
 package funcheck.scalacheck
 
 import scala.tools.nsc.{Global, SubComponent}
-import funcheck.util.FreshNameCreator
 
-trait ScalaCheckIntegrator[T <: SubComponent] extends ScalaCheck[T] 
-  with FilterGeneratorAnnotations[T]
+
+trait ScalaCheckIntegrator extends ScalaCheck 
+  with FilterGeneratorAnnotations
   with GeneratorDefDefInjector
-  with FreshNameCreator 
+  with ForAllTransformer 
 {
-  self: T =>
+  val global: Global
   import global._
   
   
@@ -27,198 +27,5 @@ trait ScalaCheckIntegrator[T <: SubComponent] extends ScalaCheck[T]
     (Gen.createGenDefDef(klasses.toList,defs.toList), Arbitrary.getArbitraryDefDefs)
   }
   
-  object Gen extends Gen {
-    /** 
-     * Map that stores for each @generator annotated ClassDef or DefDef the automatically  
-     * generated DefDef for creating instances of the <code>org.scalacheck.Gen</code> class.
-     * The <code>Type</code> that is associated to the DefDef is either the type of the 
-     * ClassDef or the returning type of the DefDef.
-     */
-    private val tpe2listGen = scala.collection.mutable.Map.empty[Type, List[DefDef]]
-    private val tpe2listGenSym = scala.collection.mutable.Map.empty[Type, List[Symbol]]
-    
-     /** 
-     * Add the <code>gen</code> generator DefDef declaration to the list of 
-     * generators for <code>tpe</code>.
-     * 
-     * @param tpe The type of elements generated by the <code>gen</code>.
-     * @param gen The DefDef declaration for the generator method.
-     */
-    def +[T](map: collection.mutable.Map[Type, List[T]], key: Type, value: T): Unit = map.get(key) match {
-      case None         => map += key -> List(value)
-      case Some(values) => map += key -> (value :: values)
-    }
-   
-    /** List of generator DefDef symbols for a given type <code>tpe</code>*/
-    def genSymbolsForType(tpe: Type): List[Symbol] = tpe2listGenSym.get(tpe) match {
-      case None => Nil
-      case Some(symbols) => symbols
-    } 
-    
-    /** 
-     * Second Pass: Create symbols for the generator DefDef that will be created
-     * durind the Third Pass.
-     */
-    def createGenDefDef(klasses: List[ClassDef], defs: List[DefDef]): List[DefDef] = {
-      val generable: List[(Symbol,Tree)] = createGenDefSyms(klasses, defs)
-      
-      for { (genSym, genTree) <- generable } genTree match {
-        case cd: ClassDef => 
-          val tpe = cd.symbol.tpe
-          Gen + (tpe2listGen, tpe, Gen.createGenDef(cd, genSym))
-        
-        case d: DefDef =>
-          val tpe = d.tpt.symbol.tpe
-          val generated = DefDef(genSym, Modifiers(0), List(), rhsGenDef(Ident(d.name))(d)(genSym))
-          Gen + (tpe2listGen, tpe, generated)
-      }
-      
-      // flatten into single list values of Gen.tpe2listGen
-      (List[DefDef]() /: Gen.tpe2listGen.values) {
-        case (xs, xss) => xs ::: xss
-      }
-    }
-    
-    
-    /** 
-     * Create method symbols for each <code>@generator</code> annotated ClassDef
-     * and DefDef.
-     */
-    private def createGenDefSyms(klasses: List[ClassDef], defs: List[DefDef]): List[(Symbol, Tree)] = {
-    
-      val genKlasses: List[(Symbol, ClassDef)] = for(klass <- klasses) yield {
-        val genName = fresh.newName("gen"+klass.name)
-        val tpe = klass.symbol.tpe
-        val genSym = createGenDefSymbol(klass.symbol.enclClass.owner, genName, tpe)
-        
-        Gen + (tpe2listGenSym, tpe, genSym)
-        
-        (genSym, klass)
-      }
-    
-      val genDefs: List[(Symbol, DefDef)] = for(d <- defs) yield {
-        val genName = fresh.newName("gen"+d.name)
-        val tpe = d.tpt.symbol.tpe
-        val genSym = createGenDefSymbol(d.symbol.owner, genName, tpe)
-        
-        Gen + (tpe2listGenSym, tpe, genSym)
-        
-        (genSym, d)
-      }
-    
-      genKlasses ::: genDefs
-    }
-    
-    
-    
-    def createGenDef(cd: ClassDef, genDef: Symbol): DefDef = {
-      val d: DefDef = getConstructorOf(cd)
-      val DefDef(_,_,_,vparamss,retTpe,_) = d 
-      assert(vparamss.size <= 1, "currying is not supported. Change signature of "+cd.symbol)
-      
-      
-      if(cd.symbol.hasFlag(scala.tools.nsc.symtab.Flags.ABSTRACT)) {
-        val generators = retTpe.symbol.children.toList.map(s => genSymbolsForType(s.tpe)).flatMap(v=>v)
-        DefDef(genDef, Modifiers(0), List(), Gen.oneOf(generators))
-      } 
-      else {
-        
-        val constrObj = resetAttrs(d.tpt.duplicate)
-        val instance = Select(New(constrObj), nme.CONSTRUCTOR)
-        
-        assert(d.tpt.isInstanceOf[TypeTree])
-        
-        val body = rhsGenDef(instance)(d)(genDef)
-        DefDef(genDef, Modifiers(0), List(), body)
-      }
-    }
-    
-    
-     /** <code>base</code> is either 
-     *       - Select(New(tpe),constructor) [constructor] 
-     *       - Ident(name)   [method call]
-     */
-    private def rhsGenDef(base: Tree)(d: DefDef)(extOwner: Symbol): Tree = {
-      val DefDef(_,name,_,vparamss,retTpe,_) = d
-      assert(vparamss.size <= 1, "currying is not supported. Change signature of "+d.symbol)
-      
-      if(vparamss.head.isEmpty)
-        Gen.value(Apply(base, Nil))
-      
-      else {
-        var owner = extOwner
-      
-        val paramssTpe: List[ValDef] = vparamss.flatMap(v=>v).map(p => 
-          ValDef(Modifiers(0), fresh.newName("v"), resetAttrs(p.tpt.duplicate), EmptyTree))
-      
-      
-        var last = true
-      
-      
-        val z :Tree = Apply(base, paramssTpe.map(p => Ident(p.name)))
-        val body = (paramssTpe :\ z) {
-          case (param,apply) => {
-            val body = Function(List(param), apply)
-            body.symbol.owner = owner
-            owner = body.symbol
-            //XXX: it is not flatMap in general. fix this!!
-            if(last) {
-              last = false
-              Gen.map(Arbitrary.arbitrary(param.tpt.asInstanceOf[TypeTree]), body)
-            } else
-              Gen.flatMap(Arbitrary.arbitrary(param.tpt.asInstanceOf[TypeTree]), body)
-          }
-        }
-      
-        body
-      }
-    }
-   
-    
-    
-    private def getConstructorOf(cd: ClassDef): DefDef = {
-      val Template(parents, self, body) = cd.impl
-      var dd: DefDef  = null
-      for { b <- body } b match {
-        case d @ DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => dd = d
-        case _ => ;
-      }
-      dd
-    } ensuring (res => res != null)
-
-  }
-  
   
-  object Arbitrary extends Arbitrary {
-    
-    /** Map that stores not built-in <code>org.scalacheck.Arbitrary</code> DefDef definitions. */
-    private val tpe2arbDefDef = scala.collection.mutable.Map.empty[Type,DefDef]
-    
-    def getArbitraryDefDefs: List[DefDef] = tpe2arbDefDef.values.toList
-    
-    override protected def arbitrary(tpeSym: Symbol): Apply = {
-      require(tpe2arbApp.get(tpeSym.tpe).isEmpty, "Arbitrary.arbitrary["+tpeSym.tpe+"] is already in the map")
-      
-      val owner = tpeSym.toplevelClass
-      val arbName = fresh.newName("arb"+tpeSym.name)
-      val tpe = tpeSym.tpe
-      
-      val arbDef = createArbitraryDefSymbol(owner, arbName, tpe)
-      
-            
-      val genNames = Gen.genSymbolsForType(tpe)
-      
-      
-      val generated = DefDef(arbDef, Modifiers(0), List(), Arbitrary(Gen.oneOf(genNames)))
-      tpe2arbDefDef += tpe -> generated  
-      
-      val result = applyArbitrary(Ident(arbDef))
-      tpe2arbApp += tpe -> result
-        
-      result
-            
-    }
-    
-    
-  }
 }