diff --git a/bin/test_dump.py b/bin/test_dump.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fdb9ed16e5d11890124ba4a79bf94cf52707e31
--- /dev/null
+++ b/bin/test_dump.py
@@ -0,0 +1,16 @@
+import pykat
+
+kat = pykat.finesse.kat()
+
+kat.parseCommands("""
+bs bs1 0.5 0.5 0 0 n1 dump n3 dump
+""")
+
+print "BEFORE"
+print "".join(kat.generateKatScript())
+
+kat.nodes.replaceNode(kat.bs1, kat.bs1.nodes[3], kat.nodes.createNode("test4"))
+kat.nodes.replaceNode(kat.bs1, kat.bs1.nodes[1], kat.nodes.createNode("test2"))
+
+print "AFTER"
+print "".join(kat.generateKatScript())
diff --git a/bin/test_hom.py b/bin/test_hom.py
new file mode 100644
index 0000000000000000000000000000000000000000..49e51c02f97e220522f5095473160fd19033a557
--- /dev/null
+++ b/bin/test_hom.py
@@ -0,0 +1,16 @@
+import pykat
+
+kat = pykat.finesse.kat()
+
+kat.parseCommands("""
+l l1 1 0 80 n1
+l l2 1 0 90 n4
+
+bs bs1 0.5 0.5 0 0 n1 n2 n3 n4
+
+fsig noise l1 amp 1 0 1
+
+hd hd1 0 n2 n3
+
+xaxis hd1 phase lin 0 360 1000
+""")
\ No newline at end of file
diff --git a/pykat/detectors.py b/pykat/detectors.py
index 8e7ec5add156757190ccff9ae51c2e8fd41cc491..3cb0d8fbe0127ba2a7bf482e512860d8884d2a3f 100644
--- a/pykat/detectors.py
+++ b/pykat/detectors.py
@@ -11,32 +11,52 @@ from pykat.utils import *
 from pykat.gui.graphics import *
 from pykat.node_network import *
 from pykat.param import Param
-
+import collections
 import pykat.exceptions as pkex
 import warnings
 import copy
 
-class Detector(object) :
-    def __init__(self, name, node=None):
+class BaseDetector(object) :
+    
+    def __init__(self, name, nodes=None, max_nodes=1):
+        
         self.__name = name
         self._svgItem = None
         self._kat = None
         self.noplot = False
         self.enabled = True
         self.tag = None
-        self.__node = None
         self._params = []
         self._mask = {}
         self.__scale = None
         self.__removed = False
-        self.__requested_node = None
         
-        if node != None:
-            if node[-1]=='*':
-                self._alternate_beam = True
-                node=node[:-1]
-            
-            self.__requested_node = node
+        self._alternate_beam = []
+        self._nodes = []
+        self._requested_nodes = []
+        
+        if nodes != None:
+            if isinstance(nodes, collections.Iterable):
+                if len(nodes) > max_nodes:
+                    raise pkex.BasePyKatException("Tried to set too many nodes, %s, maximum number is %i." %(str(nodes),max_nodes))
+                    
+                for n in nodes:
+                    if n[-1]=='*':
+                        self._alternate_beam.append(True)
+                        n = n[:-1]
+                    else:
+                        self._alternate_beam.append(False)
+                        
+                    self._requested_nodes.append(n)
+            else:
+                # if we don't have a collection
+                if nodes[-1]=='*':
+                    self._alternate_beam.append(True)
+                    nodes = nodes[:-1]
+                else:
+                    self._alternate_beam.append(False)
+                    
+                self._requested_nodes.append(nodes)
     
     def _register_param(self, param):
         self._params.append(param)
@@ -44,8 +64,9 @@ class Detector(object) :
     def _on_kat_add(self, kat):
         self._kat = kat
         
-        if self.__requested_node != None:
-            self.__node = kat.nodes.createNode(self.__requested_node)
+        for rn in self._requested_nodes:
+            if rn != None:
+                self._nodes.append(kat.nodes.createNode(rn))
     
     def remove(self):
         if self.__removed:
@@ -66,7 +87,6 @@ class Detector(object) :
     def getQGraphicsItem(self):    
         return None
 
-        
     @property
     def removed(self): return self.__removed
     
@@ -75,15 +95,6 @@ class Detector(object) :
     @scale.setter
     def scale(self, value):
         self.__scale = value
-
-    @property 
-    def node(self): return self.__node
-    @node.setter
-    def node(self, value):
-        if value in self._kat.nodes:
-            self.__node = self._kat.nodes[value]
-        else:
-            raise pkex.BasePyKatException("There is no node called " + value)
     
     @property
     def name(self): return self.__name        
@@ -91,19 +102,61 @@ class Detector(object) :
     def __str__(self): return self.name
 
     def mask(self, n, m, factor):
-        id = str(n)+"_"+str(m)
+        _id = str(n)+"_"+str(m)
         
         # if the mask is 1 then remove this so it doesn't get 
         # printed as by default the value is 1.0
-        if id in self._mask and factor == 1.0:
-            del self._mask[id]
+        if _id in self._mask and factor == 1.0:
+            del self._mask[_id]
+                
+        self._mask[_id] = factor
+
+    def _set_node(value, index):
+        if self._kat == None:
+            raise pkex.BasePyKatException("This detector has not been added to a kat object yet")
+        else:
+            if value[-1] == '*':
+                self._alternate_beam[index] = True
+                value = value[:-1]
+            else:
+                self._alternate_beam[index] = False
+                
+            if value in self._kat.nodes:
+                self._nodes[index] = self._kat.nodes[value]
+            else:
+                raise pkex.BasePyKatException("There is no node called " + value + " in the kat object this detector is attached to.")
+    
+class Detector1(BaseDetector):
+    
+    @property 
+    def node(self): return self.__nodes[0]
+    @node.setter
+    def node(self, value):
+        self._set_node(value, 0)      
+        
+                
+class Detector2(BaseDetector):
+    
+    @property 
+    def node1(self): return self.__nodes[0]
+    @node1.setter
+    def node(self, value):
+        self._set_node(value, 0)
+        
+    @property 
+    def node2(self): return self.__nodes[1]
+    @node2.setter
+    def node(self, value):
+        self._set_node(value, 1)
+                
+                
+                
                 
-        self._mask[id] = factor
 
-class ad(Detector):
+class ad(Detector1):
     
     def __init__(self, name, frequency, node_name, mode=None, alternate_beam=False):
-        Detector.__init__(self, name, node_name)
+        BaseDetector.__init__(self, name, node_name)
         self.mode = mode
         self.alternate_beam = alternate_beam
         self.__f = Param("f", self, frequency)
@@ -154,10 +207,10 @@ class ad(Detector):
         
         return rtn
 
-class gouy(Detector):
+class gouy(Detector1):
     
     def __init__(self, name, direction, spaces):
-        Detector.__init__(self, name)
+        BaseDetector.__init__(self, name)
         self.spaces = copy.copy(spaces)
         self.direction = direction
         self.alternate_beam = False
@@ -202,11 +255,11 @@ class gouy(Detector):
 
 
 
-class bp(Detector):
+class bp(Detector1):
     acceptedParameters = ['w', 'w0', 'z', 'zr', 'g', 'r', 'q']
     
     def __init__(self, name, direction, parameter, node, alternate_beam=False):
-        Detector.__init__(self, name, node)
+        BaseDetector.__init__(self, name, node)
         self.parameter = parameter
         self.direction = direction
         self.alternate_beam = alternate_beam
@@ -258,10 +311,10 @@ class bp(Detector):
         return rtn
 
 
-class pd(Detector):
+class pd(Detector1):
 
     def __init__(self, name, num_demods, node_name, senstype=None, alternate_beam=False, pdtype=None, **kwargs):
-        Detector.__init__(self, name, node_name)
+        BaseDetector.__init__(self, name, node_name)
         
         self.__num_demods = num_demods
         self.__senstype = senstype
@@ -451,7 +504,7 @@ class pd(Detector):
             rtn.append("pd{0}{1} {2}{3} {4}{5}".format(senstype, self.num_demods, self.name, fphi_str, self.node.name, alt_str))
 
             if self.scale != None:
-                rtn.append("scale {1} {0:.16g}".format(self.name, self.scale))
+                rtn.append("scale {1} {0}".format(self.name, self.scale))
 
             if self.pdtype != None:
                 rtn.append("pdtype {0} {1}".format(self.name, self.pdtype))
@@ -558,7 +611,7 @@ class qnoised(pd):
             rtn.append("qnoised{5} {0} {1} {2} {3}{4}".format(self.name, self.num_demods, fphi_str, self.node.name, alt_str, senstype))
 
             if self.scale != None:
-                rtn.append("scale {1} {0:.16g}".format(self.name, self.scale))
+                rtn.append("scale {1} {0}".format(self.name, self.scale))
                 
             for p in self._params:
                 rtn.extend(p.getFinesseText())
@@ -651,17 +704,17 @@ class qshot(pd):
             rtn.append("qshot{5} {0} {1} {2} {3}{4}".format(self.name, self.num_demods, fphi_str, self.node.name, alt_str,senstype))
 
             if self.scale != None:
-                rtn.append("scale {1} {0:.16g}".format(self.name, self.scale))
+                rtn.append("scale {1} {0}".format(self.name, self.scale))
                 
             for p in self._params:
                 rtn.extend(p.getFinesseText())
             
         return rtn
         
-def xd(Detector):
+def xd(Detector1):
 
     def __init__(self, name, node_name, component, motion):
-        Detector.__init__(name, None)
+        BaseDetector.__init__(name, None)
         
         self.__motion = motion
         self.__component = component
@@ -688,11 +741,51 @@ def xd(Detector):
             rtn.append("xd {0} {1} {2}".format(self.name, self.component, self.motion))
 
             if self.scale != None:
-                rtn.append("scale {1} {0:.16g}".format(self.name, self.scale))
+                rtn.append("scale {1} {0}".format(self.name, self.scale))
                 
             for p in self._params:
                 rtn.extend(p.getFinesseText())
             
         return rtn
     
-    
\ No newline at end of file
+    
+class hd(Detector2):
+    
+    def __init__(self, name, phase, node1_name, node2_name):
+        BaseDetector.__init__(self, name, (node1_name, node2_name), max_nodes=2)
+    
+        self.__homangle = Param("phase", self, None)
+    
+    @property
+    def phase(self): return self.__phase
+    @phase.setter
+    def phase(self, value): self.__phase.value = value
+    
+    def parseAttributes(self, values):
+        raise pkex.BasePyKatException("hd detector %s has no attributes to set" % self.name)
+    
+    @staticmethod
+    def parseFinesseText(text): 
+        values = text.split()
+        
+        return hd(values[1], float(values[2]), str(values[3]), str(values[4]))
+    
+    def getFinesseText(self):
+        rtn = []
+        
+        if self.enabled:   
+            n1 = self.nodes[0].name
+            n2 = self.nodes[1].name
+            
+            if self.__alternate_beam1[0]: n1 += "*"
+            if self.__alternate_beam2[1]: n2 += "*"
+            
+            rtn.append("hd {0} {1} {2} {3}".format(self.name, self.phase, n1, n2))
+
+            if self.scale != None:
+                rtn.append("scale {1} {0}".format(self.name, self.scale))
+                
+            for p in self._params:
+                rtn.extend(p.getFinesseText())
+            
+        return rtn
\ No newline at end of file
diff --git a/pykat/finesse.py b/pykat/finesse.py
index 82db500ce7f4d94a997a2d202576a743400d097e..dbaabb5cbfdbf93b7b987f2ea4d0a0d2c0fe15dd 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -43,7 +43,7 @@ import re
 from collections import namedtuple, OrderedDict
 
 from pykat.node_network import NodeNetwork
-from pykat.detectors import Detector
+from pykat.detectors import BaseDetector as Detector
 from pykat.components import Component
 from pykat.commands import Command, xaxis
 from pykat.gui.gui import pyKatGUI
@@ -634,6 +634,8 @@ class kat(object):
                         obj = pykat.detectors.qnoised.parseFinesseText(line)
                     elif(first == "xaxis" or first == "xaxis*"):
                         obj = pykat.commands.xaxis.parseFinesseText(line)
+                    elif(first[0:2] == "hd"):
+                        obj = pykat.detectors.hd.parseFinesseText(line)
                     elif(first == "x2axis" or first == "x2axis*"):
                         obj = pykat.commands.x2axis.parseFinesseText(line)
                     elif(first == "gauss" or first == "gauss*" or first == "gauss**"):
@@ -1415,7 +1417,7 @@ class kat(object):
     def __del_detector(self, det):
 
         if not isinstance(det, Detector):
-            raise exceptions.ValueError("Argument is not of type Detector")
+            raise pkex.BasePyKatException("Argument is not of type Detector")
         
         name = det.name
         
@@ -1428,7 +1430,7 @@ class kat(object):
     def __add_command(self, com):
 
         if not isinstance(com, Command):
-            raise exceptions.ValueError("Argument is not of type Command")
+            raise pkex.BasePyKatException("Argument is not of type Command")
         
         name = com.__class__.__name__
         fget = lambda self: self.__get_command(name)
@@ -1454,7 +1456,7 @@ class kat(object):
     def __add_component(self, comp):
 
         if not isinstance(comp, Component):
-            raise exceptions.ValueError("Argument is not of type Component")
+            raise pkex.BasePyKatException("Argument is not of type Component")
             
         fget = lambda self: self.__get_component(comp.name)
         
@@ -1464,7 +1466,7 @@ class kat(object):
     def __del_component(self, comp):
 
         if not isinstance(comp, Component):
-            raise exceptions.ValueError("Argument is not of type Component")
+            raise pkex.BasePyKatException("Argument is not of type Component")
         
         delattr(self.__class__, comp.name)
         delattr(self, '__comp_' + comp.name)
diff --git a/pykat/gui/gui.py b/pykat/gui/gui.py
index fe11ba34b9c44bfc0c1eb0f213ca8bc31438a844..bef360d9953a22f6ecd454f56771ef1c70805f46 100644
--- a/pykat/gui/gui.py
+++ b/pykat/gui/gui.py
@@ -6,7 +6,7 @@ Created on Tue Jan 29 11:35:48 2013
 """
 
 from pykat.components import Component, space
-from pykat.detectors import Detector
+from pykat.detectors import BaseDetector as Detector
 
 from PyQt4 import QtGui, QtCore
 from PyQt4.Qt import *
diff --git a/pykat/node_network.py b/pykat/node_network.py
index fa9f282c0f99f0cf4b641aeaa8f6260084fb5663..81f7189b0d3a4c866e7563db98f126f16f2b7762 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -8,7 +8,7 @@ import exceptions
 import pykat.gui.graphics
 import pykat.exceptions as pkex
 from pykat.components import Component
-from pykat.detectors import Detector
+from pykat.detectors import BaseDetector as Detector
 from pykat.utilities.optics.gaussian_beams import beam_param
 
 class NodeNetwork(object):
@@ -34,7 +34,7 @@ class NodeNetwork(object):
         , e.g. connected, disconnected, name change, etc.
         """
         if not isinstance(comp, Component):
-            raise exceptions.ValueError("comp argument is not of type Component")
+            raise pkex.BasePyKatException("comp argument is not of type Component")
         
         if comp.id in self.__componentNodes:
             raise pkex.BasePyKatException("Component has already been registered")
@@ -86,6 +86,7 @@ class NodeNetwork(object):
         self.__componentCallback[comp.id]()
             
     def connectNodeToComp(self, node, comp, do_callback=True):
+
         if node.id in self.__nodeComponents:
             comps = self.__nodeComponents[node.id]
         else:
@@ -109,7 +110,7 @@ class NodeNetwork(object):
         
     def createNode(self, node_name):
         if node_name == 'dump':
-            return DumpNode()
+            return DumpNode(self)
             
         if node_name in self.__nodes:
             # then this node already exists
@@ -142,23 +143,24 @@ class NodeNetwork(object):
         
     def removeNode(self, node):
         
-        if not isinstance(node,Node):
-            raise exceptions.ValueError("node argument is not of type Node")
+        if not isinstance(node, Node):
+            raise pkex.BasePyKatException("node argument is not of type Node")
         
-        if node.name not in self.__nodes:
-            raise exceptions.RuntimeError("Trying to remove node {0} when it has not been added".format(node.name))
+        if not isinstance(node, DumpNode) and node.name not in self.__nodes:
+            raise pkex.BasePyKatException("Trying to remove node {0} when it has not been added".format(node.name))
         
         C = self.getNodeComponents(node)
         
         if C[0] is not None or C[1] is not None:
-            raise exceptions.RuntimeError("Cannot remove a node which is attached to components still")
+            raise pkex.BasePyKatException("Cannot remove a node which is attached to components still")
             
         if len(node.getDetectors()) > 0:
-            raise exceptions.RuntimeError("Cannot remove a node which is attached to detectors still")
+            raise pkex.BasePyKatException("Cannot remove a node which is attached to detectors still")
         
-        self.__remove_node_attr(node)
-        del self.__nodes[node.name] 
-        del self.__nodeComponents[node.id]
+        if not isinstance(node, DumpNode):
+            self.__remove_node_attr(node)
+            del self.__nodes[node.name] 
+            del self.__nodeComponents[node.id]
         
     def hasNode(self, name):
         return (name in self.__nodes)
@@ -206,7 +208,7 @@ class NodeNetwork(object):
     def __add_node_attr(self, node):
 
         if not isinstance(node, Node):
-            raise exceptions.ValueError("Argument is not of type Node")
+            raise pkex.BasePyKatException("Argument is not of type Node")
         
         name = node.name
         fget = lambda self: self.__get_node_attr(name)
@@ -216,7 +218,7 @@ class NodeNetwork(object):
     
     def __remove_node_attr(self, node):
         if not isinstance(node, Node):
-            raise exceptions.ValueError("Argument is not of type Node")
+            raise pkex.BasePyKatException("Argument is not of type Node")
         
         name = node.name
         delattr(self, '__node_' + name)
@@ -265,7 +267,7 @@ class NodeNetwork(object):
                 rn = currcomp.nodes[2]
                 tn = currcomp.nodes[1]
             else:
-                raise exceptions.ValueError("Node not attached in path find to BS")
+                raise pkex.BasePyKatException("Node not attached in path find to BS")
             
             nextcomp = None
             
@@ -513,9 +515,9 @@ class Node(object):
 class DumpNode(Node):
     __total_dump_node_id = 0
     
-    def __init__(self):
+    def __init__(self, network):
         DumpNode.__total_dump_node_id -= 1
-        Node.__init__(self, 'dump', None, DumpNode.__total_dump_node_id)
+        Node.__init__(self, 'dump', network, DumpNode.__total_dump_node_id)
         self._isDump = True