diff --git a/HelperFunctions.hs b/HelperFunctions.hs
index fea11878aff214779080ab361ebd90389329ab99..05c39c01421cdc499f291cfdeaaf9f3376380a95 100644
--- a/HelperFunctions.hs
+++ b/HelperFunctions.hs
@@ -102,17 +102,17 @@ getMethod' classTypeDecls methodId = case (concatMap searchClass classTypeDecls)
 getMainMethod :: [TypeDecl] -> Stmt
 getMainMethod classTypeDecls = fromJust' "getMainMethod" $ getMethod classTypeDecls (Ident "main")
 
+-- Gets a list of all method Idents (except constructor methods)
+getMethodIds :: [TypeDecl] -> [Ident]
+getMethodIds classTypeDecls = concatMap searchClass classTypeDecls where
+    searchClass (ClassTypeDecl (ClassDecl _ _ _ _ _ (ClassBody decls))) = searchDecls decls
+    searchDecls (MemberDecl (MethodDecl _ _ _ id _ _ _):decls) = id : searchDecls decls
+    searchDecls (_:decls) = searchDecls decls
+    searchDecls [] = []
+
 -- Gets the class declarations
 getDecls :: CompilationUnit -> [TypeDecl]
 getDecls (CompilationUnit _ _ classTypeDecls) = classTypeDecls
-
--- Gets the static member declarations and puts them in the type environment
-getStaticVars :: CompilationUnit -> TypeEnv
-getStaticVars compUnit = concatMap fromTypeDecls (getDecls compUnit) where
-    fromTypeDecls (ClassTypeDecl (ClassDecl _ _ _ _ _ (ClassBody decls))) = concatMap fromMemberDecl decls
-    fromMemberDecl (MemberDecl (FieldDecl mods t varDecls)) = if Static `elem` mods then map (fromVarDecl t) varDecls else []
-    fromMemberDecl _                                        = []
-    fromVarDecl t (VarDecl varId _) = (Name [getId varId], t)
     
 -- Checks if the var is introduced. Introduced variable names start with '$' voor return variables of methods and '#' for other variables
 isIntroducedVar :: Name -> Bool
@@ -130,6 +130,11 @@ invocationToId (MethodCall name _) = getMethodId name
 invocationToId (PrimaryMethodCall _ _ id _) = id
 invocationToId _ = undefined
 
+-- Gets the type of the elements of an array. Recursion is needed in the case of multiple dimensional arrays
+arrayContentType :: Type -> Type
+arrayContentType (RefType (ArrayType t)) = arrayContentType t
+arrayContentType t = t
+
 -- Gets a new unique variable
 getVar :: Ident
 getVar = Ident ('#' : show (getIncrPointer varPointer))
diff --git a/Main.hs b/Main.hs
index 2fe1ca8026b904983167af0e463accc91a1679fd..5f45bdd5689bf60381b01451b1a436882f98df20 100644
--- a/Main.hs
+++ b/Main.hs
@@ -4,10 +4,12 @@ import Language.Java.Syntax
 import Language.Java.Parser
 import Language.Java.Pretty
 import Data.List
+import Control.Monad
 import System.FilePath(joinPath)
 
 
 import WLP
+import Types
 import Verifier
 import HelperFunctions
 import Settings
@@ -22,16 +24,23 @@ main = do
     case result of
         Left error -> print error
         Right compUnit -> do
-                            putStrLn "\r\n-----Code-----"
-                            print compUnit
-                            putStrLn "\r\n-----WLP-----"
-                            let pred = wlpWithEnv (getDecls compUnit) (getStaticVars compUnit) (getMainMethod (getDecls compUnit)) postCond'
-                            putStrLn . prettyPrint $ pred
-                            putStrLn "\r\n-----Correctness-----"
-                            if unsafeIsTrue pred then putStrLn "WLP evaluates to true" else (if unsafeIsFalse pred then putStrLn "WLP evaluates to false" else putStrLn "undecidable")
+                            let decls = getDecls compUnit
+                            let methods = getMethodIds decls
+                            let env = getTypeEnv compUnit decls methods
+                         --   putStrLn "\r\n-----Code-----"
+                         --   print compUnit
+                            mapM_ (testMethod compUnit env decls) methods
                             
-                            
-
+-- | Calculates and prints the wlp for a given method
+testMethod :: CompilationUnit -> TypeEnv -> [TypeDecl] -> Ident -> IO ()
+testMethod compUnit env decls id = do
+    putStrLn "--------------"
+    putStrLn (prettyPrint id ++ "\r\n")
+    let pred = wlpWithEnv decls env (fromJust' "testMethod" $ getMethod decls id) postCond'
+    putStrLn . prettyPrint $ pred
+    putStrLn ""
+    if unsafeIsTrue env pred then putStrLn "WLP evaluates to true" else (if unsafeIsFalse env pred then putStrLn "WLP evaluates to false" else putStrLn "undecidable")
+    putStrLn "--------------"
 
 -- The post-condition (for testing)
 postCond' :: Exp
diff --git a/Settings.hs b/Settings.hs
index 0653c923a48040ec5b61689e81b9e9650329ca79..0e4b16f0750287d364f51c0c7c582b23ce59ed6b 100644
--- a/Settings.hs
+++ b/Settings.hs
@@ -1,7 +1,7 @@
 module Settings where
 
 testFile, postCond :: String
-testFile = "arrays3"
+testFile = "arrays1"
 postCond = "(true)"
 
 nrOfUnroll :: Int
diff --git a/Tests/2d-arrays1.java b/Tests/2d-arrays1.java
index 9841c300e3ada474acea61334094e94ebbec4a42..6d1d2baeb4ccf5ab2d387edfe5b9b1d252159b33 100644
--- a/Tests/2d-arrays1.java
+++ b/Tests/2d-arrays1.java
@@ -59,9 +59,9 @@ public class Life {
     }
     
     public static boolean occupiedNext(int numNeighbors, boolean occupied){
-        if( occupied && (numNeighbors == 2 || numNeighbors == 3))
+        if(occupied && ((numNeighbors == 2) || (numNeighbors == 3)))
             return true;
-        else if (!occupied && numNeighbors == 3)
+        else if ((!occupied) && (numNeighbors == 3))
             return true;
         else
             return false;
@@ -69,17 +69,17 @@ public class Life {
 
     private static int numNeighbors(boolean[][] world, int row, int col) {
         int num2 = world[row][col] ? -1 : 0;
-        for(int r1 = row - 1; r1 <= row + 1; r1++)
-            for(int c1 = col - 1; c1 <= col + 1; c1++)
-                if( inbounds(world, r1, c1) && world[r1][c1] )
+        for(int r1 = (row - 1); r1 <= (row + 1); r1++)
+            for(int c1 = (col - 1); c1 <= (col + 1); c1++)
+                if((inbounds(world, r1, c1)) && (world[r1][c1]) )
                     num2++;
 
         return num2;
     }
 
     private static boolean inbounds(boolean[][] world, int i, int c2) {
-        return i >= 0 && i < world.length && c2 >= 0 &&
-        c2 < world[0].length;
+        return (i >= 0) && (i < world.length) && (c2 >= 0) &&
+        (c2 < world[0].length);
     }
     
     
diff --git a/Tests/arrays1.java b/Tests/arrays1.java
index 9f0ef348a3a52d3df25870c0ca2e0953c1625d66..fdffebf49a2f2358e0e190d823968da3781f67a6 100644
--- a/Tests/arrays1.java
+++ b/Tests/arrays1.java
@@ -9,7 +9,7 @@ public class ArrayExamples
     
 		findAndPrintPairs(list, 5);
 		bubblesort(list);
-        /*
+        
 		showList(list);
 
 		list = new int[11];
@@ -23,14 +23,14 @@ public class ArrayExamples
 		list = new int[1];
 		bubblesort(list);
 		showList(list);
-        */
+        
 	}
 
 
 	// pre: list != null, list.length > 0
 	// post: return index of minimum element of array
 	public static int findMin(int[] list2)
-	{	assert list2 != null && list2.length > 0 : "failed precondition";
+	{	assert (list2 != null) && (list2.length > 0) : "failed precondition";
 
 		int indexOfMin = 0;
 		for(int k = 1; k < list2.length; k++)
@@ -49,7 +49,7 @@ public class ArrayExamples
 	 * argument
 	 */
 	public static void badResize(int[] list3, int newSize)
-	{	assert list3 != null && newSize >= 0 : "failed precondition";
+	{	assert (list3 != null) && (newSize >= 0) : "failed precondition";
 
 		int[] temp = new int[newSize];
 		int limit = Math.min(list3.length, newSize);
@@ -70,7 +70,7 @@ public class ArrayExamples
 	 *	will be copied into the new array
 	 */
 	public static int[] goodResize(int[] list4, int newSize)
-	{	assert list4 != null && newSize >= 0 : "failed precondition";
+	{	assert (list4 != null) && (newSize >= 0) : "failed precondition";
 
 		int[] result = new int[newSize];
 		int limit = Math.min(list4.length, newSize);
@@ -110,7 +110,7 @@ public class ArrayExamples
 	{
 		assert list6 != null : "failed precondition";
 
-		int temp;
+		int temp2;
 		boolean changed = true;
 		for(int n = 0; (n < list6.length) && changed; n++)
 		{	changed = false;
@@ -119,9 +119,9 @@ public class ArrayExamples
 					"is out of bounds.";
 				if(list6[o] > list6[o+1])
 				{	changed = true;
-					temp = list6[o + 1];
+					temp2 = list6[o + 1];
 					list6[o + 1] = list6[o];
-					list6[o] = temp;
+					list6[o] = temp2;
 				}
 			}
 		}
diff --git a/Tests/methods.java b/Tests/methods.java
index 47b8dfdcea5a197a035670288a461f4810d1e6b1..661059a1105f84f837a7ebd7148640f67d67d064 100644
--- a/Tests/methods.java
+++ b/Tests/methods.java
@@ -6,8 +6,8 @@ public static class Main
         C c1, c2;
         c1 = new C(1);
         c2 = new C(0);
-        c1.method1(1);
-        c2.method1(1); 
+        c1.method1(1, true);
+        c2.method1(1, true); 
         x = c1.c + c2.c;
        // C.staticMethod();
     }
@@ -34,12 +34,12 @@ public class C
         x = 4;
     }
     
-    public void method1(int n)
+    public void method1(int n, boolean b)
     {
-        
+        assert b;
         this.c += n;
         if(this.c < 2)
-            this.method1(); 
+            this.method1();
     }
     
     public int method2()
diff --git a/Types.hs b/Types.hs
new file mode 100644
index 0000000000000000000000000000000000000000..26d984dd9f39a226072d356c8bcd927f6aeaaf0e
--- /dev/null
+++ b/Types.hs
@@ -0,0 +1,79 @@
+module Types where
+
+import Language.Java.Syntax
+import Data.Maybe
+import Data.List
+
+import Folds
+import HelperFunctions
+import Settings
+
+
+typesStmtAlgebra :: StmtAlgebra TypeEnv
+typesStmtAlgebra = (fStmtBlock, fIfThen, fIfThenElse, fWhile, fBasicFor, fEnhancedFor, fEmpty, fExpStmt, fAssert, fSwitch, fDo, fBreak, fContinue, fReturn, fSynchronized, fThrow, fTry, fLabeled) where
+    fStmtBlock b                    = envBlock b
+    fIfThen e s1                    = s1
+    fIfThenElse e s1 s2             = s1 ++ s2
+    fWhile e s                      = s
+    fBasicFor init me incr s        = case init of
+                                        Just (ForLocalVars mods t vars) -> foldr (\v env' -> (varName v, t):env') s vars
+                                        _ -> s
+    fEnhancedFor                    = error "EnhancedFor"
+    fEmpty                          = []
+    fExpStmt e                      = []    
+    fAssert e _                     = []
+    fSwitch e bs                    = concatMap envSwitch bs
+    fDo s e                         = s
+    fBreak _                        = []
+    fContinue _                     = []
+    fReturn me                      = []
+    fSynchronized _ _               = []
+    fThrow e                        = []
+    fTry b cs f                     = envBlock b ++ concatMap envCatch cs ++ 
+                                        (case f of
+                                            Just b  -> envBlock b
+                                            _       -> [])
+    fLabeled _ s                    = s
+    
+                                                        
+    -- Adds declarations within a block to a type environment
+    envBlock :: Block -> TypeEnv
+    envBlock (Block bs) = foldl f [] bs 
+        where f env (LocalVars mods t vars)  = foldr (\v env' -> (varName v, t):env') env vars
+              f env (BlockStmt s)            = foldStmt typesStmtAlgebra s ++ env
+              f env _                        = env
+              
+    varName (VarDecl (VarId id) _) = Name [id]
+                                                        
+    -- Adds declarations within a switchblock block to a type environment
+    envSwitch :: SwitchBlock -> TypeEnv
+    envSwitch (SwitchBlock _ bs) = envBlock (Block bs)
+    
+    -- Adds declarations within a catchblock block to a type environment
+    envCatch :: Catch -> TypeEnv
+    envCatch (Catch (FormalParam _ t _ varId) b) = (Name [getId varId], t) : envBlock b
+
+    
+-- Gets the types of all variables that are declared in a statement
+getStmtTypeEnv :: Stmt -> TypeEnv
+getStmtTypeEnv = foldStmt typesStmtAlgebra
+
+-- Gets the parameters of a function and puts them in the type environment
+getMethodTypeEnv :: [TypeDecl] -> Ident -> TypeEnv
+getMethodTypeEnv decls id = case getMethodParams decls id of
+                                Nothing     -> []
+                                Just params -> map fromParam params
+  where
+    fromParam (FormalParam _ t _ paramId) = (Name [getId paramId], t)
+
+-- Gets the static member declarations and puts them in the type environment
+getStaticVarsTypeEnv :: CompilationUnit -> TypeEnv
+getStaticVarsTypeEnv compUnit = concatMap fromTypeDecls (getDecls compUnit) where
+    fromTypeDecls (ClassTypeDecl (ClassDecl _ _ _ _ _ (ClassBody decls))) = concatMap fromMemberDecl decls
+    fromMemberDecl (MemberDecl (FieldDecl mods t varDecls)) = if Static `elem` mods then map (fromVarDecl t) varDecls else []
+    fromMemberDecl _                                        = []
+    fromVarDecl t (VarDecl varId _) = (Name [getId varId], t)
+    
+-- Gets the type env for a compilation unit
+getTypeEnv :: CompilationUnit -> [TypeDecl] -> [Ident] -> TypeEnv
+getTypeEnv compUnit decls methods = getStaticVarsTypeEnv compUnit ++ concatMap (getMethodTypeEnv decls) methods ++ concatMap (getStmtTypeEnv . fromJust . getMethod decls) methods
\ No newline at end of file
diff --git a/Verifier.hs b/Verifier.hs
index d86c402736874307f12a349bd831eb60733f7dc3..c2406e9720b9305ff1586422653d60e217f54cd0 100644
--- a/Verifier.hs
+++ b/Verifier.hs
@@ -10,15 +10,15 @@ import HelperFunctions
 
 
 -- | Checks wether the negation is unsatisfiable
-isTrue :: Exp -> Z3 Bool
-isTrue e = isFalse (PreNot e)
+isTrue :: TypeEnv -> Exp -> Z3 Bool
+isTrue env e = isFalse env (PreNot e)
             
           
 -- | Checks wether the expression is unsatisfiable
-isFalse :: Exp -> Z3 Bool
-isFalse e = 
+isFalse :: TypeEnv -> Exp -> Z3 Bool
+isFalse env e = 
     do
-        ast <- foldExp expAssertAlgebra e
+        ast <- foldExp expAssertAlgebra e env
         assert ast
         result <- check
         solverReset
@@ -27,12 +27,12 @@ isFalse e =
             _     -> return False
         
 -- | Unsafe version of isTrue
-unsafeIsTrue :: Exp -> Bool
-unsafeIsTrue = unsafePerformIO . evalZ3 . isTrue
+unsafeIsTrue :: TypeEnv -> Exp -> Bool
+unsafeIsTrue env = unsafePerformIO . evalZ3 . isTrue env
 
 -- | Unsafe version of isFalse
-unsafeIsFalse :: Exp -> Bool
-unsafeIsFalse = unsafePerformIO . evalZ3 . isFalse
+unsafeIsFalse :: TypeEnv -> Exp -> Bool
+unsafeIsFalse env = unsafePerformIO . evalZ3 . isFalse env
 
 stringToBv :: String -> Z3 AST
 stringToBv [] = mkIntNum 0 >>= mkInt2bv 8
@@ -44,9 +44,9 @@ stringToBv (c:cs) = do
 
 -- | Defines the convertion from an expression to AST so that Z3 can assert satisfiability
 --   This is used to fold expressions generated by the WLP transformer, so not all valid Java expressions need to be handled
-expAssertAlgebra :: ExpAlgebra (Z3 AST)
+expAssertAlgebra :: ExpAlgebra (TypeEnv -> Z3 AST)
 expAssertAlgebra = (fLit, fClassLit, fThis, fThisClass, fInstanceCreation, fQualInstanceCreation, fArrayCreate, fArrayCreateInit, fFieldAccess, fMethodInv, fArrayAccess, fExpName, fPostIncrement, fPostDecrement, fPreIncrement, fPreDecrement, fPrePlus, fPreMinus, fPreBitCompl, fPreNot, fCast, fBinOp, fInstanceOf, fCond, fAssign, fLambda, fMethodRef) where
-    fLit lit       = case lit of
+    fLit lit _     = case lit of
                         Int n -> mkInteger n
                         Word n -> mkInteger n
                         Float d -> mkRealNum d
@@ -62,127 +62,139 @@ expAssertAlgebra = (fLit, fClassLit, fThis, fThisClass, fInstanceCreation, fQual
     fThisClass = undefined
     fInstanceCreation = undefined
     fQualInstanceCreation = undefined
-    fArrayCreate = undefined
+    fArrayCreate = error "ArrayCreate"
     fArrayCreateInit = undefined
-    fFieldAccess fieldAccess    = case fieldAccess of
+    fFieldAccess fieldAccess _  = case fieldAccess of
                                     PrimaryFieldAccess e id         -> case e of
                                                                         InstanceCreation _ t args _ -> undefined
                                                                         _ -> undefined
                                     SuperFieldAccess id             -> mkStringSymbol (prettyPrint (Name [id])) >>= mkIntVar
                                     ClassFieldAccess (Name name) id -> mkStringSymbol (prettyPrint (Name (name ++ [id]))) >>= mkIntVar
-    fMethodInv invocation       = case invocation of
+    fMethodInv invocation env   = case invocation of
                                     MethodCall (Name [Ident "*length"]) [a, (Lit (Int n))] -> case a of
-                                                                                                    ArrayCreate t exps dim          -> foldExp expAssertAlgebra (if fromEnum n < length exps then (exps !! fromEnum n) else Lit (Int 0))
+                                                                                                    ArrayCreate t exps dim          -> foldExp expAssertAlgebra (if fromEnum n < length exps then (exps !! fromEnum n) else Lit (Int 0)) env
                                                                                                     ArrayCreateInit t dim arrayInit -> mkInteger 0
-                                                                                                    _                               -> error "length of non-array"
+                                                                                                    ExpName name                    -> do
+                                                                                                                                        symbol <- mkStringSymbol ("*length(" ++ prettyPrint name ++ ", " ++ show n ++ ")")
+                                                                                                                                        mkIntVar symbol
+                                                                                                    Cond g a1 a2                    -> foldExp expAssertAlgebra (Cond g (MethodInv (MethodCall (Name [Ident "*length"]) [a1, (Lit (Int n))])) (MethodInv (MethodCall (Name [Ident "*length"]) [a2, (Lit (Int n))]))) env
+                                                                                                    _                               -> error ("length of non-array: " ++ prettyPrint a)
                                     _ -> error (prettyPrint invocation)
-    fArrayAccess arrayIndex     = case arrayIndex of
-                                    ArrayIndex (ArrayCreate t _ _) _ -> foldExp expAssertAlgebra (getInitValue t)
-                                    ArrayIndex (ArrayCreateInit t _ _) _ -> foldExp expAssertAlgebra (getInitValue t)
-                                    ArrayIndex e _ -> foldExp expAssertAlgebra e
-    fExpName name   = do
-                        symbol <- mkStringSymbol (prettyPrint name)
-                        mkIntVar symbol
+    fArrayAccess arrayIndex env = case arrayIndex of
+                                    ArrayIndex (ArrayCreate t _ _) _ -> foldExp expAssertAlgebra (getInitValue t) env
+                                    ArrayIndex (ArrayCreateInit t _ _) _ -> foldExp expAssertAlgebra (getInitValue t) env
+                                    ArrayIndex (ExpName name) i -> do
+                                                                    symbol <- mkStringSymbol (prettyPrint name ++ "[" ++ show i ++ "]")
+                                                                    case fmap arrayContentType (lookup name env) of
+                                                                        Just (PrimType BooleanT)    -> mkBoolVar symbol
+                                                                        Just (PrimType FloatT)      -> mkRealVar symbol
+                                                                        Just (PrimType DoubleT)     -> mkRealVar symbol
+                                                                        _                           -> mkIntVar symbol
+                                    ArrayIndex (Cond g a1 a2) i -> foldExp expAssertAlgebra (Cond g (ArrayAccess (ArrayIndex a1 i)) (ArrayAccess (ArrayIndex a2 i))) env
+                                    ArrayIndex e _ -> foldExp expAssertAlgebra e env
+    fExpName name env            = do
+                                    symbol <- mkStringSymbol (prettyPrint name)
+                                    case lookup name env of
+                                        Just (PrimType BooleanT)    -> mkBoolVar symbol
+                                        Just (PrimType FloatT)      -> mkRealVar symbol
+                                        Just (PrimType DoubleT)     -> mkRealVar symbol
+                                        _                           -> mkIntVar symbol
     fPostIncrement = undefined
     fPostDecrement = undefined
     fPreIncrement = undefined
     fPreDecrement = undefined
-    fPrePlus e = e
-    fPreMinus e = do
-                    ast <- e
-                    zero <- mkInteger 0
-                    mkSub [zero, ast]
+    fPrePlus e env  = e env
+    fPreMinus e env     = do
+                            ast <- e env
+                            zero <- mkInteger 0
+                            mkSub [zero, ast]
     fPreBitCompl = undefined
-    fPreNot e = e >>= mkNot
+    fPreNot e env = e env >>= mkNot
     fCast = undefined
-    fBinOp e1 op e2    = case op of
+    fBinOp e1 op e2 env = case op of
                             Mult -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkMul [ast1, ast2]
                             Div -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkDiv ast1 ast2
                             Rem -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkRem ast1 ast2
                             Add -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkAdd [ast1, ast2]
                             Sub -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkSub [ast1, ast2]
                             LShift -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkBvshl ast1 ast2
                             RShift -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkBvashr ast1 ast2
                             RRShift -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkBvlshr ast1 ast2
                             LThan -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkLt ast1 ast2
                             GThan -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkGt ast1 ast2
                             LThanE -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkLe ast1 ast2
                             GThanE -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkGe ast1 ast2
                             Equal -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkEq ast1 ast2
                             NotEq -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       eq <- mkEq ast1 ast2
                                       mkNot eq
                             And-> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkAnd [ast1, ast2]
                             Or -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkOr [ast1, ast2]
                             Xor -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkXor ast1 ast2
                             CAnd -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkAnd [ast1, ast2]
                             COr -> do
-                                      ast1 <- e1
-                                      ast2 <- e2
+                                      ast1 <- e1 env
+                                      ast2 <- e2 env
                                       mkOr [ast1, ast2]
     fInstanceOf = undefined
-    fCond g e1 e2       = do
-                            astg <- (g >>= mkNot)
-                            assert astg
-                            result <- check
-                            solverReset 
-                            case result of
-                                Sat     -> e2
-                                Unsat   -> e1
-                                _ -> error "can't evaluate if-condition"
+    fCond g e1 e2 env    = do
+                            astg <- g env
+                            ast1 <- e1 env
+                            ast2 <- e2 env
+                            mkIte astg ast1 ast2
     fAssign = undefined
     fLambda = undefined
     fMethodRef = undefined
\ No newline at end of file
diff --git a/WLP.hs b/WLP.hs
index 8ebf692f8dd3900aa3fdbce762c78a0e7dd10add..c84dd05fdc5d4d526b372b263c92ef64e07cc942 100644
--- a/WLP.hs
+++ b/WLP.hs
@@ -34,7 +34,7 @@ type Syn = Exp -> Exp -- The wlp transformer
 --   Statements that pass control to the next statement have to explicitly combine their wlp function with the accumulated function, as some statements (e.g. break) ignore the accumulated function.
 wlpStmtAlgebra :: StmtAlgebra (Inh -> Syn)
 wlpStmtAlgebra = (fStmtBlock, fIfThen, fIfThenElse, fWhile, fBasicFor, fEnhancedFor, fEmpty, fExpStmt, fAssert, fSwitch, fDo, fBreak, fContinue, fReturn, fSynchronized, fThrow, fTry, fLabeled) where
-    fStmtBlock (Block bs) inh       = foldr (\b r -> wlpBlock (inh {acc = r, env = envBlock bs (env inh)}) b) (acc inh) bs -- The result of the last block-statement will be the accumulated transformer for the second-last etc. The type environment is build from the left, so it has to be done seperately.
+    fStmtBlock (Block bs) inh       = foldr (\b r -> wlpBlock inh {acc = r} b) (acc inh) bs -- The result of the last block-statement will be the accumulated transformer for the second-last etc. The type environment is build from the left, so it has to be done seperately.
     fIfThen e s1                    = fIfThenElse e s1 (const id) -- if-then is just an if-then-else with an empty else-block
     fIfThenElse e s1 s2 inh         = let (e', trans) = foldExp wlpExpAlgebra e inh {acc = id}
                                           var = getVar
@@ -60,7 +60,7 @@ wlpStmtAlgebra = (fStmtBlock, fIfThen, fIfThenElse, fWhile, fBasicFor, fEnhanced
     fThrow e inh                    = case catch inh of
                                         Nothing      -> ((\q -> q &* throwException e)) -- acc is ignored, as the rest of the block is not executed
                                         Just (cs, f) -> (maybe (if f then id else (\q -> q &* throwException e)) (flip fStmtBlock (inh {acc = id, catch = Nothing})) (getCatch (decls inh) (env inh) e cs))
-    fTry (Block bs) cs f inh        = let r = (fStmtBlock (Block bs) (inh {acc = id, catch = Just (cs, isJust f)})) in (r . maybe (acc inh) (flip fStmtBlock (inh {env = envBlock bs (env inh)})) f) -- The finally-block is always executed
+    fTry (Block bs) cs f inh        = let r = (fStmtBlock (Block bs) (inh {acc = id, catch = Just (cs, isJust f)})) in (r . maybe (acc inh) (flip fStmtBlock inh) f) -- The finally-block is always executed
     fLabeled _ s                    = s
     
     -- Helper functions
@@ -71,14 +71,6 @@ wlpStmtAlgebra = (fStmtBlock, fIfThen, fIfThenElse, fWhile, fBasicFor, fEnhanced
                         BlockStmt s            -> wlp' inh s
                         LocalClass _           -> (acc inh)
                         LocalVars mods t vars  -> foldr (\v r -> (wlpDeclAssignment t (inh {acc = r}) v)) (acc inh) vars
-                                                        
-    -- Adds declarations within a block to a type environment
-    envBlock :: [BlockStmt] -> TypeEnv -> TypeEnv
-    envBlock bs env = foldl f env bs 
-        where f env (LocalVars mods t vars)                                         = foldr (\v env' -> (varName v, t):env') env vars
-              f env (BlockStmt (BasicFor (Just (ForLocalVars mods t vars)) _ _ s))  = foldr (\v env' -> (varName v, t):env') env vars
-              f env _                                                               = env
-              varName (VarDecl (VarId id) _) = Name [id]
                 
     -- wlp of a var declaration that also assigns a value. Declaring without assignment assigns the default value
     wlpDeclAssignment :: Type -> Inh -> VarDecl -> Exp -> Exp
@@ -149,7 +141,7 @@ wlpExpAlgebra :: ExpAlgebra (Inh -> (Exp, Syn))
 wlpExpAlgebra = (fLit, fClassLit, fThis, fThisClass, fInstanceCreation, fQualInstanceCreation, fArrayCreate, fArrayCreateInit, fFieldAccess, fMethodInv, fArrayAccess, fExpName, fPostIncrement, fPostDecrement, fPreIncrement, fPreDecrement, fPrePlus, fPreMinus, fPreBitCompl, fPreNot, fCast, fBinOp, fInstanceOf, fCond, fAssign, fLambda, fMethodRef) where
     fLit lit inh                                        = (Lit lit, (acc inh))
     fClassLit mType inh                                 = (ClassLit mType, (acc inh))
-    fThis inh                                           = (fromJust' "fThis" (object inh), (acc inh))
+    fThis inh                                           = (fromJust' "fThis" (object inh), acc inh)
     fThisClass name inh                                 = (ThisClass name, (acc inh))
     fInstanceCreation typeArgs t args mBody inh         = case args of
                                                             [ExpName (Name [Ident "#"])]    -> (InstanceCreation typeArgs t args mBody, acc inh) -- '#' indicates we already called the constructor method using the correct arguments
@@ -161,7 +153,7 @@ wlpExpAlgebra = (fLit, fClassLit, fThis, fThisClass, fInstanceCreation, fQualIns
     fQualInstanceCreation e typeArgs t args mBody inh   = error "fQualInstanceCreation"
     fArrayCreate t dimLengths dim inh                   = (ArrayCreate t (map (\e -> fst (e inh)) dimLengths) dim, acc inh)
     fArrayCreateInit t dim init inh                     = error "ArrayCreateInit" -- (ArrayCreateInit t dim init, acc inh)
-    fFieldAccess fieldAccess inh                        = (ExpName (foldFieldAccess inh fieldAccess), (acc inh))
+    fFieldAccess fieldAccess inh                        = (foldFieldAccess inh fieldAccess, (acc inh))
     fMethodInv invocation inh                           = case invocation of
                                                             MethodCall (Name [Ident "*assume"]) [e] -> (false, (if e == false then const true else imp e)) -- *assume is the regular assume function
                                                             _   -> if getCallCount (calls inh) (invocationToId invocation) >= nrOfUnroll  -- Check the recursion depth
@@ -276,20 +268,23 @@ wlpExpAlgebra = (fLit, fClassLit, fThis, fThisClass, fInstanceCreation, fQualIns
     foldLhs inh lhs  = case lhs of
                             FieldLhs (PrimaryFieldAccess e id)  -> case foldExp wlpExpAlgebra e inh of
                                                                     (ExpName name, trans)   -> (NameLhs (Name (fromName name ++ [id])), trans)
-                                                                    _                       -> error "foldFieldAccess"
+                                                                    _                       -> error "foldLhs"
                             ArrayLhs (ArrayIndex a i)           ->  let (a', aTrans) = foldExp wlpExpAlgebra a inh
                                                                         i' = map (\x -> foldExp wlpExpAlgebra x inh) i
                                                                     in (ArrayLhs (ArrayIndex a' (map fst i')), foldl (\trans (_, iTrans) -> trans . iTrans) aTrans i' . arrayAccessWlp a' (map fst i') inh)
                             lhs'                                -> (lhs', id)
     
-    -- Folds the expression part of a fieldaccess and simplifies it to a name
-    foldFieldAccess :: Inh -> FieldAccess -> Name
+    -- Folds the expression part of a fieldaccess and simplifies it
+    foldFieldAccess :: Inh -> FieldAccess -> Exp
     foldFieldAccess inh fieldAccess  = case fieldAccess of
                                             PrimaryFieldAccess e id     -> case fst (foldExp wlpExpAlgebra e inh) of
-                                                                                ExpName name    -> Name (fromName name ++ [id])
-                                                                                x               -> error ("foldFieldAccess: " ++ show x ++ show id)
+                                                                                ExpName name    -> ExpName (Name (fromName name ++ [id]))
+                                                                                ArrayAccess (ArrayIndex a i) -> let (a', aTrans) = foldExp wlpExpAlgebra a inh
+                                                                                                                    i' = map (\x -> foldExp wlpExpAlgebra x inh) i
+                                                                                                                in MethodInv (MethodCall (Name [Ident "*length"]) [a, (Lit (Int (toEnum (length i'))))])
+                                                                                x               -> error ("foldFieldAccess: " ++ show x ++ " . " ++ show id)
                                             SuperFieldAccess id         -> foldFieldAccess inh (PrimaryFieldAccess (fromJust' "foldFieldAccess" (object inh)) id)
-                                            ClassFieldAccess name id    -> Name (fromName name ++ [id])
+                                            ClassFieldAccess name id    -> ExpName (Name (fromName name ++ [id]))
     
     
 -- Simplified version of substVar, handy to use with introduced variables
@@ -302,7 +297,7 @@ wlp decls = wlpWithEnv decls []
 
 -- | wlp with a given type environment
 wlpWithEnv :: [TypeDecl] -> TypeEnv -> Stmt -> Exp -> Exp
-wlpWithEnv decls env = wlp' (Inh id id Nothing env decls [] Nothing Nothing)
+wlpWithEnv decls env = wlp' (Inh id id Nothing env decls [] Nothing (Just (ExpName (Name [Ident "#obj"]))))
 
 -- wlp' lets you specify the inherited attributes
 wlp' :: Inh -> Stmt -> Syn