diff --git a/bin/parse.kat b/bin/parse.kat
index ce457d3329f6e06cf7bc397be6d384af30225c15..235dd32b622715b527b0bf7a0977149d7fb4225e 100644
--- a/bin/parse.kat
+++ b/bin/parse.kat
@@ -4,7 +4,7 @@ m m1 0.5 0.5 0 n2 n3
 s s2 10 1 n3 n4
 m m2 0.5 0.5 0 n4 dump
 
-pd PD1 n
+pd PD1 n2
 
 xaxis m1 phi lin 0 360 1000
 
diff --git a/bin/test_aperture.py b/bin/test_aperture.py
new file mode 100644
index 0000000000000000000000000000000000000000..a272bd815dc874fd8f9e5d68ff683a3003aacc1a
--- /dev/null
+++ b/bin/test_aperture.py
@@ -0,0 +1,33 @@
+from pykat import finesse
+from pykat.commands import xaxis
+import pylab as pl
+import numpy as np
+
+code = """
+l l1 1 0 0 n1
+s s1 10 1 n1 n2
+m m1 1 0 0 n2 dump
+
+gauss g1 m1 n2 1e-3 0
+
+pd refl n2
+
+xaxis m1 r_ap lin 0.1e-3 2e-3 10
+"""
+
+kat = finesse.kat(kat_code = code)
+
+maxtem = np.arange(0, 3, 2)
+
+for tem in maxtem:
+    print "Calculating maxtem ",tem,"..."
+    kat.maxtem = tem
+    r = kat.run()
+    pl.plot(r.x/1e-3, r.y, label="maxtem={0}".format(tem))
+
+    
+pl.ylabel("Reflected Power [W]")
+pl.xlabel("Mirror aperture [mm]")
+pl.legend()
+pl.show()
+    
\ No newline at end of file
diff --git a/bin/test_parser.py b/bin/test_parser.py
index e7cd4acf397dfabb5dcba19bf6309b5d20416f19..d1485db317b90fee55c6b65c40a4513f0096a113 100644
--- a/bin/test_parser.py
+++ b/bin/test_parser.py
@@ -1,19 +1,23 @@
-import sys
-sys.path.append(".")
-
-from pykat import finesse, profiling
-import numpy as np
+from pykat import finesse
+from pykat.commands import xaxis
 import pylab as pl
 
-kat = finesse.kat()
-#kat.load("D:\\finesse\\test\\kat_test\\physics\\mirror_astig_tilt_all_BH.kat")
-kat.load('parse.kat')
-kat.getPerformanceData = True
+code = """
+l l1 1 0 0 n1
+s s1 10 1 n1 n2
+m m1 0.5 0.5 0 n2 n3
+s s2 10 1 n3 n4
+m m2 0.5 0.5 0 n4 dump
+
+ad ad1 0 n2
+"""
+
+kat = finesse.kat(kat_code = code)
 
-[run, perfdata] = kat.run(printout=0,printerr=0)
+kat.add(xaxis("lin", [0, 360], kat.m2, kat.m2.phi, 1000))
 
-l,t,fig = profiling.plotReducedPerformanceData(perfdata)
+r = kat.run(printerr=1)
 
-fig.savefig("Timing.png",pad_inches=0.1, bbox_inches='tight')
-fig.show()
+pl.plot(r.x, r.y)
+pl.show()
     
\ No newline at end of file
diff --git a/bin/test_plot.py b/bin/test_plot.py
index fa1ad52d0ee3d0299985746c77b2f68730e981f0..efb42c6be9b0b61a9c1534da0f3d4cd41a3111b8 100644
--- a/bin/test_plot.py
+++ b/bin/test_plot.py
@@ -1,62 +1,43 @@
-import sys
-sys.path.append("../")
-
 from pykat import finesse
 from pykat.detectors import *
 from pykat.components import *
 from pykat.commands import *
 from pykat.structs import *
-#from pykat.plotting import *
+
 import numpy as np
 import pylab as pl
 
-kat = finesse.kat()
+code = """
+l l1 1 0 0 n1
+s s1 10 1 n1 n2
+m m1 0.5 0.5 0 n2 n3
+s s2 10 1 n3 n4
+m m2 0.5 0.5 0 n4 n5
+s s3 10 1 n5 n6
+"""
+
+kat = finesse.kat(kat_code=code)
 
-laser(kat,'l1','n1',1)
-space(kat,'s1','n1','n2',1)
+kat.add(cavity('cav1','m1','n3','m2','n4'))
 
-mirror(kat,'m1','n2','n3',R=0.8,T=0.2)
-space(kat,'s2','n3','n4',L=1)
-mirror(kat,'m2','n4','n5',R=0.7,T=0.3)
-cavity(kat, 'cav1','m1','n3','m2','n4')
-space(kat,'s3','n5','n6',L=1)
+kat.add(photodiode('pd_cav','n4'))
+kat.add(photodiode('pd_ref','n2'))
+kat.add(photodiode('pd_trs','n5'))
 
-photodiode(kat,'pd_cav','n4')
-photodiode(kat,'pd_ref','n2')
-photodiode(kat,'pd_trs','n5')
+kat.add(xaxis(Scale.linear, [0, 360], kat.m2, kat.m2.phi, 100))
 
 kat.m1.Rcx = -1000.0
 kat.m1.Rcy = -1000.0
 kat.m2.Rcx =  1000.0
 kat.m2.Rcy =  1000.0
 
-xaxis(kat, Scale.linear, [0,360], kat.m2, kat.m2.phi, 1000)
-
 kat.maxtem = 0
 
 run = kat.run(printout=0,printerr=0)
 
-#pl.figure()
-#pl.ion()
-#pl.plot(run.x,run.y)
-#pl.xlabel(run.xlabel)
-#pl.ylabel("Intensity [W]")
-#pl.legend(run.ylabels)
-#pl.show()
-
-kat.m1.R = 0.5
-kat.m1.T = 0.5
-kat.pd_cav.enabled = False
-
-run = kat.run(printout=0,printerr=0)
-
-#pl.figure()
-#pl.plot(run.x,run.y)
-#pl.xlabel(run.xlabel)
-#pl.ylabel("Intensity [W]")
-#pl.legend(run.ylabels)
-#pl.show()
-
-kat.openGUI()
-
-
+pl.figure()
+pl.plot(run.x,run.y)
+pl.xlabel(run.xlabel)
+pl.ylabel("Intensity [W]")
+pl.legend(run.ylabels)
+pl.show()
diff --git a/pykat/__init__.py b/pykat/__init__.py
index a82b23d19a0120d599d8bddd79807d0dfdd07bc6..e6044ce72abfc1f06a5754e6343210a96ba7efd7 100644
--- a/pykat/__init__.py
+++ b/pykat/__init__.py
@@ -1 +1,5 @@
-__all__ = ['finesse', 'components', 'detectors', 'commands']
+#__all__ = ['finesse', 'components', 'detectors', 'commands']
+import finesse
+import components
+import detectors
+import commands
diff --git a/pykat/commands.py b/pykat/commands.py
index 70f949cbd0cb022ef39d1a762a78d05d2b9e0bb5..bf37eacd1e5dad5a1bbcd192928556916254b078 100644
--- a/pykat/commands.py
+++ b/pykat/commands.py
@@ -14,25 +14,28 @@ class Command(object):
     def getFinesseText(self):
         """ Base class for individual finesse optical components """    
         raise NotImplementedError("This function is not implemented")
+    
+    def _on_kat_add(self, kat):
+        """
+        Called when this component has been added to a kat object
+        """
+        self._kat = kat
         
 class cavity(Command):
-    def __init__(self, kat, name, c1, n1, c2, n2):
+    def __init__(self, name, c1, n1, c2, n2):
         self.__name = name
         self.__c1 = c1
         self.__c2 = c2
         self.__n1 = n1
         self.__n2 = n2
-    
-        kat.add(self)
         
     def getFinesseText(self):
-        return 'cav {0} {1} {2} {3} {4}'.format(
-                self.__name, self.__c1, self.__n1, self.__c2, self.__n2);
+        return 'cav {0} {1} {2} {3} {4}'.format(self.__name, self.__c1, self.__n1, self.__c2, self.__n2);
     
     
 class xaxis(Command):
     
-    def __init__(self, kat, scale, limits, comp, param, steps):
+    def __init__(self, scale, limits, comp, param, steps):
         
         if scale == "lin":
             scale = Scale.linear
@@ -57,22 +60,28 @@ class xaxis(Command):
             
         self.steps = steps
         
-        if not isinstance(comp, Component):
-            raise exceptions.ValueError("comp is not a Component")
-            
-        self.__comp = comp
+        # if entered component is a string then just store and use that
+        if isinstance(comp, str):
+            self.__comp = comp
+        elif not isinstance(comp, Component):
+            raise exceptions.ValueError("{0} has not been added".format(comp))
+        else:
+            self.__comp = comp
         
-        if not isinstance(param, Param) :
+        if isinstance(param, str):
+            self.__param = param
+        elif not isinstance(param, Param) :
             raise exceptions.ValueError("param argument is not of type Param")
-                
-        self._param = param
-        
-        kat.add(self)
+        else:
+            self.__param = param
         
     def getFinesseText(self):
+        # store either the component name of the string provided
+        comp_name = self.__comp.name if isinstance(self.__comp, Component) else self.__comp
+        param_name = self.__param.name if isinstance(self.__param, Param) else self.__param
         
         return 'xaxis {0} {1} {2} {3} {4} {5}'.format(
-                self.__comp.name, self._param.name, self.scale,
+                comp_name, param_name, self.scale,
                 min(self.limits), max(self.limits), self.steps);
                 
         
\ No newline at end of file
diff --git a/pykat/components.py b/pykat/components.py
index c900875c2fdb729fe4e9dc42cad1d112f63cd5b9..3f0dd9fe177ba5c717b991b52bb2bb3c9fc140b2 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -7,24 +7,37 @@ Created on Mon Jan 28 11:10:01 2013
 import exceptions
 import pykat.gui.resources
 import pykat
-import inspect
 import pykat.gui.graphics
-from pykat.gui.graphics import *
+#from pykat.gui.graphics import *
 from pykat.node_network import *
-from PyQt4.QtGui import *
-from PyQt4.Qt import *
+#from PyQt4.QtGui import *
+#from PyQt4.Qt import *
 
 class Component(object) :
-    def __init__(self, name, kat):
+    def __init__(self, name):
         self.__name = name
         self._svgItem = None
         self.__nodes = []
-        self._kat = kat
+        self._requested_node_names = []
+        self._kat = None
         
-        if not isinstance(kat,pykat.finesse.kat):
-            raise exceptions.ValueError("kat argument is not a pykat.finesse.kat object")
+        #if not isinstance(kat,pykat.finesse.kat):
+        #    raise exceptions.ValueError("kat argument is not a pykat.finesse.kat object")
             
-        kat.add(self)
+        #kat.add(self)
+    
+    def _on_kat_add(self, kat):
+        """
+        Called when this component has been added to a kat object
+        """
+        self._kat = kat
+        
+        for node_name in self._requested_node_names:
+            self._addNode(node_name)
+        
+    @staticmethod
+    def parseFinesseText(text):    
+        raise NotImplementedError("This function is not implemented")
         
     def getFinesseText(self):
         """ Base class for individual finesse optical components """    
@@ -67,12 +80,12 @@ class Param(float):
     name = property(lambda self: self.__name)
            
 class mirror(Component):
-    def __init__(self,kat,name,node1,node2,R=0,T=0,phi=0,Rcx=0,Rcy=0,xbeta=0,ybeta=0):
+    def __init__(self,name,node1,node2,R=0,T=0,phi=0,Rcx=0,Rcy=0,xbeta=0,ybeta=0):
         
-        Component.__init__(self,name,kat)
+        Component.__init__(self,name)
         
-        self.node1 = self._addNode(node1)
-        self.node2 = self._addNode(node2)
+        self._requested_node_names.append(node1)
+        self._requested_node_names.append(node2)
         
         self.__R = R
         self.__T = T
@@ -128,12 +141,31 @@ class mirror(Component):
     def Rc(self,value):
         self.Rcx = value
         self.Rcy = value
+    
+    @staticmethod
+    def parseFinesseText(text):
+        values = text.split(" ")
+
+        if values[0] != "m":
+            raise exceptions.RuntimeError("'{0}' not a valid Finesse mirror command".format(text))
+
+        values.pop(0) # remove initial value
+        
+        if len(values) != 6:
+            raise exceptions.RuntimeError("Mirror Finesse code format incorrect '{0}'".format(text))
+
+        return mirror(values[0], values[4], values[5], R=values[1], T=values[2], phi=values[3])
         
     def getFinesseText(self):        
         rtn = []
+        nodes = self.getNodes()
+        
+        if len(nodes) != 2:
+            raise exceptions.RuntimeError("Not enough nodes for mirror")
+            
         rtn.append('m {0} {1} {2} {3} {4} {5}'.format(
                 self.name, self.__R, self.__T, self.__phi,
-                self.node1.name, self.node2.name))
+                nodes[0].name, nodes[1].name))
             
         if self.Rcx != 0: rtn.append("attr {0} Rcx {1}".format(self.name,self.__Rcx))
         if self.Rcy != 0: rtn.append("attr {0} Rcy {1}".format(self.name,self.__Rcy))
@@ -144,17 +176,18 @@ class mirror(Component):
         
     def getQGraphicsItem(self):
         if self._svgItem == None:
+            nodes = self.getNodes()
             self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/mirror_flat.svg",self
-                                                ,[(-4,15,self.node1),(14,15,self.node2)])
+                                                ,[(-4,15,self.nodes[0]),(14,15,self.nodes[1])])
         return self._svgItem
    
    
 class space(Component):
-    def __init__(self,kat , name, node1, node2, L=0, n=1):
-        Component.__init__(self,name,kat)
+    def __init__(self, name, node1, node2, L=0, n=1):
+        Component.__init__(self,name,)
         
-        self.node1 = self._addNode(node1)
-        self.node2 = self._addNode(node2)
+        self._requested_node_names.append(node1)
+        self._requested_node_names.append(node2)
         
         self.__L = L
         self.__n = n
@@ -169,11 +202,29 @@ class space(Component):
     @n.setter
     def n(self,value): self.__n = value
     
+    @staticmethod
+    def parseFinesseText(text):
+        values = text.split(" ")
+
+        if values[0] != "s":
+            raise exceptions.RuntimeError("'{0}' not a valid Finesse space command".format(text))
+
+        values.pop(0) # remove initial value
+        
+        if len(values) == 5:
+            return space(values[0],values[3],values[4],L=values[1],n=values[2])
+        elif len(values) == 4:
+            return space(values[0],values[2],values[3],L=values[1])
+        else:
+            raise exceptions.RuntimeError("Space Finesse code format incorrect '{0}'".format(text))
+        
     def getFinesseText(self):
+        nodes = self.getNodes()
+        
         if self.__n == 1:
-            return 's {0} {1} {2} {3}'.format(self.name, self.__L, self.node1.name, self.node2.name)            
+            return 's {0} {1} {2} {3}'.format(self.name, self.__L, nodes[0].name, nodes[1].name)            
         else:
-            return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, self.node1.name, self.node2.name)            
+            return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, nodes[0].name, nodes[1].name)            
        
     def getQGraphicsItem(self):
         if self._QItem == None:
@@ -197,10 +248,10 @@ class space(Component):
 
     
 class laser(Component):
-    def __init__(self,kat,name,node,P=1,f_offset=0,phase=0):
-        Component.__init__(self,name,kat)
-                
-        self.node = self._addNode(node)
+    def __init__(self,name,node,P=1,f_offset=0,phase=0):
+        Component.__init__(self,name)
+        
+        self._requested_node_names.append(node)
         
         self.__power = P
         self.__f_offset = f_offset
@@ -221,16 +272,31 @@ class laser(Component):
     @phase.setter
     def phase(self,value): self.__phase = value
     
+    @staticmethod
+    def parseFinesseText(text):
+        values = text.split(" ")
+
+        if values[0] != "l":
+            raise exceptions.RuntimeError("'{0}' not a valid Finesse laser command".format(text))
+
+        values.pop(0) # remove initial value
+        
+        if len(values) == 5:
+            return laser(values[0],values[4],P=values[1],f_offset=values[2],phase=values[3])
+        elif len(values) == 4:
+            return laser(values[0],values[3],P=values[1],f_offset=values[2], phase=0)
+        else:
+            raise exceptions.RuntimeError("Laser Finesse code format incorrect '{0}'".format(text))
+    
     def getFinesseText(self):
-        if self.__phase == 0 :
-            return 'l {0} {1} {2} {3}'.format(self.name, self.__power, self.__f_offset, self.node.name)            
-        else :
-            return 'l {0} {1} {2} {4} {3}'.format(self.name, self.__power, self.__f_offset, self.__phase, self.node.name)            
+        nodes = self.getNodes()
+        
+        return 'l {0} {1} {2} {3} {4}'.format(self.name, self.__power, self.__f_offset, self.__phase, nodes[0].name)            
          
     def getQGraphicsItem(self):
         if self._svgItem == None:
             self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/laser.svg",
-                                                   self,[(65,25,self.node)])
+                                                   self,[(65,25,nodes[0])])
             
         return self._svgItem
             
diff --git a/pykat/detectors.py b/pykat/detectors.py
index 04747fcca963dee7b836cc10a27422db1879ab43..dadcc9a7226737fafe793d8b4eebb8842a16f690 100644
--- a/pykat/detectors.py
+++ b/pykat/detectors.py
@@ -13,17 +13,26 @@ from pykat.gui.graphics import *
 from pykat.node_network import *
 
 class Detector(object) :
-    def __init__(self, name,node,kat):
+    def __init__(self, name,node):
         self.__name = name
         self._svgItem = None
-        self._kat = kat
+        self._kat = None
         self.noplot = False
         self.enabled = True
         
-        kat.add(self)
+        if node.find('*'):
+            self._alternate_beam = True
+            node.replace('*','')
         
-        self.__node = kat.nodes.createNode(node)
-        self.__node.connect(self)
+        self.__requested_node = node
+
+    def _on_kat_add(self, kat):
+        self._node = kat.nodes.createNode(self.__requested_node)
+        #self.__node.connect(self)
+    
+    @staticmethod
+    def parseFinesseText(text):    
+        raise NotImplementedError("This function is not implemented")
         
     def getFinesseText(self):
         """ Base class for individual finesse optical components """    
@@ -41,24 +50,18 @@ class Detector(object) :
     name = property(__getname)
 
 class photodiode(Detector):
-    def __init__(self,kat,name,node) :
-        Detector.__init__(self,name,node,kat)
+    @staticmethod
+    def parseFinesseText(text):    
+        raise NotImplementedError("This function is not implemented")   
         
-        if node.find('*'):
-            self._alternate_beam = True
-            node.replace('*','')
-            
-        self.__node = kat.nodes.createNode(node)
-                    
-                
     def getFinesseText(self) :
         if self.enabled:    
             rtn = []
             
             if self._alternate_beam:
-                rtn.append("pd {0} {1}".format(self.name, self.__node.name))
+                rtn.append("pd {0} {1}".format(self.name, self._node.name))
             else:
-                rtn.append("pd {0} {1}*".format(self.name, self.__node.name))
+                rtn.append("pd {0} {1}*".format(self.name, self._node.name))
             
             if self.noplot:
                 rtn.append("noplot {0}".format(self.name))
diff --git a/pykat/finesse.py b/pykat/finesse.py
index 80539b13626c33a0e85f17a0eafd6c6acf3e8788..f44d3657b3ae5481259c3e3061d8ff82503b0275 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -31,6 +31,7 @@ import tempfile
 import numpy as np
 import datetime
 import pickle
+import pykat
 
 from pykat.node_network import NodeNetwork
 from pykat.detectors import Detector
@@ -48,7 +49,14 @@ class MissingFinesse(Exception) :
                "or you do not have the permissions to run it." \
                .format(os.environ.get('FINESSE_DIR'))
     
-
+class FinesseError(Exception) :
+    def __init__(self, err, kat):
+        self.__err = err
+        self.__kat = kat
+        
+    def __str__(self):
+        return "Finesse returned an error running {1}: {0}".format(self.__err, self.__kat)
+        
 class katRun(object):
     def __init__(self):
         self.runDateTime = datetime.datetime.now()
@@ -75,7 +83,7 @@ class katRun(object):
         
 class kat(object):                    
         
-    def __init__(self, katexe=""):
+    def __init__(self, kat_file=None, kat_code=None, katexe=""):
         
         self.scene = None # scene object for GUI
         self.__components = {}  # dictionary of optical components      
@@ -92,6 +100,15 @@ class kat(object):
         self.__noxaxis = None
         self.__time_code = None
         
+        if kat_code != None and kat_file != None:
+            raise exceptions.RuntimeError("Specify either a Kat file or some Kat code, not both.")
+        
+        if kat_code != None:
+            self.parseCommands(kat_code)
+        
+        if kat_file != None:
+            self.loadKatFile(kat_file)
+            
     @property
     def maxtem(self): return self.__maxtem
     @maxtem.setter
@@ -112,135 +129,150 @@ class kat(object):
     @noxaxis.setter
     def noxaxis(self,value): self.__noxaxis = bool(value)
        
-    def load(self, katfile):
-        """
-        Loads the kat file specified which can then be run
-        """
-        
+    def loadKatFile(self, katfile):
         with open(katfile) as f:
-            for lines in f.readlines():
-                self.__extra_lines.append(lines)
-        
-	   
+            parseCommands(f.readlines())
+    
+    def parseCommands(self, commands):
+        for line in commands.split("\n"):
+            if len(line.strip()) > 0: 
+                first = line.split(" ",1)[0]
+                
+                if(first == "m"):
+                    self.add(pykat.components.mirror.parseFinesseText(line))
+                elif(first == "s"):
+                    self.add(pykat.components.space.parseFinesseText(line))
+                elif(first == "l"):
+                    self.add(pykat.components.laser.parseFinesseText(line))
+                else:
+                    print "Could not parse `{0}`".format(line)
+                    self.__extra_lines.append(line + "\n")
+            
     def run(self, printout=1, printerr=1, save_output=False, save_kat=False,kat_name=None) :
         """ 
         Runs the current simulation setup that has been built thus far.
         It returns a katRun object which is populated with the various
         data from the simulation run.
         """
-        
-        r = katRun()
-        r.katScript = "".join(self.generateKatScript())       
-        
-        if len(self.__katexe) == 0:
-            # Get the environment variable for where Finesse is stored
-            self.__finesse_dir = os.environ.get('FINESSE_DIR')
-        
+        try:
+            r = katRun()
+            r.katScript = "".join(self.generateKatScript())       
             
-            if self.__finesse_dir == None :
-                raise MissingFinesseEnvVar()
-        
-            kat_exec = os.path.join(self.__finesse_dir,'kat.exe') 
+            if len(self.__katexe) == 0:
+                # Get the environment variable for where Finesse is stored
+                self.__finesse_dir = os.environ.get('FINESSE_DIR')
             
-        else:
-            kat_exec = self.__katexe
-        
-        # check if kat file exists and it is executable by user        
-        if not (os.path.isfile(kat_exec) and os.access(kat_exec, os.X_OK)):
-            raise MissingFinesse()
-        
-        # create a kat file which we will write the script into
-        katfile = tempfile.TemporaryFile(suffix=".kat")
-        katfile.writelines(r.katScript)
-        katfile.flush()
-        
-        flags = "--perl1 "
-        
-        if self.__time_code:
-            flags = flags + " --perf-timing --no-backspace"
+                
+                if self.__finesse_dir == None :
+                    raise MissingFinesseEnvVar()
             
-        kat_exec = "{0} {1} {2}".format(kat_exec, flags, katfile.name)
-                                                            
-        p=subprocess.Popen(kat_exec, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
-        for line in iter(p.stderr.readline, ""):
-            vals = line.split("-")
+                kat_exec = os.path.join(self.__finesse_dir,'kat.exe') 
+                
+            else:
+                kat_exec = self.__katexe
+            
+            # check if kat file exists and it is executable by user        
+            if not (os.path.isfile(kat_exec) and os.access(kat_exec, os.X_OK)):
+                raise MissingFinesse()
+            
+            # create a kat file which we will write the script into
+            katfile = tempfile.TemporaryFile(suffix=".kat")
+            katfile.writelines(r.katScript)
+            katfile.flush()
             
-            if len(vals) == 2:
-                action = vals[0].strip()
-                prc = vals[1].strip()[:-1]
+            flags = "--perl1 "
+            
+            if self.__time_code:
+                flags = flags + " --perf-timing --no-backspace"
                 
-                #sys.stdout.write("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b")
-                sys.stdout.write("\r{0} {1}%".format(action, prc))
-                sys.stdout.flush()
+            kat_exec = "{0} {1} {2}".format(kat_exec, flags, katfile.name)
+                          
+            p=subprocess.Popen(kat_exec, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            err = ""
             
-        [out,err] = p.communicate()
-        
-        # get the version number
-        ix = out.find('build ') + 6
-        ix2 = out.find(')',ix)
-        r.katVersion = out[ix:ix2]
-        
-        r.runDateTime = datetime.datetime.now()
-        
-        # if something has gone wrong, print err regardless
-        if p.returncode != 0:
-            print err
-            return None
-        
-        if printout == 1: print out
-        if printerr == 1: print err
-
-        root = os.path.splitext(katfile.name)
-        base = os.path.basename(root[0])            
-        outfile = root[0] + ".out"
+            for line in iter(p.stderr.readline, ""):
+                err += line
+                vals = line.split("-")
                 
-        [r.x,r.y,hdr] = self.readOutFile(outfile)
-        
-        r.xlabel = hdr[0]
-        r.ylabels = hdr[1:]
-        
-        if save_output:        
-            newoutfile = "{0}.out".format(base)
+                if len(vals) == 2:
+                    action = vals[0].strip()
+                    prc = vals[1].strip()[:-1]
+                    
+                    #sys.stdout.write("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b")
+                    sys.stdout.write("\r{0} {1}%".format(action, prc))
+                    sys.stdout.flush()
+                
+            [out,errpipe] = p.communicate()
             
-            cwd = os.path.os.getcwd()
-            newoutfile = os.path.join(cwd,newoutfile)
+            print out
             
-            if os.path.isfile(newoutfile):
-                os.remove(newoutfile)
-                
-            os.rename(outfile, newoutfile)
-
-            print "Output data saved to '{0}'".format(newoutfile)
+            # get the version number
+            ix = out.find('build ') + 6
+            ix2 = out.find(')',ix)
+            r.katVersion = out[ix:ix2]
             
-        if save_kat:
-            if kat_name == None:
-                kat_name = "pykat_output"                
+            r.runDateTime = datetime.datetime.now()
             
-            cwd = os.path.os.getcwd()
-            newkatfile = os.path.join(cwd, kat_name + ".kat")
+            if p.returncode != 0:
+                raise FinesseError(err, katfile.name)
             
-            if os.path.isfile(newkatfile):
-                os.remove(newkatfile)
-              
-            os.rename(katfile.name, newkatfile)         
+            if printout == 1: print out
+            if printerr == 1: print err
+
+            root = os.path.splitext(katfile.name)
+            base = os.path.basename(root[0])            
+            outfile = root[0] + ".out"
+                    
+            [r.x,r.y,hdr] = self.readOutFile(outfile)
             
-            print "Kat file saved to '{0}'".format(newkatfile)
+            r.xlabel = hdr[0]
+            r.ylabels = hdr[1:]
             
+            if save_output:        
+                newoutfile = "{0}.out".format(base)
+                
+                cwd = os.path.os.getcwd()
+                newoutfile = os.path.join(cwd,newoutfile)
+                
+                if os.path.isfile(newoutfile):
+                    os.remove(newoutfile)
+                    
+                os.rename(outfile, newoutfile)
 
-        katfile.close()
-        perfData = []
-        
-        if self.__time_code:
-            perffile = open(root[0] + ".perf",'r')
+                print "Output data saved to '{0}'".format(newoutfile)
+                
+            if save_kat:
+                if kat_name == None:
+                    kat_name = "pykat_output"                
+                
+                cwd = os.path.os.getcwd()
+                newkatfile = os.path.join(cwd, kat_name + ".kat")
+                
+                if os.path.isfile(newkatfile):
+                    os.remove(newkatfile)
+                  
+                os.rename(katfile.name, newkatfile)         
+                
+                print "Kat file saved to '{0}'".format(newkatfile)
+                
+
+            katfile.close()
+            perfData = []
             
-            for l in perffile.readlines():
-                vals = l.strip().split(' ')
-                perfData.append((vals[0], float(vals[1]), float(vals[2]), float(vals[3])))
+            if self.__time_code:
+                perffile = open(root[0] + ".perf",'r')
+                
+                for l in perffile.readlines():
+                    vals = l.strip().split(' ')
+                    perfData.append((vals[0], float(vals[1]), float(vals[2]), float(vals[3])))
+                    
+                return [r, perfData]
+            else:
+                return r
                 
-            return [r, perfData]
-        else:
-            return r
+        except FinesseError as fe:
+            print fe
+            
         
     def add(self, obj) :
         
@@ -251,7 +283,6 @@ class kat(object):
                         
             self.__components[obj.name] = obj
             self.__add_component(obj)
-                        
             
         elif isinstance(obj, Detector):
             
@@ -267,14 +298,11 @@ class kat(object):
             self.__add_command(obj)
             
         else :
-            raise exceptions.ValueError("Object could not be added")
-            
+            raise exceptions.ValueError("Object {0} could not be added".format(obj))
             
-            # now we have added the component we need to update the node
-            # network
-            
-       
+        obj._on_kat_add(self)
     
+
     def readOutFile(self, filename):
         
         outfile = open(filename,'r')
diff --git a/pykat/node_network.py b/pykat/node_network.py
index 64acdf17e233bbeae2c040156e9ab65fb47dd177..b39431ca5aa52fd2c97654abc255ebec76f25b3f 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -101,10 +101,7 @@ class Node(object):
     def remove(self):
         self._network.removeNode(self)
         self._item.scene().removeItem(self._item)
-     
-    #def disconnect(self, obj):
-        
-                 
+                      
     def connect(self, obj):
 
         if not (isinstance(obj,Component) or isinstance(obj,Detector)):
@@ -121,7 +118,7 @@ class Node(object):
                                     obj.name, self.__name,self._comp1.name,self._comp2.name))
             
             if self._comp1 == self._comp2:
-                raise exceptions.RuntimeError("Cannot connect {obj} to both sides of node".format(obj.name))            
+                raise exceptions.RuntimeError("Cannot connect {0} to both sides of node".format(obj.name))            
         else:
             # we must have a detector as we check above            
             self._detectors.append(obj)
@@ -173,6 +170,6 @@ class Node(object):
     
 class DumpNode(Node):
     def __init__(self):
-        Node.__init__(self,'dump')
+        Node.__init__(self, 'dump', None)
         
         
\ No newline at end of file