diff --git a/pykat/SIfloat.py b/pykat/SIfloat.py
index e18a1750f6083d32529774b2bdd74149d0c9438b..e93166719a30d21bfb80ba68c8776cd670d79cc3 100644
--- a/pykat/SIfloat.py
+++ b/pykat/SIfloat.py
@@ -1,16 +1,14 @@
 import os
 import re
 
-"""
-class SIfloat(value):
-     def __init__(self, value):
-        self.__value = value
-"""     
-
 #staticmethod
 def SIfloat(value):
-    value=str(value)
-
+    if type(value)==list:
+        return [convertToFloat(s) for s in value]
+    else:
+        return convertToFloat(value)
+    
+def convertToFloat(value):
     __prefix = {'y': 1e-24,  # yocto
                 'z': 1e-21,  # zepto
                 'a': 1e-18,  # atto
@@ -30,7 +28,7 @@ def SIfloat(value):
                 'Z': 1e21,   # zetta
                 'Y': 1e24,   # yotta
                 }
+    value = str(value)
     for i, j in __prefix.iteritems():
         value=value.replace(i, str(j))
     return float(value)
-    
diff --git a/pykat/commands.py b/pykat/commands.py
index 9a2ac779ec67587771116d196925bf8405af5de4..45ab2ca9a5f6307e5d04745170266b44f0866406 100644
--- a/pykat/commands.py
+++ b/pykat/commands.py
@@ -86,7 +86,7 @@ class xaxis(Command):
         if numpy.size(limits) != 2 :
             raise exceptions.ValueError("limits input should be a 2x1 vector of limits for the xaxis")
             
-        self.limits = numpy.array(limits).astype(float)
+        self.limits = numpy.array(SIfloat(limits)).astype(float)
         
         if steps <= 0 :
             raise exceptions.ValueError("steps value should be > 0")            
@@ -131,4 +131,4 @@ class xaxis(Command):
                 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 fe3bb36ecad940ead430abe5f9e7814d97b0165a..ab3b40325b9348928ab5167762e9d91c5cab7033 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -43,7 +43,7 @@ class Component(object) :
         self.__id = next_component_id
         next_component_id += 1
         
-    def _on_kat_add(self, kat, node_array):
+    def _on_kat_add(self, kat):
         """
         Called when this component has been added to a kat object.
         kat is the finesse.kat object which it now belongs to and
@@ -55,16 +55,12 @@ class Component(object) :
             
         self._kat = kat
         
-        for node_name in self._requested_node_names:
-            node = self.__addNode(node_name)
+        kat.nodes.registerComponentNodes(self, self._requested_node_names, self.__on_node_change)
         
-        # now that we have changed what our nodes are we need to
-        # update stuff...
-        self._on_node_change()
-        
-    def _on_node_change():
+    def __on_node_change(self):
         # need to update the node gauss parameter setter members 
-        self.__update_node_setters()
+        #self.__update_node_setters()
+        return
         
     def __update_node_setters(self):
         # check if any node setters have already been added. If so we
@@ -77,7 +73,7 @@ class Component(object) :
             detattr(self, '__nodesetter_' + ns._node.name)
             delattr(self.__class__, ns._node.name)
     
-        for node_name in self.getNodes():
+        for node in self.nodes:
             self.__add_node_setter(NodeGaussSetter(self, node))
         
     def __add_node_setter(self, ns):
@@ -97,30 +93,16 @@ class Component(object) :
     @staticmethod
     def parseFinesseText(text):    
         raise NotImplementedError("This function is not implemented")
-    
-    def setAttr(name, value):    
-        raise NotImplementedError("This function is not implemented")
-        
+            
     def getFinesseText(self):
         """ Base class for individual finesse optical components """    
         raise NotImplementedError("This function is not implemented")
         
     def getQGraphicsItem(self):    
         return None      
-        
-    def __addNode(self, name):            
-        n = self._kat.nodes.createNode(name)
-        
-        if n == None:
-            raise exceptions.RuntimeError("createNode did not return a node for '{0}'".format(name))
-        else:
-            n.connect(self)
-                        
-        return n
-        
-    def getNodes(self):
-        """ Returns a copy of the nodes the component has """
-        return self._kat.nodes.getComponentNodes(self)        
+    
+    @property
+    def nodes(self): return self._kat.nodes.getComponentNodes(self) 
     
     @property    
     def name(self): return self.__name      
@@ -132,7 +114,7 @@ class Component(object) :
     
 class Param(float):
     def __new__(self,name,value):
-        return float.__new__(self,value)
+        return float.__new__(self,SIfloat(value))
          
     def __init__(self,name,value):
         self.__name = name
@@ -230,14 +212,10 @@ class mirror(Component):
         
     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,
-                nodes[0].name, nodes[1].name))
+                self.nodes[0].name, self.nodes[1].name))
 
         if self.r_ap != 0: rtn.append("attr {0} r_ap {1}".format(self.name,self.__r_ap))            
         if self.mass != 0: rtn.append("attr {0} mass {1}".format(self.name,self.__mass))
@@ -250,8 +228,7 @@ 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,nodes[0]), (14,15,nodes[1])])
+            self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/mirror_flat.svg", self ,[(-4,15,self.nodes[0]), (14,15,self.nodes[1])])
             
         return self._svgItem
    
@@ -293,12 +270,10 @@ class space(Component):
             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, nodes[0].name, nodes[1].name)            
+            return 's {0} {1} {2} {3}'.format(self.name, self.__L, self.nodes[0].name, self.nodes[1].name)            
         else:
-            return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, nodes[0].name, nodes[1].name)            
+            return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, self.nodes[0].name, self.nodes[1].name)            
        
     def getQGraphicsItem(self):
         if self._QItem == None:
@@ -306,19 +281,19 @@ class space(Component):
         
         return self._QItem  
 
-    def changeNode(self, node_old, node_new):
-        '''
-        Called when a space's node has been connected
-        to another components node
-        '''
-        node_new.connect(self)
-        node_old.disconnect(self)
-        
-        if self._nodes[0] == node_old:
-            self._nodes[0] = node_new
-        
-        if self._nodes[1] == node_old:
-            self._nodes[1] = node_new
+    # def changeNode(self, node_old, node_new):
+        # '''
+        # Called when a space's node has been connected
+        # to another components node
+        # '''
+        # node_new.connect(self)
+        # node_old.disconnect(self)
+        
+        # if self._nodes[0] == node_old:
+            # self._nodes[0] = node_new
+        
+        # if self._nodes[1] == node_old:
+            # self._nodes[1] = node_newf
 
     
 class laser(Component):
@@ -363,15 +338,11 @@ class laser(Component):
             raise exceptions.FinesseParse("Laser Finesse code format incorrect '{0}'".format(text))
     
     def getFinesseText(self):
-        nodes = self.getNodes()
-        
-        return 'l {0} {1} {2} {3} {4}'.format(self.name, self.__power, self.__f_offset, self.__phase, nodes[0].name)            
+        return 'l {0} {1} {2} {3} {4}'.format(self.name, self.__power, self.__f_offset, self.__phase, self.nodes[0].name)            
          
     def getQGraphicsItem(self):
         if self._svgItem == None:
-            nodes = self.getNodes()
-            self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/laser.svg",
-                                                   self,[(65,25,nodes[0])])
+            self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/laser.svg", self, [(65,25,self.nodes[0])])
             
         return self._svgItem
             
diff --git a/pykat/detectors.py b/pykat/detectors.py
index ebbaed8d1be528584ece7d838f58b7d0a6f769e6..6417c0707db2e358f3d43b2f53014065e842bac5 100644
--- a/pykat/detectors.py
+++ b/pykat/detectors.py
@@ -49,25 +49,73 @@ class Detector(object) :
     name = property(__getname)
 
 class photodiode(Detector):
-    class demodulation:
-        def __init__(self, f, phase):
-            self.frequency = f
-            self.phase = phase
+            
+    def __init__(self, name, node, type, num_demods, demods):
         
-    def __init__(self, name, node, demods):
         Detector.__init__(self, name, node)
-        
-        self._num_demods = len(demods)
-        
-        for d in demods:
-            if not isinstance(d, photodiode.demodulation):
-                raise ValueError("demods array has something other than a demodulation in it")
-                
-            self._demods.append(d)
+        if num_demods>2:
+            raise NotImplementedError("pd with more than two demodulations not implemented yet")   
+        self.num_demods = num_demods
+        self.type = type
+        self
+
+    @property
+    def num_demods(self): return Param('num_demods', self.__num_demods)
+    @num_demods.setter
+    def num_demods(self,value): self.__num_demods = int(value)
+    @property
+    def type(self): return Param('type', self.__type)
+    @type.setter
+    def type(self,value): self.__type = value
+    @property
+    def f1(self): return Param('f1', self.__f1)
+    @f1.setter
+    def f1(self,value): self.__f1 = SIfloat(value)
+    @property
+    def phi1(self): return Param('phi1', self.__phi1)
+    @phi1.setter
+    def phi1(self,value): self.__phi1 = SIfloat(value)    
 
     @staticmethod
-    def parseFinesseText(text):    
-        raise NotImplementedError("This function is not implemented")   
+    def parseFinesseText(text): 
+        values = text.split(" ")
+
+        if values[0][0:2] != "pd":
+            raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text))
+        if len(value[0])==2:
+            __num_demods=0
+            __type=""
+        elif len(value[0])==3 or len(value[0])==4:
+            if value[0][3]=="S":
+                __type="S"
+            elif value[0][3]=="N":
+                __type="N"
+            else:
+                try:
+                    __num_demods=int(values[0][3])
+                    __type=""
+                except ValueError:
+                    raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text))
+            if len(value[0])==4:
+                try:
+                    __num_demods=int(values[0][4])
+                except ValueError:
+                    raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text))                
+        else:
+            raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text))
+
+        if __num_demods<0 or __num_demods>5:
+            raise exceptions.FinesseParse("'{0}' number of demodulations must be >0 and <5".format(text))
+
+        values.pop(0) # remove initial value
+        
+        if len(values) == 2 * __num_demods + 1 or len(values) == 2 * __num_demods + 2:
+            return photodiode(value[0], values[-1], __type, __num_demods, values[1:len(values-1)])
+        else:
+            raise exceptions.FinesseParse("Photodiode code format incorrect '{0}'".format(text))
+
+        #return photodiode("name", "node", demods)   
+        #raise NotImplementedError("This function is not implemented")   
         
     def getFinesseText(self) :
         if self.enabled:    
@@ -90,4 +138,4 @@ class photodiode(Detector):
             self._svgItem = ComponentQGraphicsItem(":/resources/photodiode_red.svg",self,[(-5,11,self._node)])
         
         return self._svgItem    
-        
\ No newline at end of file
+        
diff --git a/pykat/finesse.py b/pykat/finesse.py
index d7b7d3c37da1c3951c10a9d0b3b19f66d187ae22..fe7393e5408df8be16d4d14cfd9bce2bd4c31387 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -76,7 +76,7 @@ class Block:
     
 class kat(object):                    
         
-    def __init__(self, kat_file=None, kat_code=None, katdir="", katname=""):
+    def __init__(self, kat_file=None, kat_code=None, katdir="", katname="", tempdir=None, tempname=None):
         
         self.scene = None # scene object for GUI
         self.__blocks = {} # dictionary of blocks that are used
@@ -88,6 +88,8 @@ class kat(object):
         self.nodes = NodeNetwork(self)  
         self.__katdir = katdir
         self.__katname = katname
+        self.__tempdir = tempdir
+        self.__tempname = tempname
         self.pykatgui = None
         
         # Various options for running finesse, typicaly the commands with just 1 input
@@ -132,7 +134,7 @@ class kat(object):
     
     def parseKatCode(self, code):
         #commands = code.split("\n")
-        self.parseCommands(commands)
+        self.parseCommands(code)
         
     def parseCommands(self, commands):
         blockComment = False
@@ -191,16 +193,16 @@ class kat(object):
                     obj = pykat.components.space.parseFinesseText(line)
                 elif(first == "l"):
                     obj = pykat.components.laser.parseFinesseText(line)
-                elif(first == "xaxis" or first == "x2axis" or first == "xaxis*" or first == "x2axis*"):
-                    obj = pykat.commands.xaxis.parseFinesseText(line)
+                elif(first == "xaxis" or first == "x2axis" or first == "xaxis*" or first == "x2axis*"):
+                    obj = pykat.commands.xaxis.parseFinesseText(line)
                 else:
                     print "Parsing `{0}` into pykat object not implemented yet, added as extra line.".format(line)
                     obj = line
                 
-                self.__block[self.__currentTag].contents.append(obj)
+                self.__blocks[self.__currentTag].contents.append(obj)
                 
-                if not isinstance(line, str):
-                    self.__block[self.__currentTag].contents.append(obj)
+                if not isinstance(obj, str):
+                    self.__blocks[self.__currentTag].contents.append(obj)
                     self.add(obj)
                     
         self.__currentTag = NO_BLOCK 
@@ -239,7 +241,12 @@ class kat(object):
                 raise MissingFinesse()
             
             # create a kat file which we will write the script into
-            katfile = tempfile.NamedTemporaryFile(suffix=".kat")
+            if self.__tempname == None:
+                katfile = tempfile.NamedTemporaryFile(suffix=".kat", dir=self.__tempdir)
+            else:
+                filepath =os.path.join(self.__tempdir, self.__tempname+".kat" )
+                katfile = open( filepath, 'w' ) 
+                
             katfile.writelines(r.katScript)
             katfile.flush()
             
@@ -249,6 +256,7 @@ class kat(object):
                 cmd.append('--no-backspace')
 
             cmd.append(katfile.name)
+            print cmd
             p=subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
             err = ""
             
@@ -399,7 +407,8 @@ class kat(object):
         out = []    
         
         for key in self.__blocks:
-            objs = self.__blocks[key]
+            objs = self.__blocks[key].contents
+            print key, objs
             out.append("%%% FTblock " + key)
             
             for obj in objs:
diff --git a/pykat/node_network.py b/pykat/node_network.py
index 850e5fcf428cc5905c148f5bfe8ac9f58dfb21e4..de4221dd77cef26a5b7a25203a0b54d446ab30dd 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -12,52 +12,99 @@ from pykat.detectors import Detector
 
 class NodeNetwork(object):
     def __init__(self, kat):
-        self._nodes = {}
+        self.__nodes = {}
         self.__kat = kat
-        self.__componentNodes = {}
+        self.__nodeComponents = {} # dictionary of tuples containing which components are connected to a node
+        self.__componentNodes = {} # dictionary of tuples containing which nodes are connected to a given component
+        self.__componentCallback = {}
+        self.__node_id = 1
+        
+    def registerComponentNodes(self, comp, node_names, change_callback):
+        """
+        For a given component we create some nodes or get existing ones and 
+        attach them to this component. Also specify a callback function that
+        is called whenever the nodes attached to this component are changed
+        , e.g. connected, disconnected, name change, etc.
+        """
+        if not isinstance(comp, Component):
+            raise exceptions.ValueError("comp argument is not of type Component")
+        
+        if comp.id in self.__componentNodes:
+            raise pkex.BasePyKatException("Component has already been registered")
+        
+        list = []
+        
+        for name in node_names:
+            n = createNode(name)
+            self.connectNodeToComp(node, comp, do_callback=False)
+            list.append(n)
+        
+        self.__componentNodes[comp.id] = tuple(list)
+        self.__componentCallback[comp.id] = change_callback
+        
+        change_callback()
+    
+    def connectNodeToComp(self, node, comp, do_callback=True):
+        if node.id in self.__nodeComponents:
+            comps = self.__nodeComponents[node.id]
+        else:
+            comps = ()
+        
+        if len(comps) >= 2:
+            raise pkex.BasePyKatException("Node is already connected to 2 components")
+        
+        l = list(comps)
+        l.append(comp)
+        
+        self.__nodeComponents[node.id] = tuple(l)
+        
+        if do_callback: self.__componentCallback[comp.id]()
         
     def createNode(self, node_name):
         if node_name == 'dump':
             return DumpNode()
             
-        if node_name in self._nodes:
+        if node_name in self.__nodes:
             # then this node already exists
-            return self._nodes[node_name]
+            return self.__nodes[node_name]
         else:
-            n = Node(node_name, self)
-            self.__add_node(n) # add node as a member of this object, e.g. kat.nodes.n
-            self._nodes[node_name] = n
+            n = Node(node_name, self, self.__node_id)
+            
+            self.__node_id += 1
+            self.__add_node_attr(n) # add node as a member of this object, e.g. kat.nodes.n
+            self.__nodes[node_name] = n
             return n
         
     def removeNode(self, node):
         if not isinstance(node,Node):
             raise exceptions.ValueError("node argument is not of type Node")
         
-        if node.name not in self._nodes:
+        if node.name not in self.__nodes:
             raise exceptions.RuntimeError("Trying to remove node {0} when it has not been added".format(node.name))
         
-        C = node.getComponents()
+        C = self.getNodeComponents(node)
         
-        if C[0][0] is not None or C[0][1] is not None:
-            raise exceptions.RuntimeError("Cannot remove a node which is attached to components still")
+        if C[0] is not None or C[1] is not None:
+            raise exceptions.RuntimeError("Cannot remove a node which is attached to components")
             
-        if len(C[1]) > 0:
+        if len(node.getDetectors()) > 0:
             raise exceptions.RuntimeError("Cannot remove a node which is attached to detectors still")
         
-        self.__remove_node(node)
-        del self._nodes[node.name] 
+        self.__remove_node_attr(node)
+        del self.__nodes[node.name] 
         
     def hasNode(self, name):
-        return (name in self._nodes)
+        return (name in self.__nodes)
     
     def getNodes(self):
-        return self._nodes.copy()
+        return self.__nodes.copy()
     
     def dumpInfo(self):
         
-        for name in self._nodes:
+        for name in self.__nodes:
+            
+            n = self.__nodes[name]
             
-            n = self._nodes[name]
             items = n.getComponents()
             comp = items[0][:]
             det = items[1]
@@ -83,25 +130,21 @@ class NodeNetwork(object):
             print "node: {0} connected:{1} {2}->{3} {4}".format(
                     n.name,n.isConnected(),comp1, comp2, detectors)
     
-    def getComponentNodes(self, comp):
+    def getComponentNodes(self, comp): return self.__componentNodes[comp.id]
+    def getNodeComponents(self, node): return self.__nodeComponents[node.id]
     
-        if not isinstance(comp, Component):
-            raise pkex.BasePyKatException("Passed object was not a component")
-        
-        return self.__componentNodes[comp.id]
-            
-    def __add_node(self, node):
+    def __add_node_attr(self, node):
 
         if not isinstance(node, Node):
             raise exceptions.ValueError("Argument is not of type Node")
         
         name = node.name
-        fget = lambda self: self.__get_node(name)
+        fget = lambda self: self.__get_node_attr(name)
         
         setattr(self.__class__, name, property(fget))
         setattr(self, '__node_' + name, node)                   
     
-    def __remove_node(self, node):
+    def __remove_node_attr(self, node):
         if not isinstance(node, Node):
             raise exceptions.ValueError("Argument is not of type Node")
         
@@ -109,7 +152,7 @@ class NodeNetwork(object):
         detattr(self, '__node_' + name)
         delattr(self.__class__, name)
         
-    def __get_node(self, name):
+    def __get_node_attr(self, name):
         return getattr(self, '__node_' + name)        
         
 class Node(object):
@@ -117,19 +160,24 @@ class Node(object):
         w0_z = 1
         z_zR = 2
         
-    def __init__(self, name, network):
-        self._comp1 = None
-        self._comp2 = None
+    def __init__(self, name, network, id):
         self._detectors = []
         self.__name = name
         self._item = None
         self._network = network
         self.__gauss = None
         self.__gauss_version = None
+        self.__id = id
         
+    @property
+    def id(self): return self.__id
+    
     @property
     def network(self): return self._network
     
+    @property
+    def components(self): return self._network.getNodeComponents(self)
+    
     @property
     def gauss(self): return self.__gauss
     
@@ -148,36 +196,11 @@ class Node(object):
             
         self.__gauss_version = Node.gauss_version.w0_z
         
-    def getFinesseText(self):
-        
-        if not self.isConnected() or self.__gauss == None or self.__gauss_version == None:
-            return None
-            
-            
-        comp = ""
-        
-        if self._comp2 == None:
-            comp = self._comp1.name
-        else:
-            comp = self._comp2.name
-        
-        rtn = []
-        
-        if self.__gauss_version == Node.gauss_version.w0_z:
-            
-            if len(self.__gauss) == 2:
-                rtn.append("gauss gauss_{node} {comp} {node} {w0} {z}".format(node=self.name, comp=comp, w0=self.__gauss[0], z=self.__gauss[1]))
-            elif len(self.__gauss) == 4:
-                rtn.append("gauss gauss_{node} {comp} {node} {w0x} {zx} {w0y} {zy}".format(node=self.name, comp=comp, w0x=self.__gauss[0], zx=self.__gauss[1], w0y=self.__gauss[2], zy=self.__gauss[3]))
-            else:
-                raise pkex.BasePyKatException("Unexpected number of gaussian parameters")
-        else:
-            raise pkex.BasePyKatException("Unexpected gauss version")
-            
-        return rtn
+    def getFinesseText(self):    
+        return []
         
     def isConnected(self):
-        if (self._comp1 is not None) and (self._comp2 is not None):
+        if (self.components[0] is not None) and (self.self.components[1] is not None):
             return True
         else:
             return False
@@ -188,94 +211,46 @@ class Node(object):
         if self._item != None:
             self._item.scene().removeItem(self._item)
     
-    def disconnect(self, obj):
-    
-        if not (isinstance(obj,Component) or isinstance(obj,Detector)):
-            raise exceptions.ValueError("Object is not a component or detector")
-        
-        if isinstance(obj, Component):
-            
-            if self._comp1 == obj:
-                self._comp1 = None
-            elif self._comp2 == obj:
-                self._comp2 = None
-            else:
-                raise exceptions.RuntimeError("Cannot dettach {0} from node {1}".format(
-                                    obj.name, self.__name))
-          
-        else:
-            # we must have a detector as we check above            
-            self._detectors.remove(obj)
-    
-        if self._item is not None:
-            self._item.refresh()
-            
-    
-    def connect(self, obj):
-
-        if not (isinstance(obj,Component) or isinstance(obj,Detector)):
-            raise exceptions.ValueError("Object is not a component or detector")
-        
-        if isinstance(obj, Component):
-            
-            if self._comp1 == None:
-                self._comp1 = obj
-            elif self._comp2 == None:
-                self._comp2 = obj
-            else:
-                raise exceptions.RuntimeError("Cannot attach {0} to node {1} as it is already connected: {2} and {3}".format(
-                                    obj.name, self.__name,self._comp1.name,self._comp2.name))
-            
-            if self._comp1 == self._comp2:
-                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)
-    
-        if self._item is not None:
-            self._item.refresh()
-            
     def getQGraphicsItem(self,dx=0,dy=0,nsize=8,parent=None):
         if self._item == None:
             self._item = pykat.gui.graphics.NodeQGraphicItem(self,
                                                              dx,dy,
                                                              -nsize/2,-nsize/2,
-                                                             nsize,nsize,parent)
+                                                             nsize, nsize, parent)
             
         return self._item
     
-    def getComponents(self):
-        ''' Returns a tuple with the first being the 2 components that 
-        connect to the node. The second item is a list of the detectors at the
-        node'''
-        return [(self._comp1, self._comp2),self._detectors]
+    def getDetectors(self):
+        return self._detectors[:]
         
     def amIConnected(self, obj):
         """
         Checks if obj is connected to the node. Returns true or false in tuple
         with None or the other object and the node index which it is attached to
         """ 
-        if obj == self._comp1:
-            if self._comp2 == None:
+        comps = self.components
+        
+        if obj == comps[0]:
+            if comps[1] == None:
                 ix = -1
             else:
-                ix = self._comp2.getNodes().index(self)
+                ix = comps[1].getNodes().index(self)
                 
-            return [True, self._comp2, ix]
-        elif obj == self._comp2:
-            if self._comp1 == None:
+            return [True, comps[1], ix]
+            
+        elif obj == comps[1]:
+            if comps[0] == None:
                 ix = -1
             else:
-                ix = self._comp1.getNodes().index(self)
+                ix = comps[0].getNodes().index(self)
                 
-            return [True, self._comp1, ix]
+            return [True, comps[0], ix]
         else:
             return [False, None]
         
-    def __getname(self):
-        return self.__name      
-        
-    name = property(__getname)
+    @property
+    def name(self): return self.__name      
+    
     
 class DumpNode(Node):
     def __init__(self):