diff --git a/src/main/scala/leon/codegen/CodeGen.scala b/src/main/scala/leon/codegen/CodeGen.scala
deleted file mode 100644
index 7f84a897682d716f751f12dbdb68cdf00f9466de..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/codegen/CodeGen.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-package leon
-package codegen
-
-import purescala.Common._
-import purescala.Definitions._
-
-object CodeGenPhase extends LeonPhase[Program,CompilationResult] {
-  val name = "CodeGen"
-  val description = "Compiles a Leon program into Java methods"
-
-  def run(ctx : LeonContext)(p : Program) : CompilationResult = {
-    CompilationResult(successful = true)
-  } 
-}
diff --git a/src/main/scala/leon/codegen/CodeGenPhase.scala b/src/main/scala/leon/codegen/CodeGenPhase.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5c6c0ef16dabd3dd2b1ddafdb7d0b54fffd36f88
--- /dev/null
+++ b/src/main/scala/leon/codegen/CodeGenPhase.scala
@@ -0,0 +1,43 @@
+package leon
+package codegen
+
+import purescala.Common._
+import purescala.Definitions._
+
+import cafebabe._
+import cafebabe.ClassFileTypes.U2
+import cafebabe.Flags._
+
+object CodeGenPhase extends LeonPhase[Program,CompilationResult] {
+  val name = "CodeGen"
+  val description = "Compiles a Leon program into Java methods"
+
+  def run(ctx : LeonContext)(p : Program) : CompilationResult = {
+    import CodeGeneration._
+
+    implicit val env = CompilationEnvironment.fromProgram(p)
+
+    val cName = programToClassName(p)
+
+    val cf = new ClassFile(cName, None)
+    cf.setFlags(
+      (cf.getFlags | CLASS_ACC_PUBLIC | CLASS_ACC_FINAL).asInstanceOf[U2]
+    )
+
+    // This assumes that all functions of a given program get compiled
+    // as methods of a single class file.
+    for(funDef <- p.definedFunctions;
+        (_,mn) <- env.funDefToMethod(funDef)) {
+
+      val m = cf.addMethod(
+        typeToJVM(funDef.returnType),
+        mn,
+        funDef.args.map(a => typeToJVM(a.tpe)) : _*
+      )
+ 
+      CodeGeneration.compileFunDef(funDef, m.codeHandler)
+    }
+
+    CompilationResult(successful = true)
+  } 
+}
diff --git a/src/main/scala/leon/codegen/CodeGeneration.scala b/src/main/scala/leon/codegen/CodeGeneration.scala
new file mode 100644
index 0000000000000000000000000000000000000000..3fd57a438a86c5bf2ac669f7de0ff19ce8041188
--- /dev/null
+++ b/src/main/scala/leon/codegen/CodeGeneration.scala
@@ -0,0 +1,61 @@
+package leon
+package codegen
+
+import purescala.Common._
+import purescala.Definitions._
+import purescala.Trees._
+import purescala.TypeTrees._
+
+import cafebabe._
+import cafebabe.ByteCodes._
+import cafebabe.AbstractByteCodes._
+
+object CodeGeneration {
+  def programToClassName(p : Program) : String = "Leon$CodeGen$" + p.mainObject.id.uniqueName
+
+  def typeToJVM(tpe : TypeTree)(implicit env : CompilationEnvironment) : String = tpe match {
+    case Int32Type => "I"
+    case BooleanType => "Z"
+    case _ => throw CompilationException("Unsupported type : " + tpe)
+  }
+
+  // Assumes the CodeHandler has never received any bytecode.
+  // Generates method body, and freezes the handler at the end.
+  def compileFunDef(funDef : FunDef, ch : CodeHandler)(implicit env : CompilationEnvironment) {
+    // TODO, change environment to include args.
+    mkExpr(funDef.getBody, ch)
+
+    funDef.returnType match {
+      case Int32Type | BooleanType =>
+        ch << IRETURN
+
+      case other =>
+        throw CompilationException("Unsupported return type : " + other)
+    }
+
+    ch.freeze
+  }
+
+  private def mkExpr(e : Expr, ch : CodeHandler)(implicit env : CompilationEnvironment) {
+    e match {
+      case IntLiteral(v) => ch << Ldc(v)
+      case BooleanLiteral(true) => ch << Ldc(1)
+      case BooleanLiteral(false) => ch << Ldc(0)
+
+      case Plus(l, r) =>
+        mkExpr(l, ch)
+        mkExpr(r, ch)
+        ch << IADD
+
+      case Minus(l, r) =>
+        mkExpr(l, ch)
+        mkExpr(r, ch)
+        ch << ISUB
+
+      case UMinus(e) =>
+        mkExpr(Minus(IntLiteral(0), e), ch)
+
+      case _ => throw CompilationException("Unsupported expr : " + e) 
+    }
+  }
+}
diff --git a/src/main/scala/leon/codegen/CompilationEnvironment.scala b/src/main/scala/leon/codegen/CompilationEnvironment.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1eb9514e1a81e8b615928f6b9f5da0a10d0b4557
--- /dev/null
+++ b/src/main/scala/leon/codegen/CompilationEnvironment.scala
@@ -0,0 +1,27 @@
+package leon
+package codegen
+
+import purescala.Common._
+import purescala.Definitions._
+
+abstract class CompilationEnvironment() {
+  // Should contain:
+  //   - a mapping of function defs to class + method name
+  //   - a mapping of class defs to class names
+  //   - a mapping of class fields to fields
+
+  def funDefToMethod(funDef : FunDef) : Option[(String,String)]
+}
+
+object CompilationEnvironment {
+  def fromProgram(p : Program) : CompilationEnvironment = {
+    val className = CodeGeneration.programToClassName(p)
+
+    val fs = p.definedFunctions.filter(_.hasImplementation)
+    val fPairs : Map[FunDef,String] = fs.map(fd => (fd -> fd.id.uniqueName)).toMap
+
+    new CompilationEnvironment {
+      def funDefToMethod(funDef : FunDef) = fPairs.get(funDef).map(n => (className, n))
+    }
+  }
+}
diff --git a/src/main/scala/leon/codegen/CompilationException.scala b/src/main/scala/leon/codegen/CompilationException.scala
new file mode 100644
index 0000000000000000000000000000000000000000..236cc586e64b487170ba7f80377d8e690742c120
--- /dev/null
+++ b/src/main/scala/leon/codegen/CompilationException.scala
@@ -0,0 +1,6 @@
+package leon
+package codegen
+
+case class CompilationException(msg : String) extends Exception {
+  override def getMessage = msg
+}
diff --git a/src/test/resources/regression/codegen/purescala/Prog001.scala b/src/test/resources/regression/codegen/purescala/Prog001.scala
index c0eb52647720910e8f9a43c19a3af4f88c10261b..c0edc779fbcba95cec98102a9a4699fbbc12ef80 100644
--- a/src/test/resources/regression/codegen/purescala/Prog001.scala
+++ b/src/test/resources/regression/codegen/purescala/Prog001.scala
@@ -1,3 +1,5 @@
 object Prog001 {
-  def plus(x : Int, y : Int) : Int = x + y
+  def fortyTwo() = 42
+
+  // def plus(x : Int, y : Int) = x + y
 }
diff --git a/unmanaged/32/cafebabe_2.9.2-1.2.jar b/unmanaged/32/cafebabe_2.9.2-1.2.jar
index 57defc82adbd3db0baa2f7bfe33f08f1ee2f9e38..a7f91ed1b7e26933e0b0c657dbd2f240a423dc50 100644
Binary files a/unmanaged/32/cafebabe_2.9.2-1.2.jar and b/unmanaged/32/cafebabe_2.9.2-1.2.jar differ