diff --git a/sources/zweic/Analyzer.scala b/sources/zweic/Analyzer.scala
index 86deb1e..89c0427 100755
--- a/sources/zweic/Analyzer.scala
+++ b/sources/zweic/Analyzer.scala
@@ -88,12 +88,12 @@
 			case None =>
 				val mt = analyzeType(typ);
 				checkSubtype(tree.pos, "Incompatible types", analyzeExpr(varScope, expr), mt);
-				varScope + name.name -> VarSymbol(tree.pos, name.name, mt);
+				val ms = VarSymbol(tree.pos, name.name, mt);
+				ident.sym = ms;
+				varScope + name.name -> ms;
 		}
 
-	// ... � compl�ter ...
 	case Set(ident, expr) =>
-	//TODO: this method is copied from lecture script, check if it's correct
 		varScope.get(ident.name) match {
 			case Some(v) =>
 				ident.sym = v;
@@ -102,6 +102,18 @@
 				Report.error(tree.pos, "Unknown variable " + ident.name);
 		}
 		varScope
+
+	case Do(expr) =>
+		analyzeExpr(varScope, expr);
+		varScope
+
+	case PrintInt(expr) =>
+		checkIntType(tree.pos, analyzeExpr(varScope, expr));
+		varScope
+
+	case PrintChar(expr) =>
+		checkIntType(tree.pos, analyzeExpr(varScope, expr));
+		varScope
     }
 
   // Analyze a type
@@ -123,22 +135,70 @@
   // Analyze an expression
   private def analyzeExpr(varScope: VarScope, tree: Expr): Type =
     tree match {
-      // ... � compl�ter ...
-      case NullLit() =>
-        INullType
+	// ... � compl�ter ...
+	case Ident(name) =>
+		varScope.get(name.name) match {
+			case Some(v) =>
+				name.sym = v;
+				v.vartype
+			case None =>
+				Report.error(tree.pos, "Unknown variable " + name);
+				IBadType
+		}
 
-      case IntLit(_) =>
-        IIntType
-      // ... � compl�ter ...
-      case Ident(name) =>
-      	varScope.get(name.name) match {
-		case Some(v) =>
-			name.sym = v;
-			v.vartype
-		case None =>
-			Report.error(tree.pos, "Unknown variable " + name);
-			IBadType
-	}
+	case Select(expr, name) =>
+		val ct = analyzeExpr(varScope, expr);
+		ct.c.lookupField(name.name) match {
+			case Some(v) =>
+				name.sym = v;
+				v.fieldtype
+			case None =>
+				Report.error(tree.pos, "Unknown class variable " + name + " in " + ct);
+				IBadType
+		}
+
+	case Call(expr, name, args) =>
+		val ct = analyzeExpr(varScope, expr); //XXX: this implies checking if class exists
+		ct.c.lookupMethod(name.name) match {
+			case Some(v) =>
+				if (args.length != v.paramtypes.length) {
+					Report.error(tree.pos, "Wrong number of arguments for class method " + name + " in " + ct);
+					IBadType
+				}
+				if ( !args.map(x => analyzeExpr(varScope, x)).zip(v.paramtypes).forall(Tuple(a,b) => checkSubtype(tree.pos, "Incompatible types", a, b)) )
+					IBadType
+				name.sym = v;
+				v.restype
+			case None =>
+				Report.error(tree.pos, "Unknown class method " + name + " in " + ct);
+				IBadType
+		}
+
+	case New(name, args) =>
+		classScope.get(name.name) match {
+			case Some(v) =>
+				if (args.length !=  v.allFields.length) {
+					Report.error(tree.pos, "Wrong number of arguments for class constructor in " + ct);
+					IBadType
+				}
+				if ( args.map(x => analyzeExpr(varScope, x)).zip(v.allFields).forall(Tuple(a,b) => checkSubtype(tree.pos, "Incompatible types", a, b)) )
+					IBadType
+				name.sym = v;
+				IClassType(v)
+			case None =>
+				Report.error(tree.pos, "Class " + name + " is unknown");
+				IBadType
+		}
+
+	case NullLit() =>
+		INullType
+
+	case IntLit(_) =>
+		IIntType
+
+	case Unop(op, expr) =>
+		checkIntType(tree.pos, analyzeExpr(varScope, expr))
+		IIntType
 
 	case Binop(op, left, right) =>
 		val t1 = analyzeExpr(varScope, left);
@@ -151,6 +211,19 @@
 			checkIntType(right.pos, t2);
 		}
 		IIntType
+
+	case ReadInt =>
+		IIntType
+
+	case ReadChar =>
+		IIntType
+
+	case If(cond, stata, statb) =>
+		checkIntType(analyzeExpr(varScope, cond))
+		analyzeExpr(varScope, stata).lub(analyzeExpr(varScope, statb))
+
+	case Block(stats, expr) =>
+		analyzeExpr(stats.foldLeft(varScope)(analyzeStat), expr)
     }
 
   /**