diff --git a/QUESTIONS b/QUESTIONS
deleted file mode 100644
index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000
--- a/QUESTIONS
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/optimize.py b/src/optimize.py
index bba4775bedaacbc05aa7d114195654d7d2849270..88ed60e5299c459785fed36896b77fdbc54250e6 100644
--- a/src/optimize.py
+++ b/src/optimize.py
@@ -7,6 +7,45 @@ def optimize_global(statements):
     """Optimize statement sequences on a global level."""
     old_len = -1
 
+    while old_len != len(statements):
+        old_len = len(statements)
+
+        while not statements.end():
+            s = statements.read()
+
+            #     beq/bne ..., $Lx      ->      bne/beq ..., $Ly
+            #     j $Ly                     $Lx:
+            # $Lx:
+            if s.is_command('beq') or s.is_command('bne'):
+                following = statements.peek(2)
+
+                if len(following) == 2:
+                    j, label = following
+
+                    if j.is_command('j') and label.is_label(s[2]):
+                        if s.is_command('beq'):
+                            s.name = 'bne'
+                        else:
+                            s.name = 'beq'
+                        s[2] = j[0]
+                        statements.replace(3, [s, label])
+
+
+def optimize_blocks(blocks):
+    """Call the optimizer for each basic block. Do this several times until
+    no more optimizations are achieved."""
+    optimized = []
+    
+    for block in blocks:
+        optimize_block(block)
+    
+    return blocks
+
+
+def optimize_block(statements):
+    """Optimize a basic block."""
+    old_len = -1
+
     while old_len != len(statements):
         old_len = len(statements)
 
@@ -67,57 +106,15 @@ def optimize_global(statements):
                     lw[-1] = str(s[2]) + lw[-1][1:]
                     statements.replace(2, [lw])
                     continue
+                        
+            #   move $RegA, $RegB   ->  move $RegA, $RegB
+            #   move $RegB, $RegA
+            if s.is_command('move'):
+                move = statements.peek()
 
-            #     beq/bne ..., $Lx      ->      bne/beq ..., $Ly
-            #     j $Ly                     $Lx:
-            # $Lx:
-            if s.is_command('beq') or s.is_command('bne'):
-                following = statements.peek(2)
-
-                if len(following) == 2:
-                    j, label = following
-
-                    if j.is_command('j') and label.is_label(s[2]):
-                        if s.is_command('beq'):
-                            s.name = 'bne'
-                        else:
-                            s.name = 'beq'
-                        s[2] = j[0]
-                        statements.replace(3, [s, label])
-
-
-def optimize_blocks(blocks):
-    """Call the optimizer for each basic block. Do this several times until
-    no more optimizations are achieved."""
-    changed = True
-
-    while changed:
-        changed = False
-        optimized = []
-
-        for block in blocks:
-            block_changed, b = optimize_block(block)
-            optimized.append(b)
-
-            if block_changed:
-                changed = True
-
-        blocks = optimized
-
-    return reduce(lambda a, b: a + b, blocks, [])
-
-
-def optimize_block(statements):
-    """Optimize a basic block."""
-    changed = False
-    output_statements = []
-
-    for statement in statements:
-        new_statement = statement
-
-        output_statements.append(new_statement)
-
-    return changed, output_statements
+                if move.is_command('move') and move[0] == s[1] and \
+                        move[1] == s[0]:
+                    statements.replace(2, [s])
 
 
 def optimize(statements, verbose=0):
@@ -130,8 +127,7 @@ def optimize(statements, verbose=0):
 
     # Optimize basic blocks
     basic_blocks = find_basic_blocks(statements)
-#    blocks = optimize_blocks(basic_blocks)
-    blocks = basic_blocks
+    blocks = optimize_blocks(basic_blocks)
     block_statements = map(lambda b: b.statements, blocks)
     opt_blocks = reduce(lambda a, b: a + b, block_statements)
     b = len(opt_blocks)
@@ -147,7 +143,7 @@ def optimize(statements, verbose=0):
         print 'Original statements:             %d' % o
         print 'After global optimization:       %d' % g
         print 'After basic blocks optimization: %d' % b
-        print 'Speedup:                         %d (%d%%)' \
-                % (b - o, int((b - o) / o * 100))
+        print 'Optimization:                    %d (%d%%)' \
+                % (b - o, int((b - o) / float(o) * 100))
 
     return opt_blocks
diff --git a/src/statement.py b/src/statement.py
index db0ce023697a5ed447252500af3fade051704a0d..87dea3ea134e9af73bab1151f570d0399e111575 100644
--- a/src/statement.py
+++ b/src/statement.py
@@ -118,7 +118,10 @@ class Block:
 
     def peek(self, count=1):
         """Read the statements until an offset from the current pointer
-        position."""
+        position."""      
+        if self.end():
+            return Statement('empty', '') if count == 1 else []
+              
         return self.statements[self.pointer] if count == 1 \
                else self.statements[self.pointer:self.pointer + count]
 
diff --git a/tests/test_optimize.py b/tests/test_optimize.py
index 93000e1e97f9502c3909fb11021ebc08dbf5dacf..b3025ebf7aecfc2888602cb6c2f331c5fce03adc 100644
--- a/tests/test_optimize.py
+++ b/tests/test_optimize.py
@@ -1,6 +1,6 @@
 import unittest
 
-from src.optimize import optimize_global
+from src.optimize import optimize_global, optimize_block, optimize_blocks
 from src.statement import Statement as S, Block as B
 
 
@@ -9,26 +9,26 @@ class TestOptimize(unittest.TestCase):
     def setUp(self):
         pass
 
-    def test_optimize_global_movaa(self):
+    def test_optimize_block_movaa(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         block = B([foo,
                    S('command', 'move', '$regA', '$regA'),
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         self.assertEquals(block.statements, [foo, bar])
         
-    def test_optimize_global_movab(self):
+    def test_optimize_block_movab(self):
         foo = S('command', 'foo')
         move = S('command', 'move', '$regA', '$regB')
         bar = S('command', 'bar')
         block = B([foo,
                    move,
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         self.assertEquals(block.statements, [foo, move, bar])
         
-    def test_optimize_global_movinst_true(self):
+    def test_optimize_block_movinst_true(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -36,12 +36,12 @@ class TestOptimize(unittest.TestCase):
                    S('command', 'move', '$regA', '$regB'),
                    S('command', 'addu', '$regA', '$regA', 2),
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         self.assertEquals(block.statements, [foo,                     
                    S('command', 'addu', '$regA', '$regB', 2),      
                    bar])
                    
-    def test_optimize_global_movinst_false(self):
+    def test_optimize_block_movinst_false(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         statements = [foo, \
@@ -50,10 +50,10 @@ class TestOptimize(unittest.TestCase):
                       bar]
         
         block = B(statements)
-        optimize_global(block)
+        optimize_block(block)
         self.assertEquals(block.statements, statements)
                 
-    def test_optimize_global_instr_mov_jal_true(self):
+    def test_optimize_block_instr_mov_jal_true(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -62,14 +62,14 @@ class TestOptimize(unittest.TestCase):
                    S('command', 'move', '$4', '$regA'),
                    S('command', 'jal', 'L1'),
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, [foo,                     
                    S('command', 'addu', '$4', '$regC', 2),
                    S('command', 'jal', 'L1'),      
                    bar])
         
-    def test_optimize_global_instr_mov_jal_false(self):
+    def test_optimize_block_instr_mov_jal_false(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -79,11 +79,11 @@ class TestOptimize(unittest.TestCase):
                       S('command', 'jal', 'L1'), \
                       bar]
         block = B(arguments)
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, arguments)
         
-    def test_optimize_global_sw_ld_true(self):
+    def test_optimize_block_sw_ld_true(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -91,13 +91,13 @@ class TestOptimize(unittest.TestCase):
                    S('command', 'sw', '$regA', '$regB'),
                    S('command', 'ld', '$regA', '$regC'),
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, [foo,
                    S('command', 'sw', '$regA', '$regB'),
                    bar])
                    
-    def test_optimize_global_sw_ld_false(self):
+    def test_optimize_block_sw_ld_false(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -106,23 +106,23 @@ class TestOptimize(unittest.TestCase):
                      S('command', 'ld', '$regD', '$regC'), \
                      bar]
         block = B(arguments)
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, arguments)
 
-    def test_optimize_global_shift_true(self):
+    def test_optimize_block_shift_true(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
         block = B([foo,
                    S('command', 'sll', '$regA', '$regA', 0),
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, [foo,
                    bar])
                    
-    def test_optimize_global_shift_false(self):
+    def test_optimize_block_shift_false(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -130,7 +130,7 @@ class TestOptimize(unittest.TestCase):
                      S('command', 'sll', '$regA', '$regB', 0), \
                      bar]
         block = B(arguments)
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, arguments)
         
@@ -138,11 +138,11 @@ class TestOptimize(unittest.TestCase):
                      S('command', 'sll', '$regA', '$regA', 1), \
                      bar]
         block2 = B(arguments2)
-        optimize_global(block2)
+        optimize_block(block2)
         
         self.assertEquals(block2.statements, arguments2)
     
-    def test_optimize_global_add_lw_true(self):
+    def test_optimize_block_add_lw_true(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -150,13 +150,13 @@ class TestOptimize(unittest.TestCase):
                    S('command', 'add', '$regA', '$regA', 10),
                    S('command', 'lw', '$regB', '0($regA)'),
                    bar])
-        optimize_global(block)
+        optimize_block(block)
         
         self.assertEquals(block.statements, [foo,
                    S('command', 'lw', '$regB', '10($regA)'),
                    bar])
                    
-    def test_optimize_global_add_lw_false(self):
+    def test_optimize_block_add_lw_false(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
         
@@ -165,7 +165,7 @@ class TestOptimize(unittest.TestCase):
                      S('command', 'lw', '$regB', '0($regC)'), \
                      bar]
         block = B(arguments)
-        optimize_global(block)
+        optimize_block(block)
         
         arguments2 = [foo, \
                      S('command', 'add', '$regA', '$regB', 10), \
@@ -178,7 +178,7 @@ class TestOptimize(unittest.TestCase):
                      S('command', 'lw', '$regB', '1($regA)'), \
                      bar]
         block3 = B(arguments3)
-        optimize_global(block3)
+        optimize_block(block3)
         
         self.assertEquals(block.statements, arguments)
         self.assertEquals(block2.statements, arguments2)
@@ -243,3 +243,42 @@ class TestOptimize(unittest.TestCase):
         optimize_global(block)
         
         self.assertEquals(block.statements, arguments)
+        
+    def test_optimize_block_move_move_true(self):
+        foo = S('command', 'foo')
+        bar = S('command', 'bar')
+        
+        block = B([foo,
+                   S('command', 'move', '$regA', '$regB'),
+                   S('command', 'move', '$regB', '$regA'),
+                   bar])
+        optimize_block(block)
+        
+        self.assertEquals(block.statements, [foo,
+                   S('command', 'move', '$regA', '$regB'),
+                   bar])
+                   
+    def test_optimize_block_mov_mov_false(self):
+        foo = S('command', 'foo')
+        bar = S('command', 'bar')
+        
+        arguments = [foo, \
+                     S('command', 'move', '$regA', '$regB'), \
+                     S('command', 'move', '$regB', '$regC'), \
+                     bar]
+        block = B(arguments)
+        optimize_block(block)
+        
+        self.assertEquals(block.statements, arguments)
+        
+    def test_optimize_blocks(self):
+        foo = S('command', 'foo')
+        bar = S('command', 'bar')
+        
+        block1 = B([foo, bar])
+        block2 = B([bar, foo])
+        blocks_in = [block1, block2];
+        
+        blocks_out = optimize_blocks(blocks_in)
+        
+        self.assertEquals(blocks_in, blocks_out)