diff --git a/pykat/components.py b/pykat/components.py
index dbd95a23875dc33af6e3dc2931864868df92df51..a55a09ef30321f2ca9a8476b15a33b4da4a864b8 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -84,6 +84,8 @@ class NodeGaussSetter(object):
     def qy(self, value):
         self.__node().setGauss(self.__comp(), self.qx, complex(value))
         
+id___ = 0
+  
 class Component(object):
     __metaclass__ = abc.ABCMeta
 
@@ -91,7 +93,13 @@ class Component(object):
         # This creates an instance specific class for the component
         # this enables us to add properties to instances rather than
         # all classes
-        return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
+        global id___
+        id___ += 1
+        cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id___))
+        
+        cnew = type(cnew_name, (cls,), {})
+        
+        return object.__new__(cnew, *args, **kwargs)
         
     def __init__(self, name=None):
         
@@ -116,10 +124,11 @@ class Component(object):
         When deep copying a kat object we need to take into account
         the instance specific properties.
         """
-        result = self.__class__.__new__(self.__class__)
-        result.__dict__ = copy.deepcopy(self.__dict__, memo)
         
-        result.__update_node_setters             
+        # Here we create a copy of this object based of the base class
+        # of this one, otherwise we're making a copy of a copy of a copy...
+        result = self.__class__.__new__(self.__class__.__base__)
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
         
         return result
         
@@ -163,13 +172,19 @@ class Component(object):
         # need to remove them. This function should get called if the nodes
         # are updated, either by some function call or the GUI
         key_rm = [k for k in self.__dict__ if k.startswith("__nodesetter_", 0, 13)]
-        
+
         # now we have a list of which to remove
         for key in key_rm:
             ns = self.__dict__[key]
-            delattr(self, '__nodesetter_' + ns.node.name)
-            delattr(self.__class__, ns.node.name)
+            name = str(ns.node.name)
+            
+            if '__nodesetter_' + name in self.__dict__:
+                delattr(self, '__nodesetter_' + name)
             
+            if name in self.__class__.__dict__:
+                delattr(self.__class__, name)
+        
+        # Now re-add them pointing to the recent nodes
         for node in self.nodes:
             if type(node) != pykat.node_network.DumpNode:
                 ns = NodeGaussSetter(self, node)
@@ -180,9 +195,12 @@ class Component(object):
         if not isinstance(ns, NodeGaussSetter):
             raise exceptions.ValueError("Argument is not of type NodeGaussSetter")
         
-        name = ns.node.name
+        name = str(ns.node.name)
         fget = lambda self: self.__get_node_setter(name)
         
+        if name == "nITM1":
+            print(self.__class__)
+            
         setattr(self.__class__, name, property(fget))
         setattr(self, '__nodesetter_' + name, ns)                   
 
diff --git a/pykat/finesse.py b/pykat/finesse.py
index 9b469143a7d0e826a413f8c9f7b7491d1cccac8c..287a815f48a4b212708e9ce6a7a465e56910ff8f 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -416,7 +416,9 @@ class Block:
     def name(self): return self.__name
     
 Constant = namedtuple('Constant', 'name, value, usedBy')
-    
+
+id___ = 0
+
 class kat(object):  
 
     def __new__(cls, *args, **kwargs):
@@ -428,7 +430,10 @@ class kat(object):
         # kat objects share the same class definition they also have the
         # same properties regardless of whether they have the actual
         # object added to it. So we create an instance specific class.
-        return object.__new__(type(pykat.finesse.kat.__name__, (pykat.finesse.kat,), {}), *args, **kwargs)
+        global id___
+        id___ += 1
+        cnew = type(pykat.finesse.kat.__name__ + str("_") + str(id___), (pykat.finesse.kat,), {})
+        return object.__new__(cnew, *args, **kwargs)
 	
     def __init__(self, kat_file=None, kat_code=None, katdir="", katname="", tempdir=None, tempname=None):
         self.scene = None # scene object for GUI
@@ -477,17 +482,32 @@ class kat(object):
             self.loadKatFile(kat_file)
 
     def __deepcopy__(self, memo):
-        cls = self.__class__
-        result = cls.__new__(cls)
+        """
+        When deep copying a kat object we need to take into account
+        the instance specific properties. This is because when
+        the kat object adds new components it also adds properties for
+        each of these. There properties are unique to each kat object,
+        but properties are part of the class definition. Thus if two
+        kat objects share the same class definition they also have the
+        same properties regardless of whether they have the actual
+        object added to it. So we create an instance specific class.
+        """
+        result = self.__class__.__new__(self.__class__)
         memo[id(self)] = result
-        
-        for k, v in self.__dict__.items():
-            setattr(result, k, copy.deepcopy(v, memo))
-        
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
+
+        # Find all properties in class we are copying
+        # and deep copy these to the new class instance
+        for x in self.__class__.__dict__.items():
+            if isinstance(x[1], property):
+                setattr(result.__class__, x[0], x[1])
+    
+        result.nodes._NodeNetwork__update_nodes_properties()
+                
         # Update any weakrefs
         for c in result.components:
             result.components[c]._Component__update_node_setters()
-            
+        
         return result
     
     @property
diff --git a/pykat/node_network.py b/pykat/node_network.py
index f75c055e2871700a8ff864d72c0b90c328f5481b..2500812d48665b21e6dec1ee5040fb6d384e626d 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -22,13 +22,21 @@ from pykat.detectors import BaseDetector as Detector
 from pykat.optics.gaussian_beams import beam_param
 from copy import deepcopy
 
+id___ = 0
+    
 class NodeNetwork(object):
-
+    
     def __new__(cls, *args, **kwargs):
-    # This creates an instance specific class for the component
-    # this enables us to add properties to instances rather than
-    # all classes
-        return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
+        # This creates an instance specific class for the component
+        # this enables us to add properties to instances rather than
+        # all classes
+        global id___
+        id___ += 1
+        cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id___))
+        
+        cnew = type(cnew_name, (cls,), {})
+        
+        return object.__new__(cnew, *args, **kwargs)
 
     def __init__(self, kat):
         self.__nodes = {}
@@ -37,7 +45,20 @@ class NodeNetwork(object):
         self.__componentNodes = {} # dictionary of tuples containing which nodes are connected to a given component
         self.__componentCallback = {}
         self.__node_id = 1
-            
+    
+    def __deepcopy__(self, memo):
+        """
+        When deep copying a kat object we need to take into account
+        the instance specific properties.
+        """
+        
+        # Here we create a copy of this object based of the base class
+        # of this one, otherwise we're making a copy of a copy of a copy...
+        result = self.__class__.__new__(self.__class__.__base__)
+        result.__dict__ = deepcopy(self.__dict__, memo)
+        
+        return result
+                
     @property
     def kat(self): return self.__kat
         
@@ -151,7 +172,29 @@ class NodeNetwork(object):
         self.__nodeComponents[node.id] = tuple(l)
         
         if do_callback: self.__componentCallback[comp.id]()
-        
+    
+    def __update_nodes_properties(self):
+        # check if any node setters have already been added. If so we
+        # need to remove them. This function should get called if the nodes
+        # are updated, either by some function call or the GUI
+        key_rm = [k for k in self.__dict__ if k.startswith("__node_", 0, 7)]
+
+        # now we have a list of which to remove
+        for key in key_rm:
+            ns = self.__dict__[key]
+            name = str(ns.name)
+            
+            if '__node_' + name in self.__dict__:
+                delattr(self, '__node_' + name)
+            
+            if name in self.__class__.__dict__:
+                delattr(self.__class__, name)
+        
+        # Now re-add them pointing to the recent nodes
+        for node in self.__nodes:
+            if not self.__nodes[node].isDump:
+                self.__add_node_attr(self.__nodes[node])
+         
     def createNode(self, node_name):
         """
         This creates a new node object. It won't be connected to anything or added to a
@@ -285,6 +328,7 @@ class NodeNetwork(object):
             kat.nodes.replaceNode(kat.bs1, "n1", kat.nodes.createNode("test1"))
         
         name = node.name
+        
         delattr(self, '__node_' + name)
         delattr(self.__class__, name)
         
diff --git a/test/test_deepcopying_references.py b/test/test_deepcopying_references.py
new file mode 100644
index 0000000000000000000000000000000000000000..04ad0996e1c3376ac622f4782977ce6317b84631
--- /dev/null
+++ b/test/test_deepcopying_references.py
@@ -0,0 +1,46 @@
+"""
+Test file to ensure that references between deep copied objects are handled properly
+"""
+
+import pykat
+from copy import deepcopy
+
+kat0 = pykat.finesse.kat()
+
+kat0.parseCommands("m m1 1 0 0 n0 n1")
+
+kat1 = deepcopy(kat0)
+
+assert(kat0 != kat1)
+assert(kat0.__class__ != kat1.__class__)
+
+assert(kat0.m1 != kat1.m1)
+assert(kat0.m1.__class__ != kat1.m1.__class__)
+
+assert(kat0.m1.n0 != kat1.m1.n0)
+assert(kat0.m1.n0.node != kat1.m1.n0.node)
+assert(kat0.nodes.n0 != kat1.nodes.n0)
+
+new = kat1.nodes.createNode("n4")
+
+kat1.nodes.replaceNode(kat1.m1, kat1.m1.n0, new)
+
+assert(not hasattr(kat1.nodes, "n0"))
+assert(hasattr(kat1.nodes, "n4"))
+
+assert(hasattr(kat0.nodes, "n0"))
+assert(not hasattr(kat0.nodes, "n4"))
+
+assert(hasattr(kat1.m1, "n4"))
+assert(not hasattr(kat1.m1, "n0"))
+
+assert(hasattr(kat0.m1, "n0"))
+assert(not hasattr(kat0.m1, "n4"))
+
+assert(kat0.nodes.n0 == kat0.m1.n0.node)
+assert(kat0.nodes.n1 == kat0.m1.n1.node)
+
+assert(kat1.nodes.n4 == kat1.m1.n4.node)
+assert(kat1.nodes.n1 == kat1.m1.n1.node)
+
+print("PASSED")
\ No newline at end of file