diff --git a/Source/Processors/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph.cpp
index c0c64686e30eaa58021b9ad2ccc2d870cf6a7ec5..bcd2a84a15be248335bf223654360f422c958a05 100644
--- a/Source/Processors/ProcessorGraph.cpp
+++ b/Source/Processors/ProcessorGraph.cpp
@@ -123,12 +123,12 @@ void ProcessorGraph::updatePointers()
     getRecordNode()->setUIComponent(getUIComponent());
 }
 
-void* ProcessorGraph::createNewProcessor(String& description)
+void* ProcessorGraph::createNewProcessor(String& description, int id)
 {
 
     GenericProcessor* processor = createProcessorFromDescription(description);
 
-    int id = currentNodeId++;
+    //int id = currentNodeId++;
 
     if (processor != 0)
     {
@@ -182,6 +182,12 @@ void ProcessorGraph::clearSignalChain()
 void ProcessorGraph::changeListenerCallback(ChangeBroadcaster* source)
 {
 
+   refreshColors();
+
+}
+
+void ProcessorGraph::refreshColors()
+{
     for (int i = 0; i < getNumNodes(); i++)
     {
         Node* node = getNode(i);
@@ -198,7 +204,6 @@ void ProcessorGraph::changeListenerCallback(ChangeBroadcaster* source)
             e->refreshColors();
         }
     }
-
 }
 
 void ProcessorGraph::restoreParameters()
diff --git a/Source/Processors/ProcessorGraph.h b/Source/Processors/ProcessorGraph.h
index ef0ae08e9589ff69b0ecd90e3e8e702e09fa51b7..3ea84eb4d132d6c57baeb2d686c0f955b98fd2fe 100644
--- a/Source/Processors/ProcessorGraph.h
+++ b/Source/Processors/ProcessorGraph.h
@@ -57,7 +57,7 @@ public:
     ProcessorGraph();
     ~ProcessorGraph();
 
-    void* createNewProcessor(String& description);
+    void* createNewProcessor(String& description, int id);
     GenericProcessor* createProcessorFromDescription(String& description);
 
     void removeProcessor(GenericProcessor* processor);
@@ -85,6 +85,8 @@ public:
 
     Array<GenericProcessor*> getListOfProcessors();
 
+    void refreshColors();
+
 private:
 
     int currentNodeId;
diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp
index ab24b75bd762842a73e75c359981e44a2fb8649f..ea774886ff3bbd3b867731588522550dc803e376 100755
--- a/Source/UI/EditorViewport.cpp
+++ b/Source/UI/EditorViewport.cpp
@@ -67,6 +67,9 @@ EditorViewport::EditorViewport()
     addAndMakeVisible(rightButton);
     addAndMakeVisible(leftButton);
 
+    currentId = 100;
+    maxId = 100;
+
 }
 
 EditorViewport::~EditorViewport()
@@ -113,14 +116,14 @@ void EditorViewport::paint(Graphics& g)
         float insertionX = (float)(borderSize) * 2.5 + (float) tabSize;
 
         int n;
-        for (n = 0; n < insertionPoint; n++)
+        for (n = leftmostEditor; n < insertionPoint; n++)
         {
             insertionX += editorArray[n]->getWidth();
 
         }
 
-        if (n > 1)
-            insertionX += borderSize*(n-1);
+        if (n - leftmostEditor > 1)
+            insertionX += borderSize*(n-leftmostEditor-1);
 
         g.setColour(Colours::yellow);
         g.drawLine(insertionX, (float) borderSize,
@@ -131,13 +134,18 @@ void EditorViewport::paint(Graphics& g)
     int insertionX = tabSize + borderSize;
     g.setColour(Colours::darkgrey);
 
-    int x = insertionX + 19;
+    int x = insertionX + 15;
     int y = borderSize + 2;
     //int w = 30;
     //int h = getHeight() - 2*(borderSize+2);
 
-    g.drawImageAt(sourceDropImage, x, y);
-
+    if (editorArray.size() > 0)
+    {
+        if (!editorArray[0]->getProcessor()->isSource())
+            g.drawImageAt(sourceDropImage, x, y);
+    } else {
+        g.drawImageAt(sourceDropImage, x, y);
+    }
 }
 
 bool EditorViewport::isInterestedInDragSource(const SourceDetails& dragSourceDetails)
@@ -180,7 +188,7 @@ void EditorViewport::itemDragMove(const SourceDetails& dragSourceDetails)
         int leftEdge;
         int centerPoint;
 
-        for (int n = 0; n < editorArray.size(); n++)
+        for (int n = leftmostEditor; n < editorArray.size(); n++)
         {
             leftEdge = editorArray[n]->getX();
             centerPoint = leftEdge + (editorArray[n]->getWidth())/2;
@@ -230,7 +238,7 @@ void EditorViewport::itemDropped(const SourceDetails& dragSourceDetails)
         /// needed to remove const cast --> should be a better way to do this
         //String description = sourceDescription.substring(0);
 
-        GenericEditor* activeEditor = (GenericEditor*) getProcessorGraph()->createNewProcessor(description);//, source, dest);
+        GenericEditor* activeEditor = (GenericEditor*) getProcessorGraph()->createNewProcessor(description, currentId);//, source, dest);
 
         std::cout << "Active editor: " << activeEditor << std::endl;
 
@@ -263,6 +271,9 @@ void EditorViewport::itemDropped(const SourceDetails& dragSourceDetails)
         getGraphViewer()->addNode(activeEditor);
 
         repaint();
+
+        currentId++;
+
     }
 }
 
@@ -307,6 +318,18 @@ void EditorViewport::makeEditorVisible(GenericEditor* editor, bool highlight, bo
     if (highlight)
         editor->highlight();
 
+    while (!editor->isVisible())
+    {
+        if (leftmostEditor < editorArray.indexOf(editor))
+            leftmostEditor++;
+        else
+            leftmostEditor--;
+
+        refreshEditors();
+    }
+
+    repaint();
+
 }
 
 void EditorViewport::deleteNode(GenericEditor* editor)
@@ -331,6 +354,8 @@ void EditorViewport::deleteNode(GenericEditor* editor)
         
         
 
+        repaint();
+
     }
 }
 
@@ -654,13 +679,31 @@ void EditorViewport::mouseDown(const MouseEvent& e)
     for (int i = 0; i < editorArray.size(); i++)
     {
 
-        if (e.eventComponent == editorArray[i] && e.y < 22)
-            // event must take place along title bar
+        if (e.eventComponent == editorArray[i])
+           
             // || e.eventComponent->getParentComponent() == editorArray[i] ||
             //    e.eventComponent->getParentComponent()->getParentComponent() ==
             //            editorArray[i])
         {
 
+            if (e.getNumberOfClicks() == 2) // double-clicks toggle collapse state
+            {
+                if (editorArray[i]->getCollapsedState())
+                {
+                    editorArray[i]->switchCollapsedState();
+                } else {
+                    if (e.y < 22)
+                    {
+                        editorArray[i]->switchCollapsedState();
+                    }
+                }
+                return;
+            }
+
+            // make sure uncollapsed editors don't accept clicks outside their title bar
+            if (!editorArray[i]->getCollapsedState() && e.y > 22)
+                return;
+
             clickInEditor = true;
             editorArray[i]->select();
 
@@ -1131,9 +1174,12 @@ const String EditorViewport::saveState(File fileToUse)
     int saveOrder = 0;
 
     XmlElement* xml = new XmlElement("SETTINGS");
-
+	
     XmlElement* info = xml->createNewChildElement("INFO");
 
+    XmlElement* version = info->createNewChildElement("VERSION");
+    version->addTextElement("0.1");
+
     Time currentTime = Time::getCurrentTime();
 
     XmlElement* date = info->createNewChildElement("DATE");
@@ -1195,7 +1241,7 @@ const String EditorViewport::saveState(File fileToUse)
 
                 editor = (GenericEditor*) nextProcessor->getEditor();
 
-                if ((nextProcessor->isSplitter() || nextProcessor->isMerger())
+                if ((nextProcessor->isSplitter())// || nextProcessor->isMerger())
                     && nextProcessor->saveOrder < 0)
                 {
                     splitPoints.add(nextProcessor);
@@ -1261,6 +1307,7 @@ const String EditorViewport::saveState(File fileToUse)
     }
 
     getControlPanel()->saveStateToXml(xml); // save the control panel settings
+    getProcessorList()->saveStateToXml(xml);
     getUIComponent()->saveStateToXml(xml);  // save the UI settings
 
     if (! xml->writeToFile(currentFile, String::empty))
@@ -1291,7 +1338,7 @@ const String EditorViewport::loadState(File fileToLoad)
     // {
     //     return "No configuration selected.";
     // }
-
+	int maxID=100;
     currentFile = fileToLoad;
 
     std::cout << "Loading processor graph." << std::endl;
@@ -1308,6 +1355,34 @@ const String EditorViewport::loadState(File fileToLoad)
         return "Not a valid file.";
     }
 
+	bool olderVersionFound = true;
+	forEachXmlChildElement(*xml, element)
+    {
+		  if (element->hasTagName("INFO"))
+		  {
+			  forEachXmlChildElement(*element, element2)
+			  {
+			   if (element2->hasTagName("VERSION")) 
+			   {
+				   String S= element2->getAllSubText();
+				   double version =S.getDoubleValue();
+				   if (version >= 0.1)
+					   olderVersionFound = false;
+			   }
+			  }
+			  break;
+		  }
+	}
+	if (olderVersionFound)
+	{
+		    bool response = AlertWindow::showOkCancelBox (AlertWindow::NoIcon,
+                                   "Old configuration file.",
+                                    "File may not load properly since it could lack some fields. Continute?",
+                                     "Yes", "No", 0, 0);
+        if (!response)
+			return "Failed To Open " + fileToLoad.getFileName();
+  
+	}
     clearSignalChain();
 
     String description;// = " ";
@@ -1328,6 +1403,9 @@ const String EditorViewport::loadState(File fileToLoad)
             {
 
                 int insertionPt = processor->getIntAttribute("insertionPoint");
+                currentId = processor->getIntAttribute("NodeId");
+
+				maxID= (maxID > currentId) ? maxID  : currentId ;
 
                 if (insertionPt == 1)
                 {
@@ -1348,6 +1426,7 @@ const String EditorViewport::loadState(File fileToLoad)
                 p = (GenericProcessor*) lastEditor->getProcessor();
                 p->loadOrder = loadOrder;
                 p->parametersAsXml = processor;
+
                 //Sets parameters based on XML files
                 setParametersByXML(p, processor);
                 loadOrder++;
@@ -1357,6 +1436,8 @@ const String EditorViewport::loadState(File fileToLoad)
                     splitPoints.add(p);
                 }
 
+                signalChainManager->updateVisibleEditors(editorArray[0], 0, 0, UPDATE);
+
             }
             else if (processor->hasTagName("SWITCH"))
             {
@@ -1390,6 +1471,8 @@ const String EditorViewport::loadState(File fileToLoad)
                     }
                 }
 
+                signalChainManager->updateVisibleEditors(editorArray[0], 0, 0, UPDATE);
+
             }
 
         }
@@ -1411,6 +1494,7 @@ const String EditorViewport::loadState(File fileToLoad)
     getProcessorGraph()->restoreParameters();
 
     getControlPanel()->loadStateFromXml(xml); // save the control panel settings
+    getProcessorList()->loadStateFromXml(xml);
     getUIComponent()->loadStateFromXml(xml);  // save the UI settings
 
     if (editorArray.size() > 0)
@@ -1418,10 +1502,16 @@ const String EditorViewport::loadState(File fileToLoad)
 
     refreshEditors();
 
+    getProcessorGraph()->restoreParameters();
+
+
     String error = "Opened ";
     error += currentFile.getFileName();
 
     delete xml;
+
+	currentId=maxID+1; // make sure future processors don't have overlapping id numbers
+
     return error;
 }
 /* Set parameters based on XML.*/
diff --git a/Source/UI/EditorViewport.h b/Source/UI/EditorViewport.h
index c47d94395d0582fed8052f31877bd53f03b53811..242befc7d567b5f9ddfde92e83677cdfe7c5ed42 100755
--- a/Source/UI/EditorViewport.h
+++ b/Source/UI/EditorViewport.h
@@ -210,6 +210,9 @@ private:
 
     void resized();
 
+    int currentId;
+    int maxId;
+
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EditorViewport);
 
 };
@@ -247,7 +250,7 @@ public:
     /** Returns the editor associated with this SignalChainTabButton.*/
     GenericEditor* getEditor()
     {
-        return firstEditor;
+         return firstEditor;
     }
 
     /** Sets the number of this SignalChainTabButton.*/
diff --git a/Source/UI/ProcessorList.cpp b/Source/UI/ProcessorList.cpp
index e3c9dd9c8727d13a75efcf4d97a064459a2a119d..c60b9f319e24ee04d104b544e945d7a04b58be79 100755
--- a/Source/UI/ProcessorList.cpp
+++ b/Source/UI/ProcessorList.cpp
@@ -56,22 +56,26 @@ ProcessorList::ProcessorList()
     //sources->addSubItem(new ProcessorListItem("Custom FPGA"));
     sources->addSubItem(new ProcessorListItem("Rhythm FPGA"));
     sources->addSubItem(new ProcessorListItem("File Reader"));
+	//sources->addSubItem(new ProcessorListItem("Network Events"));
     sources->addSubItem(new ProcessorListItem("Serial Port"));
     //sources->addSubItem(new ProcessorListItem("Event Generator"));
 
     ProcessorListItem* filters = new ProcessorListItem("Filters");
     filters->addSubItem(new ProcessorListItem("Bandpass Filter"));
-    //filters->addSubItem(new ProcessorListItem("Event Detector"));
     filters->addSubItem(new ProcessorListItem("Spike Detector"));
     //filters->addSubItem(new ProcessorListItem("Resampler"));
     filters->addSubItem(new ProcessorListItem("Phase Detector"));
     //filters->addSubItem(new ProcessorListItem("Digital Ref"));
     filters->addSubItem(new ProcessorListItem("Channel Map"));
+	//filters->addSubItem(new ProcessorListItem("Eye Tracking"));
+
 
     ProcessorListItem* sinks = new ProcessorListItem("Sinks");
     sinks->addSubItem(new ProcessorListItem("LFP Viewer"));
     //sinks->addSubItem(new ProcessorListItem("LFP Trig. Avg."));
     sinks->addSubItem(new ProcessorListItem("Spike Viewer"));
+	//sinks->addSubItem(new ProcessorListItem("PSTH"));
+	//sinks->addSubItem(new ProcessorListItem("Network Sink"));
     //sinks->addSubItem(new ProcessorListItem("WiFi Output"));
     //sinks->addSubItem(new ProcessorListItem("Arduino Output"));
     // sinks->addSubItem(new ProcessorListItem("FPGA Output"));
@@ -81,6 +85,7 @@ ProcessorList::ProcessorList()
     utilities->addSubItem(new ProcessorListItem("Splitter"));
     utilities->addSubItem(new ProcessorListItem("Merger"));
     utilities->addSubItem(new ProcessorListItem("Record Control"));
+    //utilities->addSubItem(new ProcessorListItem("Advancers"));
 
     baseItem = new ProcessorListItem("Processors");
     baseItem->addSubItem(sources);
@@ -113,12 +118,14 @@ ProcessorList::~ProcessorList()
 
 }
 
+
+
 bool ProcessorList::isOpen()
 {
     return baseItem->isOpen();
 }
 
-void ProcessorList::paintCanvas(Graphics& g)
+void ProcessorList::paint(Graphics& g)
 {
 
     drawItems(g);
@@ -269,7 +276,7 @@ void ProcessorList::clearSelectionState()
 
 ProcessorListItem* ProcessorList::getListItemForYPos(int y)
 {
-    int bottom = (yBuffer + itemHeight) - getScrollAmount();
+    int bottom = (yBuffer + itemHeight); // - getScrollAmount();
 
     //std::cout << "Bottom: " << bottom << std::endl;
     //std::cout << "Y coordinate: " << y << std::endl;
@@ -350,7 +357,7 @@ void ProcessorList::toggleState()
     repaint();
 }
 
-void ProcessorList::mouseDownInCanvas(const MouseEvent& e)
+void ProcessorList::mouseDown(const MouseEvent& e)
 {
 
     isDragging = false;
@@ -361,15 +368,15 @@ void ProcessorList::mouseDownInCanvas(const MouseEvent& e)
 
     //std::cout << xcoord << " " << ycoord << std::endl;
 
-    ProcessorListItem* fli = getListItemForYPos(ycoord);
+    ProcessorListItem* listItem = getListItemForYPos(ycoord);
 
-    if (fli != 0)
+    if (listItem != 0)
     {
         //std::cout << "Selecting: " << fli->getName() << std::endl;
-        if (!fli->hasSubItems())
+        if (!listItem->hasSubItems())
         {
             clearSelectionState();
-            fli->setSelected(true);
+            listItem->setSelected(true);
         }
 
     }
@@ -378,26 +385,26 @@ void ProcessorList::mouseDownInCanvas(const MouseEvent& e)
         //std::cout << "No selection." << std::endl;
     }
 
-    if (fli != 0)
+    if (listItem != 0)
     {
-        if (xcoord < getWidth() - getScrollBarWidth())
+        if (xcoord < getWidth())
         {
             if (e.mods.isRightButtonDown() || e.mods.isCtrlDown())
             {
 
-                if (fli->getName().equalsIgnoreCase("Sources"))
+                if (listItem->getName().equalsIgnoreCase("Sources"))
                 {
                     currentColor = SOURCE_COLOR;
                 }
-                else if (fli->getName().equalsIgnoreCase("Filters"))
+                else if (listItem->getName().equalsIgnoreCase("Filters"))
                 {
                     currentColor = FILTER_COLOR;
                 }
-                else if (fli->getName().equalsIgnoreCase("Utilities"))
+                else if (listItem->getName().equalsIgnoreCase("Utilities"))
                 {
                     currentColor = UTILITY_COLOR;
                 }
-                else if (fli->getName().equalsIgnoreCase("Sinks"))
+                else if (listItem->getName().equalsIgnoreCase("Sinks"))
                 {
                     currentColor = SINK_COLOR;
                 }
@@ -420,7 +427,7 @@ void ProcessorList::mouseDownInCanvas(const MouseEvent& e)
                 colourSelector.setColour(ColourSelector::backgroundColourId, Colours::transparentBlack);
                 colourSelector.setSize(300, 275);
 
-                Rectangle<int> rect = Rectangle<int>(0,0,10,10);
+                juce::Rectangle<int> rect = juce::Rectangle<int>(0,0,10,10);
 
                 CallOutBox callOut(colourSelector, rect, nullptr);
                 callOut.setTopLeftPosition(e.getScreenX(), e.getScreenY());
@@ -431,13 +438,13 @@ void ProcessorList::mouseDownInCanvas(const MouseEvent& e)
             }
             else
             {
-                fli->reverseOpenState();
+                listItem->reverseOpenState();
             }
         }
 
-        if (fli == baseItem)
+        if (listItem == baseItem)
         {
-            if (fli->isOpen())
+            if (listItem->isOpen())
             {
                 getUIComponent()->childComponentChanged();
             }
@@ -463,24 +470,24 @@ void ProcessorList::changeListenerCallback(ChangeBroadcaster* source)
 
 }
 
-void ProcessorList::mouseDragInCanvas(const MouseEvent& e)
+void ProcessorList::mouseDrag(const MouseEvent& e)
 {
 
-    if (e.getMouseDownX() < getWidth()-getScrollBarWidth() && !(isDragging))
+    if (e.getMouseDownX() < getWidth() && !(isDragging))
     {
 
-        ProcessorListItem* fli = getListItemForYPos(e.getMouseDownY());
+        ProcessorListItem* listItem = getListItemForYPos(e.getMouseDownY());
 
-        if (fli != 0)
+        if (listItem != 0)
         {
 
-            if (!fli->hasSubItems())
+            if (!listItem->hasSubItems())
             {
                 isDragging = true;
 
-                String b = fli->getParentName();
+                String b = listItem->getParentName();
                 b += "/";
-                b += fli->getName();
+                b += listItem->getName();
 
                 const String dragDescription = b;
 
@@ -498,11 +505,11 @@ void ProcessorList::mouseDragInCanvas(const MouseEvent& e)
                         Image dragImage(Image::ARGB, 100, 15, true);
 
                         Graphics g(dragImage);
-                        g.setColour(findColour(fli->colorId));
+                        g.setColour(findColour(listItem->colorId));
                         g.fillAll();
                         g.setColour(Colours::white);
                         g.setFont(14);
-                        g.drawSingleLineText(fli->getName(),10,12);//,75,15,Justification::centredRight,true);
+                        g.drawSingleLineText(listItem->getName(),10,12);//,75,15,Justification::centredRight,true);
 
                         dragImage.multiplyAllAlphas(0.6f);
 
@@ -517,6 +524,113 @@ void ProcessorList::mouseDragInCanvas(const MouseEvent& e)
 
 }
 
+void ProcessorList::saveStateToXml(XmlElement* xml)
+{
+    XmlElement* processorListState = xml->createNewChildElement("PROCESSORLIST");
+
+    for (int i = 0; i < 5; i++)
+    {
+        XmlElement* colorState = processorListState->createNewChildElement("COLOR");
+
+        int id;
+
+        switch (i)
+        {
+            case 0:
+                id = PROCESSOR_COLOR;
+                break;
+            case 1:
+                id = SOURCE_COLOR;
+                break;
+            case 2:
+                id = FILTER_COLOR;
+                break;
+            case 3:
+                id = SINK_COLOR;
+                break;
+            case 4:
+                id = UTILITY_COLOR;
+                break;
+            default:
+                // do nothing
+            ;
+        }
+
+        Colour c = findColour(id);
+
+        colorState->setAttribute("ID", (int) id);
+        colorState->setAttribute("R", (int) c.getRed());
+        colorState->setAttribute("G", (int) c.getGreen());
+        colorState->setAttribute("B", (int) c.getBlue());
+
+    }
+}
+
+void ProcessorList::loadStateFromXml(XmlElement* xml)
+{
+    forEachXmlChildElement(*xml, xmlNode)
+    {
+        if (xmlNode->hasTagName("PROCESSORLIST"))
+        {
+            forEachXmlChildElement(*xmlNode, colorNode)
+            {
+                setColour(colorNode->getIntAttribute("ID"), 
+                          Colour(
+                            colorNode->getIntAttribute("R"),
+                            colorNode->getIntAttribute("G"),
+                            colorNode->getIntAttribute("B")));
+            }
+        }
+    }
+
+    repaint();
+
+    getProcessorGraph()->refreshColors();
+}
+
+Array<Colour> ProcessorList::getColours()
+{
+    Array<Colour> c;
+
+    c.add(findColour(PROCESSOR_COLOR));
+    c.add(findColour(SOURCE_COLOR));
+    c.add(findColour(FILTER_COLOR));
+    c.add(findColour(SINK_COLOR));
+    c.add(findColour(UTILITY_COLOR));
+	return c;
+}
+
+void ProcessorList::setColours(Array<Colour> c)
+{
+    for (int i = 0; i < c.size(); i++)
+    {
+        switch (i)
+        {
+            case 0:
+                setColour(PROCESSOR_COLOR, c[i]);
+                break;
+            case 1:
+                setColour(SOURCE_COLOR, c[i]);
+                break;
+            case 2:
+                setColour(FILTER_COLOR, c[i]);
+                break;
+            case 3:
+                setColour(SINK_COLOR, c[i]);
+                break;
+            case 4:
+                setColour(UTILITY_COLOR, c[i]);
+                break;
+            default:
+                ;// do nothing
+        }
+    }
+
+    
+}
+
+// ===================================================================
+
 ProcessorListItem::ProcessorListItem(const String& name_)
     : selected(false), open(true), name(name_)
 {
@@ -609,6 +723,7 @@ void ProcessorListItem::setParentName(const String& name)
     }
 }
 
+
 // Blue slate:
 // if (parentName.equalsIgnoreCase("Processors"))
 // {
diff --git a/Source/UI/ProcessorList.h b/Source/UI/ProcessorList.h
index c19f47f36c183a26554ad135a83821f98732ee49..9873a0eb8dd43a1fcb9694ae4ba72bda6c142e3d 100755
--- a/Source/UI/ProcessorList.h
+++ b/Source/UI/ProcessorList.h
@@ -25,7 +25,6 @@
 #define __PROCESSORLIST_H_C3A661E9__
 
 #include "../../JuceLibraryCode/JuceHeader.h"
-#include "../Processors/Visualization/OpenGLCanvas.h"
 #include "../AccessClass.h"
 
 class ProcessorListItem;
@@ -48,7 +47,7 @@ class UIComponent;
 
 */
 
-class ProcessorList : public OpenGLCanvas,
+class ProcessorList : public Component,
     public DragAndDropContainer,
     public AccessClass,
     public ChangeListener
@@ -68,10 +67,22 @@ public:
     /** Returns the open/closed state of the ProcessorList.*/
     bool isOpen();
 
-private:
+    /** Draws the ProcessorList. */
+    void paint(Graphics& g);
+
+    /** Gets the colors of the different types of processors.*/
+    Array<Colour> getColours();
+
+    /** Sets the colors of the different types of processors.*/
+    void setColours(Array<Colour>);
 
-    /** Renders the canvas. */
-    void paintCanvas(Graphics& g);
+    /** Saves the ProcessorList state. */
+    void saveStateToXml(XmlElement*);
+
+    /** Loads the ProcessorList state. */
+    void loadStateFromXml(XmlElement*);
+
+private:
 
     /** The main method for drawing the ProcessorList.*/
     void drawItems(Graphics& g);
@@ -88,13 +99,13 @@ private:
     /** Returns the ProcessorListItem that sits at a given y coordinate.*/
     ProcessorListItem* getListItemForYPos(int y);
 
-    /** Sets the appropriate OpenGL viewport for drawing.*/
+    /** Sets the appropriate viewport for drawing.*/
     void setViewport(Graphics& g, bool);
 
     int currentColor;
 
     /** Returns the height requested by the ProcessorList. Determines whether or not
-    the OpenGLCanvas needs to draw scroll bars.*/
+    to draw scroll bars.*/
     int getTotalHeight();
 
     /** Deselects all items within the ProcessorList.*/
@@ -107,10 +118,10 @@ private:
     String category;
 
     /** Called when a mouse click begins within the boundaries of the ProcessorList.*/
-    void mouseDownInCanvas(const MouseEvent& e);
+    void mouseDown(const MouseEvent& e);
 
     /** Called when a mouse drag occurs within the boundaries of the ProcessorList.*/
-    void mouseDragInCanvas(const MouseEvent& e);
+    void mouseDrag(const MouseEvent& e);
 
     /** The base item in the list.*/
     ScopedPointer<ProcessorListItem> baseItem;
diff --git a/Source/UI/SignalChainManager.cpp b/Source/UI/SignalChainManager.cpp
index e4d9d063b8ca38f03d438e150b632e8b43a03eba..6f2af4e25dde3df75db89d629a866dc4e3b5d4ab 100755
--- a/Source/UI/SignalChainManager.cpp
+++ b/Source/UI/SignalChainManager.cpp
@@ -187,25 +187,38 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         std::cout << "    Removing editor." << std::endl;
 
         GenericProcessor* p = (GenericProcessor*) editorArray[index]->getProcessor();
+        
+       // GenericProcessor* source = p->getSourceNode();
+        if (p->getSourceNode() != nullptr)
+			if (p->getSourceNode()->isSplitter())
+				p->getSourceNode()->setSplitterDestNode(nullptr);
 
         // if the processor to be removed is a merger,
         // we need to inform the other source that its merger has disappeared
         if (p->isMerger())
         {
             p->switchIO();
-            if (p->getSourceNode() != 0)
-                p->getSourceNode()->setDestNode(0);
+            if (p->getSourceNode() != nullptr)
+                p->getSourceNode()->setDestNode(nullptr);
         }
 
         // if the processor to be removed is a splitter, we need to make sure 
         // there aren't any orphaned processors
         if (p->isSplitter())
         {
-            p->switchIO();
-            if (p->getDestNode() != 0)
+            p->switchIO(0);
+            if (p->getDestNode() != nullptr)
             {
                 std::cout << "Found an orphaned signal chain" << std::endl;
-                p->getDestNode()->setSourceNode(0);
+                p->getDestNode()->setSourceNode(nullptr);
+                createNewTab(p->getDestNode()->getEditor());
+            }
+
+            p->switchIO(1);
+            if (p->getDestNode() != nullptr)
+            {
+                std::cout << "Found an orphaned signal chain" << std::endl;
+                p->getDestNode()->setSourceNode(nullptr);
                 createNewTab(p->getDestNode()->getEditor());
             }
         }
@@ -220,12 +233,17 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
 
         if (editorArray.size() > 0)
         {
-            GenericProcessor* p = (GenericProcessor*) editorArray[0]->getProcessor();
-            merger = (p->isMerger() && p->stillHasSource());
+            // take the next processor in the array
+            GenericProcessor* p2 = (GenericProcessor*) editorArray[0]->getProcessor();
+            merger = (p2->isMerger() && p2->stillHasSource());
             if (merger)
             {
                 std::cout << "We've got a merger!" << std::endl;
-                //p->switchSource();
+                //p2->switchIO(0);
+                p2->setMergerSourceNode(p->getSourceNode());
+                MergerEditor* me = (MergerEditor*) editorArray[0];
+                me->switchSource();
+               // p2->setMergerSourceNode(nullptr);
             }
         }
 
@@ -358,22 +376,21 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         GenericProcessor* currentProcessor = (GenericProcessor*) editorToAdd->getProcessor();
         GenericProcessor* source = currentProcessor->getSourceNode();
 
-        if (source != 0)
+        if (source != nullptr)
         {
             std::cout << "Source: " << source->getName() << std::endl;
 
             // need to switch the splitter somehow
-            // if (action == ACTIVATE || action == UPDATE)
-            // {
-            //  if (source->isSplitter())
-            //  {
-            //      source->setPathToProcessor(currentProcessor);
-            //  }
-            // }
+            if (action == ACTIVATE || action == UPDATE)
+            {
+             if (source->isSplitter())
+             {
+                 source->setPathToProcessor(currentProcessor);
+             }
+            }
 
             editorToAdd = (GenericEditor*) source->getEditor();
 
-
         }
         else
         {
@@ -406,8 +423,10 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
             {
                 std::cout << "It's a merger!" << std::endl;
 
+                editorToAdd->switchIO(0);
+
                 if (dest->getSourceNode() != currentProcessor)
-                    editorToAdd->switchSource();
+                    editorToAdd->switchIO(1);
 
             }
 
@@ -499,25 +518,27 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
             GenericEditor* source = signalChainArray[n]->getEditor();
             GenericProcessor* p = source->getProcessor();
 
-            p->update();
-
-            if (p->isSplitter())
-            {
-                splitters.add(p);
-            }
+          //  p->update();
 
-            GenericProcessor* dest = p->getDestNode();
+          //  GenericProcessor* dest = p->getDestNode();
 
-            while (dest != 0)
+            while (p != 0)
             {
                 // iterate through processors
-                dest->update();
-                dest = dest->getDestNode();
+                p->update();
+
+                if (p->isSplitter())
+                {
+                    splitters.add(p);
+                }
+
+                p = p->getDestNode();
 
-                if (dest == 0 && splitters.size() > 0)
+                if (p == 0 && splitters.size() > 0)
                 {
-                    splitters.getFirst()->switchIO();
-                    dest = splitters[0]->getDestNode();
+                    splitters.getFirst()->switchIO(); // switch the signal chain
+                    p = splitters[0]->getDestNode();
+                    splitters.getFirst()->switchIO(); // switch it back
                     splitters.remove(0);
                 }
             }