diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile
index 151287fe10235e5717abf93f8105602401514331..ade31750e62655e49440e6decbdb79c491ae136a 100644
--- a/Builds/Linux/Makefile
+++ b/Builds/Linux/Makefile
@@ -71,7 +71,6 @@ OBJECTS := \
   $(OBJDIR)/LfpDisplayCanvas_4a58e87e.o \
   $(OBJDIR)/OpenGLCanvas_3c775a41.o \
   $(OBJDIR)/SpikeDetector_300d85e7.o \
-  $(OBJDIR)/FileReader_18023b0e.o \
   $(OBJDIR)/AudioNode_94606ff3.o \
   $(OBJDIR)/EventNode_95c842b7.o \
   $(OBJDIR)/MergerEditor_d1fcc0df.o \
@@ -274,11 +273,6 @@ $(OBJDIR)/SpikeDetector_300d85e7.o: ../../Source/Processors/SpikeDetector.cpp
 	@echo "Compiling SpikeDetector.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/FileReader_18023b0e.o: ../../Source/Processors/FileReader.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling FileReader.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/AudioNode_94606ff3.o: ../../Source/Processors/AudioNode.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling AudioNode.cpp"
diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
index e6dfea255137553f617920d46d8f9d8ae4730225..cc8e44707063c1fe600def6b1003e6ad1f36c2a1 100644
--- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
@@ -45,7 +45,6 @@
 		B13883377C9316B9603336B4 = { isa = PBXBuildFile; fileRef = 2E96DA81EE37A0ECE471A928; };
 		073B178E7EF1759BA0AACCCE = { isa = PBXBuildFile; fileRef = 0C5335B0E57C9DC92FC57E5F; };
 		4BE0DDA01B73223EF0BD934A = { isa = PBXBuildFile; fileRef = 3DD0741FCFBC7563EC722D9B; };
-		6656467170D2822949BD2F7F = { isa = PBXBuildFile; fileRef = 5AC4DD48CCB1AB4936A2DE4A; };
 		08B501E0D7764C6B613AF529 = { isa = PBXBuildFile; fileRef = B7750B27E4F3748ECCCCF69D; };
 		9CBA3837CC8CAA03A03F2D9C = { isa = PBXBuildFile; fileRef = FA57CE4F63FF1592D6B3F9B5; };
 		93A3E6284F2DAED3F491332B = { isa = PBXBuildFile; fileRef = AD73EA6B24378294003DC2D0; };
@@ -196,8 +195,6 @@
 		7738F51AE0EC63D76EE0F761 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OpenGLCanvas.h; path = ../../Source/Processors/Visualization/OpenGLCanvas.h; sourceTree = SOURCE_ROOT; };
 		3DD0741FCFBC7563EC722D9B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDetector.cpp; path = ../../Source/Processors/SpikeDetector.cpp; sourceTree = SOURCE_ROOT; };
 		6E4B37AA4BFEB5A37E3AC250 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDetector.h; path = ../../Source/Processors/SpikeDetector.h; sourceTree = SOURCE_ROOT; };
-		5AC4DD48CCB1AB4936A2DE4A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FileReader.cpp; path = ../../Source/Processors/FileReader.cpp; sourceTree = SOURCE_ROOT; };
-		44E93A2D64EB5ADA54CB2CFB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FileReader.h; path = ../../Source/Processors/FileReader.h; sourceTree = SOURCE_ROOT; };
 		B7750B27E4F3748ECCCCF69D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioNode.cpp; path = ../../Source/Processors/AudioNode.cpp; sourceTree = SOURCE_ROOT; };
 		12866D44BE115E8837468F48 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioNode.h; path = ../../Source/Processors/AudioNode.h; sourceTree = SOURCE_ROOT; };
 		FA57CE4F63FF1592D6B3F9B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = EventNode.cpp; path = ../../Source/Processors/EventNode.cpp; sourceTree = SOURCE_ROOT; };
@@ -434,8 +431,6 @@
 				15543D7982B26B70879960F4,
 				3DD0741FCFBC7563EC722D9B,
 				6E4B37AA4BFEB5A37E3AC250,
-				5AC4DD48CCB1AB4936A2DE4A,
-				44E93A2D64EB5ADA54CB2CFB,
 				B7750B27E4F3748ECCCCF69D,
 				12866D44BE115E8837468F48,
 				FA57CE4F63FF1592D6B3F9B5,
@@ -621,7 +616,6 @@
 				B13883377C9316B9603336B4,
 				073B178E7EF1759BA0AACCCE,
 				4BE0DDA01B73223EF0BD934A,
-				6656467170D2822949BD2F7F,
 				08B501E0D7764C6B613AF529,
 				9CBA3837CC8CAA03A03F2D9C,
 				93A3E6284F2DAED3F491332B,
diff --git a/Source/Processors/AudioNode.cpp b/Source/Processors/AudioNode.cpp
index d513370f2610fb422f7799ffbddf0fba43d6e70c..5cede137287c4457cdf398f2c6c6f1918d6a58fb 100644
--- a/Source/Processors/AudioNode.cpp
+++ b/Source/Processors/AudioNode.cpp
@@ -28,8 +28,8 @@ AudioNode::AudioNode()
 	: GenericProcessor("Audio Node"), volume(5.0f), audioEditor(0)
 {
 
-	numInputs = 64;
-	numOutputs = 2;
+	settings.numInputs = 64;
+	settings.numOutputs = 2;
 
 	// 64 inputs, 2 outputs (left and right channel)
 	setPlayConfigDetails(getNumInputs(),getNumOutputs(),44100.0,128);
diff --git a/Source/Processors/Editors/GenericEditor.h b/Source/Processors/Editors/GenericEditor.h
index 17f2bac8a09ea1370941add7d06c740244f4a6c1..301e22f2c9dcb15e6fa9b0c3c09171ca14f2ba4a 100644
--- a/Source/Processors/Editors/GenericEditor.h
+++ b/Source/Processors/Editors/GenericEditor.h
@@ -54,11 +54,10 @@ class GenericEditor : public AudioProcessorEditor,
 
 {
 public:
-	GenericEditor (GenericProcessor* owner);//, FilterViewport* vp);
+	GenericEditor (GenericProcessor* owner);
 	virtual ~GenericEditor();
 
 	void paint (Graphics& g);
-	//void setViewport(FilterViewport*);
 
 	bool keyPressed (const KeyPress& key);
 
@@ -83,7 +82,7 @@ public:
 	virtual void switchSource(int) { }  // needed for MergerEditor
 	virtual void switchSource() { }; // needed for MergerEditor
 
-	AudioProcessor* getProcessor() const {return getAudioProcessor();}
+	GenericProcessor* getProcessor() const {return (GenericProcessor*) getAudioProcessor();}
 	
 	void createRadioButtons(int x, int y, int w, StringArray values, const String& name);
 		
diff --git a/Source/Processors/Editors/MergerEditor.cpp b/Source/Processors/Editors/MergerEditor.cpp
index 1fa5234af7b1298f8920ab5ee46171c962eacc3a..fef818681a300807954b877fb935c25ec9eae38a 100644
--- a/Source/Processors/Editors/MergerEditor.cpp
+++ b/Source/Processors/Editors/MergerEditor.cpp
@@ -101,14 +101,14 @@ void MergerEditor::buttonClicked(Button* button)
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(0);
+		processor->switchIO(0);
 
 	} else if (button == pipelineSelectorB) 
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(1);
+		processor->switchIO(1);
 		
 	}
 }
@@ -120,14 +120,14 @@ void MergerEditor::switchSource(int source)
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(0);
+		processor->switchIO(0);
 
 	} else if (source == 1)
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(1);
+		processor->switchIO(1);
 		
 	}
 }
@@ -143,6 +143,6 @@ void MergerEditor::switchSource()
 	pipelineSelectorA->setToggleState(!isAOn,false);
 
 	Merger* processor = (Merger*) getProcessor();
-	processor->switchSource();
+	processor->switchIO();
 
 }
\ No newline at end of file
diff --git a/Source/Processors/Editors/SplitterEditor.cpp b/Source/Processors/Editors/SplitterEditor.cpp
index 20de8670ce3d5c47f4b5683ed0171deff233e8db..e3c11c61aadbdc42629f641c521b2408d8b8875c 100644
--- a/Source/Processors/Editors/SplitterEditor.cpp
+++ b/Source/Processors/Editors/SplitterEditor.cpp
@@ -101,14 +101,14 @@ void SplitterEditor::buttonClicked(Button* button)
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(0);
+		processor->switchIO(0);
 
 	} else if (button == pipelineSelectorB) 
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(1);
+		processor->switchIO(1);
 		
 	}
 }
@@ -120,14 +120,14 @@ void SplitterEditor::switchDest(int dest)
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(0);
+		processor->switchIO(0);
 
 	} else if (dest == 1)
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(1);
+		processor->switchIO(1);
 		
 	}
 }
\ No newline at end of file
diff --git a/Source/Processors/EventNode.cpp b/Source/Processors/EventNode.cpp
index 59ddf59440225100b53618a6fd0ee0e310b47796..c0ee0c90e4c43a1a94d70feb0860804a312d188f 100644
--- a/Source/Processors/EventNode.cpp
+++ b/Source/Processors/EventNode.cpp
@@ -27,10 +27,6 @@
 EventNode::EventNode()
 	: GenericProcessor("Event Generator"), Hz(1), accumulator(0)
 {
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
 
 }
 
@@ -42,25 +38,17 @@ EventNode::~EventNode()
 AudioProcessorEditor* EventNode::createEditor()
 {
 	editor = new EventNodeEditor(this);
-	//setEditor(editor);
-
-	std::cout << "Creating editor." << std::endl;
-
 	return editor;
-
 }
 
-
-bool EventNode::canSendSignalTo(GenericProcessor* p)
+void EventNode::updateSettings()
 {
-	if (p->getName().equalsIgnoreCase("WiFi Output"))
-	{
-		return true;
-	} else {
-		return false;
-	}
+	// add event channels
+	settings.eventChannelIds.add(1);
+	settings.eventChannelNames.add("Trigger");
 }
 
+
 void EventNode::setParameter (int parameterIndex, float newValue)
 {
 	std::cout << "Setting frequency to " << newValue << " Hz." << std::endl;
@@ -81,11 +69,10 @@ void EventNode::process(AudioSampleBuffer &buffer,
 		if (accumulator > getSampleRate()/Hz)
 		{
 			//std::cout << "Adding message." << std::endl;
-			addMidiEvent(midiMessages, 10, i);
+			addEvent(midiMessages, 10, i);
 			accumulator = 0;
 		}
 
 	}	
-	
 
 }
diff --git a/Source/Processors/EventNode.h b/Source/Processors/EventNode.h
index 6d1491a0c207c019b3645b77099911d3ebb1441a..f0664849d04018c8476024f7601ebce6e47d3cc0 100644
--- a/Source/Processors/EventNode.h
+++ b/Source/Processors/EventNode.h
@@ -36,8 +36,6 @@
 
 */
 
-class FilterViewport;
-
 class EventNode : public GenericProcessor
 
 {
@@ -50,11 +48,10 @@ public:
 	void setParameter (int parameterIndex, float newValue);
 
 	bool isSource() {return true;}
-	bool hasEditor() const {return true;}
 
-	float getSampleRate() {return 44100.0;}
+    int getDefaultNumOutputs() {return 0;}
 
-	bool canSendSignalTo(GenericProcessor*);
+    void updateSettings();
 
 	AudioProcessorEditor* createEditor();
 	
diff --git a/Source/Processors/FileReader.cpp b/Source/Processors/FileReader.cpp
deleted file mode 100644
index e0facd69406e3e149bc87def857cfc2df5d4bf6f..0000000000000000000000000000000000000000
--- a/Source/Processors/FileReader.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "FileReader.h"
-
-
-FileReader::FileReader()
-	: GenericProcessor("File Reader"),
-	  sampleRate (40000.0),
-	  numChannels(16),
-	  samplesPerBlock(1024)
-{
-	setNumOutputs(numChannels);
-	setNumInputs(0);
-}
-
-FileReader::~FileReader()
-{
-}
-
-
-//AudioProcessorEditor* FileReader::createEditor( )
-//{
-	//filterEditor = new FilterEditor(this);
-	
-//	std::cout << "Creating editor." << std::endl;
-//	sourceEditor = new SourceNodeEditor(this);
-//	return sourceEditor;
-//}
-
-
-
-void FileReader::setParameter (int parameterIndex, float newValue)
-{
-	//std::cout << "Message received." << std::endl;
-}
-
-bool FileReader::enable () {
-
-	File file = File("./data_stream_16ch");
-	input = file.createInputStream();
-
-	
-	std::cout << "File Reader received enable signal." << std::endl;
-
-	return true;
-
-}
-
-bool FileReader::disable() {
-
-	deleteAndZero(input);
-	
-	std::cout << "File reader received disable signal." << std::endl;
-
-	return true;
-
-}
-
-void FileReader::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
-                            int& nSamples)
-{
-
-	nSamples = samplesPerBlock;
-	//std::cout << buffer.getNumChannels() << std::endl;
-	
-    for (int i = 0; i < samplesPerBlock; ++i)
-    {
-
-    	for (int j = 0; j < numChannels; j++) {
-    		
-    		if (input->isExhausted())
-    			input->setPosition(0);   			
-    	
-    		const float sample = float(input->readShort());
-
-    		*buffer.getSampleData (j, i) = sample;
-    	}
-
-    }
-}
\ No newline at end of file
diff --git a/Source/Processors/FileReader.h b/Source/Processors/FileReader.h
deleted file mode 100644
index 30394bdd3bbef20564c6dfe04c05c685c4b5d6d0..0000000000000000000000000000000000000000
--- a/Source/Processors/FileReader.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef __FILEREADER_H_605BF4A__
-#define __FILEREADER_H_605BF4A__
-
-
-#include "../../JuceLibraryCode/JuceHeader.h"
-#include "GenericProcessor.h"
-
-/**
-
-  --UNDER CONSTRUCTION--
-
-  Reads data from a file with a specific format.
-
-  @see GenericProcessor
-
-*/
-
-
-class FileReader : public GenericProcessor
-
-{
-public:
-	
-	// real member functions:
-	FileReader();
-	~FileReader();
-
-	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
-
-	void setParameter (int parameterIndex, float newValue);
-
-	//AudioProcessorEditor* createEditor();
-	bool hasEditor() const {return true;}
-
-	bool enable();
-	bool disable();
-
-	bool isSource() {return true;}
-
-private:
-
-	float sampleRate;
-	int numChannels;
-	int samplesPerBlock;
-
-	FileInputStream* input;
-
-	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileReader);
-
-};
-
-
-
-
-#endif  // __FILEREADER_H_605BF4A__
diff --git a/Source/Processors/FilterNode.cpp b/Source/Processors/FilterNode.cpp
index e8526cf86ad89947b1f1c1997b614a36e3963f9a..e381b58ea7f1e7b83da1d04ae20c465afab3d556 100644
--- a/Source/Processors/FilterNode.cpp
+++ b/Source/Processors/FilterNode.cpp
@@ -81,51 +81,34 @@ AudioProcessorEditor* FilterNode::createEditor()
 //  necessary to interoperate with the Filter virtual base class and its derived classes
 
 
-void FilterNode::setNumInputs(int inputs)
+void FilterNode::updateSettings()
 {		
 
-	numInputs = inputs;
-	setNumOutputs(inputs);
-
 	filters.clear();
 	lowCuts.clear();
 	highCuts.clear();
 
-	if (inputs < 100) {
-
-	for (int n = 0; n < getNumInputs(); n++)
-	{
-		std::cout << "Creating filter number " << n << std::endl;
-
-		filters.add(new Dsp::SmoothedFilterDesign 
-			<Dsp::Butterworth::Design::BandPass 	// design type
-			<4>,								 	// order
-			1,										// number of channels (must be const)
-			Dsp::DirectFormII>						// realization
-			(1024));	 
-
-		lowCuts.add(1.0f);
-		highCuts.add(1000.0f);
-		
-		setFilterParameters(1.0f, 1000.0f, n);
-	}
-
-	}
-				
-}
-
-void FilterNode::setSampleRate(float r)
-{
-	sampleRate = r;
-
-	if (numInputs < 100) {
+	if (getNumInputs() < 100) {
 
 		for (int n = 0; n < getNumInputs(); n++)
 		{
-			setFilterParameters(lowCuts[n], highCuts[n], n);
+			std::cout << "Creating filter number " << n << std::endl;
+
+			filters.add(new Dsp::SmoothedFilterDesign 
+				<Dsp::Butterworth::Design::BandPass 	// design type
+				<4>,								 	// order
+				1,										// number of channels (must be const)
+				Dsp::DirectFormII>						// realization
+				(1024));	 
+
+			lowCuts.add(1.0f);
+			highCuts.add(1000.0f);
+			
+			setFilterParameters(1.0f, 1000.0f, n);
 		}
+
 	}
-	
+				
 }
 
 void FilterNode::setFilterParameters(double lowCut, double highCut, int chan)
diff --git a/Source/Processors/FilterNode.h b/Source/Processors/FilterNode.h
index 2a6e616477d13d6b4eb18822254ee47d35a3caba..1dbe3fbd025385f56c26b3978c0a49a1f34dbf0c 100644
--- a/Source/Processors/FilterNode.h
+++ b/Source/Processors/FilterNode.h
@@ -52,9 +52,8 @@ public:
 	AudioProcessorEditor* createEditor();
 
 	bool hasEditor() const {return true;}
-	
-	void setNumInputs(int);
-	void setSampleRate(float);
+
+    void updateSettings();
 	
 private:
 
diff --git a/Source/Processors/GenericProcessor.cpp b/Source/Processors/GenericProcessor.cpp
index 2bee50b370f7d819373b9f56905db121bb840b91..5f658a44f9e0b4efc91c9001560cf84aea4a405a 100644
--- a/Source/Processors/GenericProcessor.cpp
+++ b/Source/Processors/GenericProcessor.cpp
@@ -32,7 +32,6 @@ GenericProcessor::GenericProcessor(const String& name_) :
 	nextAvailableChannel(0), currentChannel(-1),
 	wasConnected(false)
 {
-
 }
 
 GenericProcessor::~GenericProcessor()
@@ -52,41 +51,6 @@ void GenericProcessor::setParameter (int parameterIndex, float newValue)
 
 }
 
-GenericProcessor* GenericProcessor::getOriginalSourceNode()
-{
-	if (isSource())
-	{
-		return this;
-	} else {
-		
-		GenericProcessor* source = getSourceNode();
-
-		if (source != 0)
-		{
-			while (!source->isSource() && source != 0)
-			{
-				source = source->getSourceNode();
-			}
-
-			return source;
-
-		} else {
-			return 0;
-		}
-	}
-}
-
-int GenericProcessor::getDefaultNumOutputs()
-{
-	if (!isSink())
-	{
-		return 10;
-	} else {
-		return 0;
-	}
-}
-
-
 void GenericProcessor::prepareToPlay (double sampleRate_, int estimatedSamplesPerBlock)
 {
 	// use the enable() function instead
@@ -101,15 +65,6 @@ void GenericProcessor::releaseResources()
 	// disable() is only called by the ProcessorGraph at the end of acquisition
 }
 
-
-// void GenericProcessor::sendMessage(const String& msg)
-// {
-// 	std::cout << "Message: ";
-// 	std::cout << msg << "...." << std::endl;
-// 	UI->transmitMessage(msg);
-// }
-
-
 int GenericProcessor::getNextChannel(bool increment)
 {
 	int chan = nextAvailableChannel;
@@ -278,80 +233,75 @@ void GenericProcessor::setDestNode(GenericProcessor* dn)
 	}
 }
 
-void GenericProcessor::updateSettings()
+void GenericProcessor::clearSettings()
 {
+	settings.originalSource = 0;
+	settings.numInputs = 0;
+	settings.numOutputs = 0;
+	settings.inputChannelNames.clear();
+	settings.outputChannelNames.clear();
+	settings.bitVolts.clear();
+	settings.eventChannelIds.clear();
+	settings.eventChannelNames.clear();
+}
+
+void GenericProcessor::update()
+{
+
+	clearSettings();
 	
 	if (sourceNode != 0)
 	{
-		setSampleRate(sourceNode->getSampleRate());
-		setNumInputs(sourceNode->getNumOutputs());
+		// everything is inherited except numOutputs
+		settings = sourceNode->settings;
+		settings.numOutputs = settings.numInputs;
+
 	} else {
-		setSampleRate(getDefaultSampleRate());
-		setNumInputs(0);
-		setNumOutputs(getDefaultNumOutputs());
-	}
 
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
+		settings.sampleRate = getDefaultSampleRate();
+		settings.numOutputs = getDefaultNumOutputs();
 
-	updateParameters();
+		for (int i = 0; i < getNumOutputs(); i++)
+			settings.bitVolts.add(getDefaultBitVolts());
 
-	GenericEditor* editor = (GenericEditor*) getEditor();
+		generateDefaultChannelNames(settings.outputChannelNames);
 
-	editor->update();
+	}
 
-}
+	if (this->isSink())
+	{
+		settings.numOutputs = 0;
+		settings.outputChannelNames.clear();
+	}
 
-void GenericProcessor::updateParameters()
-{
-	
-}
+	updateSettings(); // custom settings code
 
+	// required for the ProcessorGraph to know the
+	// details of this processor:
+	setPlayConfigDetails(getNumInputs(),  // numIns
+		                 getNumOutputs(), // numOuts
+		                 44100.0,         // sampleRate
+		                 128);            // blockSize
 
-int GenericProcessor::getNumInputs()
-{
-	return numInputs;
-}
+	editor->update(); // update editor settings
 
-int GenericProcessor::getNumOutputs()
-{
-	return numOutputs;
 }
 
-void GenericProcessor::setNumInputs(int n) {
-	numInputs = n;
-	// if (destNode != 0)
-	// {
-	// 	destNode->setNumInputs();
-	// }
-	//setPlayConfigDetails(numInputs,numOutputs,44100.0,1024);
-}
-
-void GenericProcessor::setNumInputs() {
-	
-	int n = getSourceNode()->getNumOutputs();
-	setNumInputs(n);
-}
-
-void GenericProcessor::setNumOutputs()
+void GenericProcessor::generateDefaultChannelNames(StringArray& names)
 {
-	setNumOutputs(getNumInputs());
-}
+	names.clear();
 
-void GenericProcessor::setNumOutputs(int n) {
-	numOutputs = n;
-	//setPlayConfigDetails(numInputs,numOutputs,44100.0,1024);
-}
+	for (int i = 0; i < settings.numOutputs; i++)
+	{
+		String channelName = "CH";
+		channelName += (i+1);
+		names.add(channelName);
+	}
 
-float GenericProcessor::getSampleRate()
-{
-	return sampleRate;
-}
-void GenericProcessor::setSampleRate(float sr)
-{
-	sampleRate = sr;
 }
 
-int GenericProcessor::checkForMidiEvents(MidiBuffer& midiMessages)
+
+int GenericProcessor::checkForEvents(MidiBuffer& midiMessages)
 {
 
 	if (midiMessages.getNumEvents() > 0) 
@@ -388,7 +338,7 @@ int GenericProcessor::checkForMidiEvents(MidiBuffer& midiMessages)
 
 }
 
-void GenericProcessor::addMidiEvent(MidiBuffer& midiMessages, int numberToAdd, int sampleNum)
+void GenericProcessor::addEvent(MidiBuffer& midiMessages, int numberToAdd, int sampleNum)
 {
 	uint8 data[2];
 
diff --git a/Source/Processors/GenericProcessor.h b/Source/Processors/GenericProcessor.h
index e59e3ca0fbbb31c11be2e5ef8e4ea54c692d47b9..a5742e6cabd5942c7f200ef2dabef7b114a698ee 100644
--- a/Source/Processors/GenericProcessor.h
+++ b/Source/Processors/GenericProcessor.h
@@ -112,30 +112,19 @@ public:
 	GenericProcessor* sourceNode;
 	GenericProcessor* destNode;
 
-	int numInputs;
-	int numOutputs;
-
-	float sampleRate;
-
-	virtual float getSampleRate();
-	virtual void setSampleRate(float sr);
+	virtual float getSampleRate() {return settings.sampleRate;}
 	virtual float getDefaultSampleRate() {return 44100.0;}
 
-	virtual int getNumInputs();
-	virtual void setNumInputs(int);
-	virtual void setNumInputs();
-	
-	virtual int getNumOutputs();
-	virtual void setNumOutputs(int);
-	virtual void setNumOutputs();
-	virtual int getDefaultNumOutputs();
+	virtual int getNumInputs() {return settings.numInputs;}
+	virtual int getNumOutputs() {return settings.numOutputs;}
+	virtual int getDefaultNumOutputs() {return 2;}
+
+	//virtual float getBitVolts() {return settings.bitVolts;}
+	virtual float getDefaultBitVolts() {return 1.0;}
 
 	virtual int getNextChannel(bool);
 	virtual void resetConnections();
 	
-	virtual void updateSettings(); // updates sample rate and number of channels
-	virtual void updateParameters(); // called in updateSettings() to update params
-
 	virtual void setCurrentChannel(int chan) {currentChannel = chan;}
 
 	int getNodeId() {return nodeId;}
@@ -144,12 +133,9 @@ public:
 	// get/set source node functions
 	GenericProcessor* getSourceNode() {return sourceNode;}
 	GenericProcessor* getDestNode() {return destNode;}
-	GenericProcessor* getOriginalSourceNode();
 
-	virtual void switchSource(int) { };
-	virtual void switchSource() { };
-	virtual void switchDest() { };
-	virtual void switchDest(int) { };
+	virtual void switchIO(int) { };
+	virtual void switchIO() { };
 
 	virtual void setSourceNode(GenericProcessor* sn);
 	virtual void setDestNode(GenericProcessor* dn);
@@ -177,8 +163,8 @@ public:
 
 	int nextAvailableChannel;
 
-	int checkForMidiEvents(MidiBuffer& mb);
-	void addMidiEvent(MidiBuffer& mb, int a, int b);
+	int checkForEvents(MidiBuffer& mb);
+	void addEvent(MidiBuffer& mb, int a, int b);
 
 	bool isEnabled;
 
@@ -192,6 +178,32 @@ public:
 	virtual GenericEditor* getEditor() {return editor;}
 	ScopedPointer<GenericEditor> editor;
 
+	struct ProcessorSettings {
+
+		GenericProcessor* originalSource;
+
+		int numInputs;
+		int numOutputs;
+		StringArray inputChannelNames;
+		StringArray outputChannelNames;
+
+		float sampleRate;
+		Array<float> bitVolts;
+
+		Array<int> eventChannelIds;
+		StringArray eventChannelNames;
+
+	};
+
+	ProcessorSettings settings;
+
+	virtual void clearSettings();
+
+	virtual void generateDefaultChannelNames(StringArray&);
+
+	virtual void update(); // default node updating
+	virtual void updateSettings() {};
+
 private:
 
 	void processBlock (AudioSampleBuffer &buffer, MidiBuffer &midiMessages);
diff --git a/Source/Processors/LfpDisplayNode.cpp b/Source/Processors/LfpDisplayNode.cpp
index efc8841b38e11974e6d589f6b9b7165cb52e3a25..fb313b3829dc7b4925009bdd6f7d2b72534ca613 100644
--- a/Source/Processors/LfpDisplayNode.cpp
+++ b/Source/Processors/LfpDisplayNode.cpp
@@ -30,64 +30,32 @@ LfpDisplayNode::LfpDisplayNode()
 	  displayBufferIndex(0), abstractFifo(100)
 
 {
-
-	numInputs = 2;
-	numOutputs = 0;
-	sampleRate = 44100.0;
-
-	setPlayConfigDetails(2,0,44100.0,128);
-
-	displayBuffer = new AudioSampleBuffer (8, 100);
+	displayBuffer = new AudioSampleBuffer(8, 100);
 	eventBuffer = new MidiBuffer();
 }
 
 LfpDisplayNode::~LfpDisplayNode()
 {
-
-	deleteAndZero(displayBuffer);
-	deleteAndZero(eventBuffer);
+	//deleteAndZero(displayBuffer);
+	//deleteAndZero(eventBuffer);
 }
 
 AudioProcessorEditor* LfpDisplayNode::createEditor()
 {
 
-	editor = new LfpDisplayEditor(this);
-
-	//editor->setBuffers (displayBuffer, eventBuffer);
-	//editor->setUIComponent (getUIComponent());
-	//editor->setConfiguration (config);
-	//editor->updateNumInputs(getNumInputs());
-	//editor->updateSampleRate(sampleRate);
-
-	//setEditor(editor);
-	
+	editor = new LfpDisplayEditor(this);	
 	return editor;
 
 }
 
-void LfpDisplayNode::setNumInputs(int inputs)
-{
-	std::cout << "Setting num inputs on LfpDisplayNode to " << inputs << std::endl;
-	numInputs = inputs;	
-	setNumOutputs(0);
-
-	setPlayConfigDetails(getNumInputs(),0,44100.0,128);
-
-	LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
-	editor->updateNumInputs(inputs);
-}
-
-void LfpDisplayNode::setSampleRate(float r)
+void LfpDisplayNode::updateSettings()
 {
-	sampleRate = r;
-
-	LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
-	editor->updateSampleRate(r);
+	std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl;
 }
 
 bool LfpDisplayNode::resizeBuffer()
 {
-	int nSamples = (int) sampleRate*bufferLength;
+	int nSamples = (int) getSampleRate()*bufferLength;
 	int nInputs = getNumInputs();
 
 	std::cout << "Resizing buffer. Samples: " << nSamples << ", Inputs: " << nInputs << std::endl;
diff --git a/Source/Processors/LfpDisplayNode.h b/Source/Processors/LfpDisplayNode.h
index a0555542c33170cf6b61d61973309558e84c5a83..898cf978aedbacbcf6caad04ce5463fa999b95be 100644
--- a/Source/Processors/LfpDisplayNode.h
+++ b/Source/Processors/LfpDisplayNode.h
@@ -56,8 +56,7 @@ public:
 
 	void setParameter(int, float);
 
-	void setNumInputs(int inputs);
-	void setSampleRate(float r);
+	void updateSettings();
 
 	bool enable();
 	bool disable();
@@ -67,10 +66,8 @@ public:
 
 private:
 
-	DataViewport* dataViewport;
-
-	AudioSampleBuffer* displayBuffer;
-	MidiBuffer* eventBuffer;
+	ScopedPointer<AudioSampleBuffer> displayBuffer;
+	ScopedPointer<MidiBuffer> eventBuffer;
 
 	int displayBufferIndex;
 
diff --git a/Source/Processors/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph.cpp
index 56afd9dec21069d6b17c253396af547701716be3..219387137afe9f5a71a1f98ec14bf5f146a1f20e 100644
--- a/Source/Processors/ProcessorGraph.cpp
+++ b/Source/Processors/ProcessorGraph.cpp
@@ -28,7 +28,6 @@
 #include "AudioNode.h"
 #include "LfpDisplayNode.h"
 #include "EventNode.h"
-#include "FileReader.h"
 #include "FilterNode.h"
 #include "GenericProcessor.h"
 #include "RecordNode.h"
@@ -285,7 +284,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 			{
 				dest = splitters.getFirst(); // dest is now the splitter
 				splitters.remove(0); // take it out of the 
-				dest->switchDest(); // switch to the other destination
+				dest->switchIO(); // switch to the other destination
 				dest->wasConnected = true; // don't want to re-add splitter
 				source = dest->getSourceNode(); // splitter is now source
 			}
diff --git a/Source/Processors/ProcessorGraph.h b/Source/Processors/ProcessorGraph.h
index 279ae740665397680f3415ed47fc706a67241577..b69364753faf21d3cbc737bf265c4c9a5ebae71c 100644
--- a/Source/Processors/ProcessorGraph.h
+++ b/Source/Processors/ProcessorGraph.h
@@ -45,13 +45,8 @@
 
 class GenericProcessor;
 class RecordNode;
-class SignalChainTabButton;
 class AudioNode;
-//class SourceNode;
-//class EditorViewport;
-//class UIComponent;
-//class Configuration;
-//class MessageCenter;
+class SignalChainTabButton;
 
 class ProcessorGraph : public AudioProcessorGraph,
 					   public AccessClass
@@ -71,11 +66,6 @@ public:
 	RecordNode* getRecordNode();
 	AudioNode* getAudioNode();
 
-	//void setUIComponent(UIComponent* ui);
-	//void setFilterViewport(FilterViewport *fv);
-	//void setMessageCenter(MessageCenter* mc);
-	//void setConfiguration(Configuration* config);
-
 	void updateConnections(Array<SignalChainTabButton*, CriticalSection>);
 
 	bool processorWithSameNameExists(const String& name);
@@ -83,9 +73,6 @@ public:
 	void saveState();
 	void loadState();
 
-	//int getNextFreeAudioChannel();
-	//int getNextFreeRecordChannel();
-
 private:	
 
 	int currentNodeId;
@@ -100,14 +87,6 @@ private:
 	void createDefaultNodes();
 	void clearConnections();
 
-	//UIComponent* UI;
-	//FilterViewport* filterViewport;
-	///Configuration* config;
-	//MessageCenter* messageCenter;
-
-	//int totalAudioConnections;
-	//int totalRecordConnections;
-
 };
 
 
diff --git a/Source/Processors/ResamplingNode.cpp b/Source/Processors/ResamplingNode.cpp
index 1c17cdd5ce37359d78375eabd6e98efd1313c98c..9e66626244f52a6e67ebf88ee831c029dbc7eacc 100644
--- a/Source/Processors/ResamplingNode.cpp
+++ b/Source/Processors/ResamplingNode.cpp
@@ -33,11 +33,11 @@ ResamplingNode::ResamplingNode(bool destBufferType)
 	
 {
 
-	setNumInputs(2);
-	setNumOutputs(2);
+	settings.numInputs = 2;
+	settings.numOutputs = 2;
 
-		setPlayConfigDetails(2, // number of inputs
-				         2, // number of outputs
+	setPlayConfigDetails(getNumInputs(), // number of inputs
+				         getNumOutputs(), // number of outputs
 				         44100.0, // sampleRate
 				         128);    // blockSize
 
diff --git a/Source/Processors/SignalGenerator.cpp b/Source/Processors/SignalGenerator.cpp
index 0b7740618f80f4d56a22033ac94eda6b4464eb26..20aa46afc103d801ceeb73782a494b1277b2bb7d 100644
--- a/Source/Processors/SignalGenerator.cpp
+++ b/Source/Processors/SignalGenerator.cpp
@@ -34,43 +34,21 @@ SignalGenerator::SignalGenerator()
 	
 {
 
-	setNumOutputs(10);
-	setNumInputs(0);
-
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
-
-
 }
 
 SignalGenerator::~SignalGenerator()
 {
-	//config->removeDataSource(this);	
-}
 
+}
 
-// void SignalGenerator::setConfiguration(Configuration* cf)
-// {
-// 	config = cf;
-
-//      DataSource* d = new DataSource(this, config);
-
-// 	 // add a new data source to this configuration
-//      config->addDataSource(d);
-
-// }
 
 AudioProcessorEditor* SignalGenerator::createEditor( )
 {
 	editor = new SignalGeneratorEditor(this);
-	//setEditor(ed);
-	
-	//std::cout << "Creating editor." << std::endl;
-	//filterEditor = new FilterEditor(this);
 	return editor;
 }
 
-void SignalGenerator::updateParameters()
+void SignalGenerator::updateSettings()
 {
 
 	std::cout << "Signal generator updating parameters" << std::endl;
@@ -99,7 +77,7 @@ void SignalGenerator::setParameter (int parameterIndex, float newValue)
 			amplitudes.set(currentChannel,newValue);
 		} else {
 			frequencies.set(currentChannel,newValue);
-			phasePerSample.set(currentChannel, double_Pi * 2.0 / (sampleRate / frequencies[currentChannel]));
+			phasePerSample.set(currentChannel, double_Pi * 2.0 / (getSampleRate() / frequencies[currentChannel]));
 		}
 	}
 
diff --git a/Source/Processors/SignalGenerator.h b/Source/Processors/SignalGenerator.h
index abf1036edcff43ff4d3530e60b87b19c2d2d53ed..8d3465671391ac82293c38fb7b8b409482d48459 100644
--- a/Source/Processors/SignalGenerator.h
+++ b/Source/Processors/SignalGenerator.h
@@ -61,7 +61,7 @@ public:
 
 	bool isSource() {return true;}
 
-	void updateParameters();
+	void updateSettings();
 
 private:
 	
diff --git a/Source/Processors/SourceNode.cpp b/Source/Processors/SourceNode.cpp
index fc031adafb84e7e8938ebe7a5b25db5305f7cc41..c964169f0b24d9dad8fccff3d34fda162dbb9d52 100644
--- a/Source/Processors/SourceNode.cpp
+++ b/Source/Processors/SourceNode.cpp
@@ -28,7 +28,7 @@
 SourceNode::SourceNode(const String& name_)
 	: GenericProcessor(name_),
 	  dataThread(0),
-	  sourceCheckInterval(750), wasDisabled(true)
+	  sourceCheckInterval(2000), wasDisabled(true)
 {
 	if (getName().equalsIgnoreCase("Intan Demo Board")) {
 		dataThread = new IntanThread(this);
@@ -38,17 +38,6 @@ SourceNode::SourceNode(const String& name_)
 		dataThread = new FileReaderThread(this);
 	}
 
-	setNumInputs(0);
-
-	if (dataThread != 0) {
-		setNumOutputs(dataThread->getNumChannels());
-		inputBuffer = dataThread->getBufferAddress();
-	} else {
-		setNumOutputs(10);
-	}
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
-
 	if (dataThread != 0)
 	{
 		if (!dataThread->foundInputSource())
@@ -59,19 +48,24 @@ SourceNode::SourceNode(const String& name_)
 		enabledState(false);
 	}
 
-	// check for input source every two seconds
+	// check for input source every few seconds
 	startTimer(sourceCheckInterval); 
 
 }
 
 SourceNode::~SourceNode() 
 {
-	if (dataThread != 0)
-		deleteAndZero(dataThread);
+	//if (dataThread != 0)
+	//	deleteAndZero(dataThread);
 
 	//config->removeDataSource(this);	
 }
 
+void SourceNode::updateSettings()
+{
+
+}
+
 float SourceNode::getSampleRate()
 {
 
@@ -108,30 +102,6 @@ void SourceNode::enabledState(bool t)
 
 }
 
-// void SourceNode::setConfiguration(Configuration* cf)
-// {
-// 	config = cf;
-
-//      DataSource* d = new DataSource(this, config);
-
-//   //   // add tetrodes -- should really be doing this dynamically
-//      d->addTrode(4, "TT1");
-//      d->addTrode(4, "TT2");
-//      d->addTrode(4, "TT3");
-//      d->addTrode(4, "TT4");
-
-//      for (int n = 0; n < d->numTetrodes(); n++)
-//       {
-//            std::cout << d->getTetrode(n)->getName();
-//       }
-//       std::cout << std::endl;
-
-// 	 // // add a new data source to this configuration
-//      config->addDataSource(d);
-
-// }
-
-
 void SourceNode::setParameter (int parameterIndex, float newValue)
 {
 	//std::cout << "Got parameter change notification";
@@ -140,9 +110,6 @@ void SourceNode::setParameter (int parameterIndex, float newValue)
 AudioProcessorEditor* SourceNode::createEditor()
 {
 	editor = new SourceNodeEditor(this);
-	//setEditor(ed);
-	
-//	std::cout << "Creating editor." << std::endl;
 	return editor;
 }
 
@@ -154,7 +121,7 @@ void SourceNode::timerCallback()
 			std::cout << "Input source found." << std::endl;
 			//stopTimer(); // check for input source every two seconds
 			enabledState(true);
-			GenericEditor* ed = (GenericEditor*) getEditor();
+			GenericEditor* ed = getEditor();
 			//ed->enable();
 			getEditorViewport()->makeEditorVisible(ed);
 		}
@@ -162,7 +129,7 @@ void SourceNode::timerCallback()
 		if (isEnabled) {
 			std::cout << "No input source found." << std::endl;
 			enabledState(false);
-			GenericEditor* ed = (GenericEditor*) getEditor();
+			GenericEditor* ed = getEditor();
 			//ed->disable();
 			getEditorViewport()->makeEditorVisible(ed);
 		}
diff --git a/Source/Processors/SourceNode.h b/Source/Processors/SourceNode.h
index fd6664411f6dadfe73b6289313d229a58fe4ae44..78a9c1f781cd82427cb2a6c82328d69265fa44d7 100644
--- a/Source/Processors/SourceNode.h
+++ b/Source/Processors/SourceNode.h
@@ -90,9 +90,11 @@ private:
 	//const String name;
 	void timerCallback();
 
-	DataThread* dataThread;
+	ScopedPointer<DataThread> dataThread;
 	DataBuffer* inputBuffer;
 
+	void updateSettings();
+
 	int* numSamplesInThisBuffer;
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SourceNode);
diff --git a/Source/Processors/Utilities/Merger.cpp b/Source/Processors/Utilities/Merger.cpp
index 778ecd665dcbff778bee2b1de789adf9ceb511ec..36947163ef9ff59f8e7fe4c8ae07fc108a3f6970 100644
--- a/Source/Processors/Utilities/Merger.cpp
+++ b/Source/Processors/Utilities/Merger.cpp
@@ -30,10 +30,7 @@ Merger::Merger()
 	: GenericProcessor("Merger"), 
 		sourceNodeA(0), sourceNodeB(0), activePath(0)//, tabA(-1), tabB(-1)
 {
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
+	
 }
 
 Merger::~Merger()
@@ -64,7 +61,7 @@ void Merger::setMergerSourceNode(GenericProcessor* sn)
 	}
 }
 
-void Merger::switchSource(int sourceNum) {
+void Merger::switchIO(int sourceNum) {
 
 	//std::cout << "Switching to source number " << sourceNum << std::endl;
 	
@@ -95,7 +92,7 @@ bool Merger::stillHasSource()
 
 }
 
-void Merger::switchSource()
+void Merger::switchIO()
 {
 	if (activePath == 0) {
 		activePath = 1;
@@ -108,25 +105,55 @@ void Merger::switchSource()
 
 }
 
-void Merger::setNumInputs(int n)
+void Merger::addSettingsFromSourceNode(GenericProcessor* sn)
+{
+
+	settings.numInputs += sn->getNumOutputs();
+	settings.inputChannelNames.addArray(sn->settings.inputChannelNames);
+	settings.eventChannelIds.addArray(sn->settings.eventChannelIds);
+	settings.eventChannelNames.addArray(sn->settings.eventChannelNames);
+	settings.bitVolts.addArray(sn->settings.bitVolts);
+
+	settings.originalSource = sn->settings.originalSource;
+	settings.sampleRate = sn->settings.sampleRate;
+
+	settings.numOutputs = settings.numInputs;
+	settings.outputChannelNames = settings.inputChannelNames;
+
+}
+
+void Merger::updateSettings()
 {
-	numInputs = 0;
+
+	// default is to get everything from sourceNodeA,
+	// but this might not be ideal
+	clearSettings();
 
 	if (sourceNodeA != 0)
 	{
 		std::cout << "   Merger source A found." << std::endl;
-		numInputs += sourceNodeA->getNumOutputs();
+		addSettingsFromSourceNode(sourceNodeA);
 	}
+
 	if (sourceNodeB != 0)
 	{
 		std::cout << "   Merger source B found." << std::endl;
-		numInputs += sourceNodeB->getNumOutputs();
+		addSettingsFromSourceNode(sourceNodeB);
+	}	
+
+	if (sourceNodeA == 0 && sourceNodeB == 0) {
+
+		settings.sampleRate = getDefaultSampleRate();
+		settings.numOutputs = getDefaultNumOutputs();
+
+		for (int i = 0; i < getNumOutputs(); i++)
+			settings.bitVolts.add(getDefaultBitVolts());
+
+		generateDefaultChannelNames(settings.outputChannelNames);
 	}
 
 	std::cout << "Number of merger outputs: " << getNumInputs() << std::endl;
 
-	setNumOutputs(getNumInputs());
-
 }
 
 // void Merger::setNumOutputs(int /*outputs*/)
diff --git a/Source/Processors/Utilities/Merger.h b/Source/Processors/Utilities/Merger.h
index 66d4459bc188844581cabd3cb6175e1f724d5bea..7b416027915a4b5b5c0417520c013d737b6df8d9 100644
--- a/Source/Processors/Utilities/Merger.h
+++ b/Source/Processors/Utilities/Merger.h
@@ -51,11 +51,12 @@ public:
 
 	bool isMerger() {return true;}
 
-	void switchSource(int);
-	void switchSource();
+	void switchIO(int);
+	void switchIO();
 	void setMergerSourceNode(GenericProcessor* sn);
 
-	void setNumInputs(int);
+    void updateSettings();
+    void addSettingsFromSourceNode(GenericProcessor* sn);
 
 	bool stillHasSource();
 
diff --git a/Source/Processors/Utilities/Splitter.cpp b/Source/Processors/Utilities/Splitter.cpp
index 32fa9e0f7497724f9c604212aa81d8911293ccd1..7290be5f4bb2a4490187d31bca56415433d3cbbf 100644
--- a/Source/Processors/Utilities/Splitter.cpp
+++ b/Source/Processors/Utilities/Splitter.cpp
@@ -31,10 +31,6 @@ Splitter::Splitter()
 		destNodeA(0), destNodeB(0), activePath(0)
 {
 
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
 }
 
 Splitter::~Splitter()
@@ -65,7 +61,7 @@ void Splitter::setSplitterDestNode(GenericProcessor* dn)
 	}
 }
 
-void Splitter::switchDest(int destNum) {
+void Splitter::switchIO(int destNum) {
 	
 	std::cout << "Switching to dest number " << destNum << std::endl;
 	
@@ -81,11 +77,11 @@ void Splitter::switchDest(int destNum) {
 		std::cout << "Dest node: " << getDestNode() << std::endl;
 	}
 
-	getEditorViewport()->makeEditorVisible((GenericEditor*) getEditor());
+	getEditorViewport()->makeEditorVisible(getEditor());
 
 }
 
-void Splitter::switchDest()
+void Splitter::switchIO()
 {
 	if (activePath == 0) {
 		activePath = 1;
@@ -97,9 +93,3 @@ void Splitter::switchDest()
 	}
 
 }
-
-void Splitter::setNumInputs(int n)
-{
-	numInputs = n;
-	setNumOutputs(getNumInputs());
-}
\ No newline at end of file
diff --git a/Source/Processors/Utilities/Splitter.h b/Source/Processors/Utilities/Splitter.h
index 69581ba625c6fc5ee72ba6793032cce4dee4a8d9..ed775bdcf4ebe83ab5ed07ec52a80218f1479609 100644
--- a/Source/Processors/Utilities/Splitter.h
+++ b/Source/Processors/Utilities/Splitter.h
@@ -53,11 +53,10 @@ public:
 
 	bool isSplitter() {return true;}
 
-	void switchDest(int);
-    void switchDest();
+	void switchIO(int);
+    void switchIO();
 	void setSplitterDestNode(GenericProcessor* dn);
 
-    void setNumInputs(int);
 
 private:
 
diff --git a/Source/Processors/WiFiOutput.cpp b/Source/Processors/WiFiOutput.cpp
index c84664285ddf34c709a38354fd9f1ea1e7fb4653..ccf3deea3131813cc3459ec867f4fd0de3191024 100644
--- a/Source/Processors/WiFiOutput.cpp
+++ b/Source/Processors/WiFiOutput.cpp
@@ -27,11 +27,6 @@
 WiFiOutput::WiFiOutput()
 	: GenericProcessor("WiFi Output")
 {
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
-
 }
 
 WiFiOutput::~WiFiOutput()
@@ -42,11 +37,6 @@ WiFiOutput::~WiFiOutput()
 AudioProcessorEditor* WiFiOutput::createEditor()
 {
 	editor = new WiFiOutputEditor(this);
-	
-	//setEditor(wifiEditor);
-	//wifiEditor->setConfiguration(config);
-
-	//std::cout << "Creating editor." << std::endl;
 	return editor;
 }
 
@@ -57,12 +47,12 @@ void WiFiOutput::setParameter (int parameterIndex, float newValue)
 }
 
 void WiFiOutput::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
+                            MidiBuffer &events,
                             int& nSamples)
 {
 	
 
-	int sampleNum = checkForMidiEvents(midiMessages);
+	int sampleNum = checkForEvents(events);
 
 	if (sampleNum >= 0)
 	{
diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp
index 2d89b13327eae2c8957902c9f77e72ad84e916c0..657fc69f5ba32ffccfba187408826713904e1389 100644
--- a/Source/UI/EditorViewport.cpp
+++ b/Source/UI/EditorViewport.cpp
@@ -811,10 +811,7 @@ const String EditorViewport::saveState(const File& file)
                 {
                     splitPoints.add(nextProcessor);
 
-                    if (nextProcessor->isSplitter())
-                        nextProcessor->switchDest(0);
-                    else
-                        nextProcessor->switchSource(0);
+                    nextProcessor->switchIO(0);
                 }
 
             } else {
@@ -826,22 +823,19 @@ const String EditorViewport::saveState(const File& file)
                     nextProcessor = splitPoints.getFirst();
                     splitPoints.remove(0);
 
+                    nextProcessor->switchIO(1);
+                    signalChain->addChildElement(switchNodeXml(nextProcessor));
+                    
                     if (nextProcessor->isMerger())
                     {
-                        std::cout << "    Switching merger source." << std::endl;
-                        nextProcessor->switchSource(1);
-                        signalChain->addChildElement(switchNodeXml(nextProcessor));
                         insertionPt = 0;
                         moveForward = false;
-                    } else {
-                        std::cout << "    Switching splitter dest." << std::endl;
-                        nextProcessor->switchDest(1);
-                        signalChain->addChildElement(switchNodeXml(nextProcessor));
+                    } else { 
                         insertionPt = 1;
                         moveForward = true;
                     }
 
-                    editor = (GenericEditor*) nextProcessor->getEditor();
+                    editor = nextProcessor->getEditor();
 
                 } else {
 
diff --git a/Source/UI/SignalChainManager.cpp b/Source/UI/SignalChainManager.cpp
index 29f77b0406c8837d15c45acbdb823209bb76b291..8885e20f18bb44393291033e8d178b4aab95fca5 100644
--- a/Source/UI/SignalChainManager.cpp
+++ b/Source/UI/SignalChainManager.cpp
@@ -175,7 +175,7 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         // need to inform the other source that its merger has disappeared
         if (p->isMerger())
         {
-        	p->switchSource();
+        	p->switchIO();
         	if (p->getSourceNode() != 0)
         		p->getSourceNode()->setDestNode(0);
         }
@@ -257,18 +257,18 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
             dest = (GenericProcessor*) editorArray[n]->getProcessor();
             source = (GenericProcessor*) editorArray[n-1]->getProcessor();
 
-            //if (!dest->isMerger())
+            if (!dest->isMerger())
         		dest->setSourceNode(source);
-        	//else
-        	//	dest->setMergerSourceNode(source);
+        	else
+        		dest->setMergerSourceNode(source);
 
            //std::cout << dest->getName() << "::";
         }
 
-        if (!dest->isSplitter())
+       // if (!dest->isSplitter())
         	dest->setDestNode(0); // set first source as 0
-        else
-        	dest->setSplitterDestNode(0);
+       // else
+       // 	dest->setSplitterDestNode(0);
       //  dest->setDestNode(0); // set last dest as 0
 
       // std::cout << std::endl;
@@ -468,33 +468,38 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
 
         std::cout << "Updating settings." << std::endl;
 
+        Array<GenericProcessor*> splitters;
+
         for (int n = 0; n < signalChainArray.size(); n++)
-        {
+        { // iterate through signal chains
             
-            GenericEditor* source = (GenericEditor*) signalChainArray[n]->getEditor();
-            GenericProcessor* p = (GenericProcessor*) source->getProcessor();
+            GenericEditor* source = signalChainArray[n]->getEditor();
+            GenericProcessor* p = source->getProcessor();
 
-            p->updateSettings();
+            p->update();
+
+            if (p->isSplitter())
+            {
+                splitters.add(p);
+            }
 
             GenericProcessor* dest = p->getDestNode();
 
             while (dest != 0)
-            {
-                dest->updateSettings();
+            { // iterate through processors
+                dest->update();
                 dest = dest->getDestNode();
+
+                if (dest == 0 && splitters.size() > 0)
+                {
+                    splitters.getFirst()->switchIO();
+                    dest = splitters[0]->getDestNode();
+                    splitters.remove(0);
+                }
             }
         }
     }
 
-   // std::cout << "OK2." << std::endl;
-
-    // Step 8: make sure all editors are visible, and refresh
-   // for (int n = 0; n < editorArray.size(); n++)
-  //  {
-       // std::cout << "Editor " << n << ": " << editorArray[n]->getName() << std::endl;
-    //    editorArray[n]->setVisible(true);
-   // }
-
 
    std::cout << "Finished adding new editor." << std::endl << std::endl << std::endl;
     
diff --git a/open-ephys.jucer b/open-ephys.jucer
index 2768d9df5014df67ecc942d65400bef9ec6de543..58e9e746e724640d85ae26ac05ad361384237962 100644
--- a/open-ephys.jucer
+++ b/open-ephys.jucer
@@ -164,8 +164,6 @@
               file="Source/Processors/SpikeDetector.cpp"/>
         <FILE id="jIX00WN" name="SpikeDetector.h" compile="0" resource="0"
               file="Source/Processors/SpikeDetector.h"/>
-        <FILE id="sKJ2lid" name="FileReader.cpp" compile="1" resource="0" file="Source/Processors/FileReader.cpp"/>
-        <FILE id="9o71Tr2" name="FileReader.h" compile="0" resource="0" file="Source/Processors/FileReader.h"/>
         <FILE id="gZRZq2O" name="AudioNode.cpp" compile="1" resource="0" file="Source/Processors/AudioNode.cpp"/>
         <FILE id="ZPSmLKn" name="AudioNode.h" compile="0" resource="0" file="Source/Processors/AudioNode.h"/>
         <FILE id="hGnGAjh" name="EventNode.cpp" compile="1" resource="0" file="Source/Processors/EventNode.cpp"/>