diff --git a/bin/test_aperture.py b/bin/test_aperture.py
index 03bcee70685592c1f7527009bd1ef6e46f779ee1..7f42b1eee64ab7c77cea95026484d822d48ec269 100644
--- a/bin/test_aperture.py
+++ b/bin/test_aperture.py
@@ -28,7 +28,6 @@ for tem in maxtem:
     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()
diff --git a/bin/test_pykat_gui.py b/bin/test_pykat_gui.py
index 2a77fefee9a3de88c536ff4a94ecfe8b8f05a187..463c622479761a7fe844648122888a6e765ed52a 100644
--- a/bin/test_pykat_gui.py
+++ b/bin/test_pykat_gui.py
@@ -6,12 +6,13 @@ 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
 
 code = """
-l l1 1 0 0 n1
+#l l1 1 0 0 n1
+
+s s1 1 n3 n4
 """
 
 kat = finesse.kat(kat_code = code)
diff --git a/pykat/components.py b/pykat/components.py
index 93481203502a644e628fbd37cb202172d3ab4566..f4ed356940f8e8306ec71c540fe8e4911f15fe31 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -94,8 +94,8 @@ class Component(object) :
         # now we have a list of which to remove
         for key in key_rm:
             ns = self.__dict__[key]
-            detattr(self, '__nodesetter_' + ns._node.name)
-            delattr(self, ns._node.name)
+            delattr(self, '__nodesetter_' + ns.node.name)
+            delattr(self.__class__, ns.node.name)
         
         for node in self.nodes:
             if type(node) != pykat.node_network.DumpNode:
@@ -305,22 +305,7 @@ class space(Component):
         if self._QItem == None:
             self._QItem = pykat.gui.graphics.SpaceQGraphicsItem(self)
         
-        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_newf
-
+        return self._QItem          
     
 class laser(Component):
     def __init__(self,name,node,P=1,f_offset=0,phase=0):
diff --git a/pykat/gui/graphics.py b/pykat/gui/graphics.py
index c9465f36dca3c21ab2cebbc399ef9be9011d5a06..96113037e5727bc384c4c5aa9d84aa4c1275c347 100644
--- a/pykat/gui/graphics.py
+++ b/pykat/gui/graphics.py
@@ -56,16 +56,16 @@ class SpaceQGraphicsItem(QGraphicsLineItem):
     @property
     def space(self): return self.__space
     
-    def refresh(self):    
-        nodes = self.__space.getNodes()
-            
+    def refresh(self):
+        nodes = self.__space.nodes
+                
         conn = nodes[0].amIConnected(self.__space)
         
         x1 = 0
         y1 = 0
         x2 = 0
         y2 = 0
-        
+                
         if conn[0]:
             if conn[1] != None:
                 if self.__n1 is not None:
@@ -178,7 +178,7 @@ class ComponentQGraphicsItem(QtSvg.QGraphicsSvgItem):
     def itemChange(self, change, value):
         # if the item is moved then update any spaces attached to it
         if change == QGraphicsItem.ItemPositionHasChanged:
-            nodes = self.__component.getNodes()
+            nodes = self.__component.nodes
             
             for n in nodes:
                 conn = n.amIConnected(self.__component)
diff --git a/pykat/gui/gui.py b/pykat/gui/gui.py
index db41984bd3919fbed5a3aa27d481ba41b50c8037..5532630aafb2716dc882c518ab155680cb853542 100644
--- a/pykat/gui/gui.py
+++ b/pykat/gui/gui.py
@@ -5,7 +5,7 @@ Created on Tue Jan 29 11:35:48 2013
 @author: Daniel
 """
 
-from pykat.components import Component
+from pykat.components import Component, space
 from pykat.detectors import Detector
 
 from PyQt4 import QtGui, QtCore
@@ -16,11 +16,11 @@ import qt_gui
 import functools
 
 class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
-    def __init__(self, kat,parent=None):
+    def __init__(self, kat, parent=None):
         super(pyKatGUI, self).__init__(parent)
         
         self.setupUi(self)
-        self.graphicsView = pyKatGraphicsView(self.centralwidget)
+        self.graphicsView = pyKatGraphicsView(self.centralwidget, kat)
         self.graphicsView.setObjectName("graphicsView")
         self.graphicsView.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
         self.graphicsView.viewport().setMouseTracking(True)
@@ -41,8 +41,11 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
         self.actionExport_to_SVG.triggered.connect(lambda: self.exportToSVG())
         self.actionClose.triggered.connect(lambda: self.close)
 
-        self.kat = kat        
+        self._kat = kat        
         
+    @property
+    def kat(self): return self._kat
+    
     def main(self):
         self.show()
         
@@ -52,7 +55,6 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
         return self.__scene
 
     def addComponentsToScene(self):
-        
         for c in self.kat.getComponents():
             self.addComponentToScene(c)
                 
@@ -120,7 +122,27 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
 
         self.kat.add(l)
         self.addComponentToScene(l,x,y)   
+     
+    def disconnect(self, node):
+        comps = self.kat.nodes.getNodeComponents(node)
+        
+        spaces = [c for c in comps if isinstance(c, space)]
+        
+        if len(spaces) > 0:
+            dis_comp = spaces[0]
+        else:
+            dis_comp = comps[0]
+        
+        new_node_name = self.kat.getNewNodeNames("n", 1)
+        new_node = self.kat.nodes.createNode(new_node_name[0])
+        
+        self.kat.nodes.replaceNode(dis_comp, node, new_node)
         
+        # refresh all the graphics that might be affected
+        for c in node.components + new_node.components:
+            if c != None:
+                c.getQGraphicsItem().refresh()
+    
 class pyKatGraphicsScene(QGraphicsScene):
     def drawBackground(self, painter, rect):
         size = 10
@@ -149,9 +171,9 @@ class pyKatGraphicsScene(QGraphicsScene):
             painter.drawLine(y, rect.top(), y, rect.bottom())
                     
 class pyKatGraphicsView(QGraphicsView):
-    def __init__(self,val):
-        QGraphicsView.__init__(self,val)
-        
+    def __init__(self, val, kat):
+        QGraphicsView.__init__(self, val)
+        self._kat = kat
         self.__selected_item = None
         self.__prev_pt = None
         self.setMouseTracking(True)
@@ -189,8 +211,11 @@ class pyKatGraphicsView(QGraphicsView):
                 menu.addAction("Delete")
             if isinstance(item,NodeQGraphicItem):
                 menu.addSeparator()
-                menu.addAction("Disconnect")
+                comps = self._kat.nodes.getNodeComponents(item.node)
                 
+                if(comps.count(None) == 0):
+                    action = menu.addAction("Disconnect")
+                    action.triggered.connect(functools.partial(gui.disconnect, item.node))
 
         menu.popup(ev.globalPos());        
         
@@ -244,8 +269,7 @@ class pyKatGraphicsView(QGraphicsView):
             # connect space of node dragged to the component node
             # the space node that has been dragged gets deleted and we
             # replace it with the components
-            space.changeNode(node_s, node_c)
-            node_s.remove() # now remove from node network completly
+            self._kat.nodes.replaceNode(space, node_s, node_c)
             
             # then refresh the graphical items
             qspace.refresh()
diff --git a/pykat/node_network.py b/pykat/node_network.py
index f4067debe0e4f33eed8530e912be9c66b4053887..0e915d767d76a6998a07f1bce096b025a2704ef9 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -47,17 +47,54 @@ class NodeNetwork(object):
         
         change_callback()
     
+    def replaceNode(self, comp, node_old, node_new):
+        
+        if node_new.components.count(None) == 0:
+            raise pkex.BasePyKatException("New node already connected to two components")
+            
+        if comp not in node_old.components:
+            raise pkex.BasePyKatException("Old node not attached to component")
+        
+        if comp in node_new.components:
+            raise pkex.BasePyKatException("New node already attached to component")
+        
+        # add component to new node component list
+        new_node_comps = list(node_new.components)
+        new_node_comps[new_node_comps.index(None)] = comp
+        self.__nodeComponents[node_new.id] = tuple(new_node_comps)
+        
+        # remove component from old node list
+        old_node_comps = list(node_old.components)
+        old_node_comps[old_node_comps.index(comp)] = None
+        self.__nodeComponents[node_old.id] = tuple(old_node_comps)
+        
+        comp_nodes = list(comp.nodes)
+        comp_nodes[comp_nodes.index(node_old)] = node_new
+        self.__componentNodes[comp.id] = tuple(comp_nodes)
+        
+        # if old node is no longer connected to anything then delete it
+        if node_old.components.count(None) == 2:
+            self.removeNode(node_old)
+            
+        self.__componentCallback[comp.id]()
+            
     def connectNodeToComp(self, node, comp, do_callback=True):
         if node.id in self.__nodeComponents:
             comps = self.__nodeComponents[node.id]
         else:
-            comps = ()
+            comps = (None,) * 2
         
-        if len(comps) >= 2:
+        if len(comps) >= 2 and comps[0] != None and comps[1] != None:
             raise pkex.BasePyKatException("Node is already connected to 2 components")
         
         l = list(comps)
-        l.append(comp)
+        
+        if l[0] == None:
+            l[0] = comp
+        elif l[1] == None:
+            l[1] = comp
+        else:
+            raise pkex.BasePyKatException("Connected to two coponents already")
         
         self.__nodeComponents[node.id] = tuple(l)
         
@@ -76,6 +113,7 @@ class NodeNetwork(object):
             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
+            self.__nodeComponents[n.id] = (None, None)
             return n
         
     def removeNode(self, node):
@@ -133,8 +171,11 @@ class NodeNetwork(object):
             print "node: {0} connected:{1} {2}->{3} {4}".format(
                     n.name,n.isConnected(),comp1, comp2, detectors)
     
-    def getComponentNodes(self, comp): return self.__componentNodes[comp.id]
-    def getNodeComponents(self, node): return self.__nodeComponents[node.id]
+    def getComponentNodes(self, comp):
+        return self.__componentNodes[comp.id]
+    
+    def getNodeComponents(self, node):
+        return self.__nodeComponents[node.id]
     
     def __add_node_attr(self, node):
 
@@ -152,8 +193,8 @@ class NodeNetwork(object):
             raise exceptions.ValueError("Argument is not of type Node")
         
         name = node.name
-        detattr(self.__class__, '__node_' + name)
-        delattr(self, name)
+        delattr(self, '__node_' + name)
+        delattr(self.__class__, name)
         
     def __get_node_attr(self, name):
         return getattr(self, '__node_' + name)        
@@ -222,7 +263,7 @@ class Node(object):
         return rtn
         
     def isConnected(self):
-        if (self.components[0] is not None) and (self.self.components[1] is not None):
+        if (self.components[0] is not None) and (self.components[1] is not None):
             return True
         else:
             return False
@@ -256,7 +297,7 @@ class Node(object):
             if comps[1] == None:
                 ix = -1
             else:
-                ix = comps[1].getNodes().index(self)
+                ix = comps[1].nodes.index(self)
                 
             return [True, comps[1], ix]
             
@@ -264,7 +305,7 @@ class Node(object):
             if comps[0] == None:
                 ix = -1
             else:
-                ix = comps[0].getNodes().index(self)
+                ix = comps[0].nodes.index(self)
                 
             return [True, comps[0], ix]
         else:
diff --git a/pykat/parser.py b/pykat/parser.py
deleted file mode 100644
index 9bcd32dffe05796e34722343e8b68fdc067c6b20..0000000000000000000000000000000000000000
--- a/pykat/parser.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import os
-import exceptions
-import numpy as np
-
-from pykat.node_network import NodeNetwork
-from pykat.detectors import Detector
-from pykat.components import Component
-from pykat.commands import Command, xaxis
-
-components = np.array(['m','m1','m2','l','s','bs','bs1','bs2','pd','pd*'])
-commands = np.array(['attr','tem','tem*','gauss','gauss*','gauss**','cav','conf'])
-
-
-# some commands we ignore, we do the plotting with pyhton
-# so don't need 
-ignore = ['gnuterm']
-def parse_kat_file(kat_filename):
-    
-    kat_cmps = [] # holds the components found in kat file
-    kat_cmds = [] # holds the commands found in kat file
-    
-    katfile = open(kat_filename,'r')
-    
-    for line in katfile.readlines():
-        arg = line.split(' ')[0]
-        
-        # c
-        if (components == arg).any():
-            kat_cmps.append()
-            
-        elif (commands == arg).any():
-            print ""
-
-def parse_m(line):
-    return line
-    
\ No newline at end of file