diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile
index 652cf09c8080c40bafe3a34f5e8cc68bd096cab1..23c77cf51bcc9025d57c3f3763afa5f410fe85b4 100644
--- a/Builds/Linux/Makefile
+++ b/Builds/Linux/Makefile
@@ -55,8 +55,6 @@ OBJECTS := \
   $(OBJDIR)/AccessClass_de9602d5.o \
   $(OBJDIR)/PracticalSocket_2574ecc8.o \
   $(OBJDIR)/AudioComponent_521bd9c9.o \
-  $(OBJDIR)/NetworkEventsEditor_ae5ec8e7.o \
-  $(OBJDIR)/NetworkEvents_5344c99a.o \
   $(OBJDIR)/ProcessorManager_2aa7db2a.o \
   $(OBJDIR)/PluginManager_f764c180.o \
   $(OBJDIR)/AudioEditor_3931be27.o \
@@ -86,7 +84,6 @@ OBJECTS := \
   $(OBJDIR)/GenericEditor_becb2ad6.o \
   $(OBJDIR)/ImageIcon_c89b23a6.o \
   $(OBJDIR)/VisualizerEditor_3672b003.o \
-  $(OBJDIR)/KwikFileSource_58456030.o \
   $(OBJDIR)/FileSource_a1ad7002.o \
   $(OBJDIR)/FileReader_e4a9ccaa.o \
   $(OBJDIR)/FileReaderEditor_e1193ff7.o \
@@ -102,19 +99,8 @@ OBJECTS := \
   $(OBJDIR)/OriginalRecording_d6dc3293.o \
   $(OBJDIR)/RecordEngine_97ef83aa.o \
   $(OBJDIR)/RecordNode_cc21a82a.o \
-  $(OBJDIR)/PeriStimulusTimeHistogramEditor_6be5bf55.o \
-  $(OBJDIR)/PeriStimulusTimeHistogramNode_9631ca2a.o \
-  $(OBJDIR)/tictoc_cdca1ed.o \
-  $(OBJDIR)/TrialCircularBuffer_4a4cef0c.o \
   $(OBJDIR)/SourceNode_de3985ea.o \
   $(OBJDIR)/SourceNodeEditor_cdc90937.o \
-  $(OBJDIR)/SpikeDisplayCanvas_2219bd20.o \
-  $(OBJDIR)/SpikeDisplayEditor_6e1d56b5.o \
-  $(OBJDIR)/SpikeDisplayNode_be27b98a.o \
-  $(OBJDIR)/SpikeSortBoxes_17f37282.o \
-  $(OBJDIR)/SpikeSorter_5f160cae.o \
-  $(OBJDIR)/SpikeSorterCanvas_f0ead366.o \
-  $(OBJDIR)/SpikeSorterEditor_3cee6cfb.o \
   $(OBJDIR)/Splitter_889c68aa.o \
   $(OBJDIR)/SplitterEditor_93a6dbf7.o \
   $(OBJDIR)/Visualizer_2e631df8.o \
@@ -188,16 +174,6 @@ $(OBJDIR)/AudioComponent_521bd9c9.o: ../../Source/Audio/AudioComponent.cpp
 	@echo "Compiling AudioComponent.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/NetworkEventsEditor_ae5ec8e7.o: ../../Source/Processors/NetworkEvents/NetworkEventsEditor.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling NetworkEventsEditor.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/NetworkEvents_5344c99a.o: ../../Source/Processors/NetworkEvents/NetworkEvents.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling NetworkEvents.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/ProcessorManager_2aa7db2a.o: ../../Source/Processors/ProcessorManager/ProcessorManager.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling ProcessorManager.cpp"
@@ -343,11 +319,6 @@ $(OBJDIR)/VisualizerEditor_3672b003.o: ../../Source/Processors/Editors/Visualize
 	@echo "Compiling VisualizerEditor.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/KwikFileSource_58456030.o: ../../Source/Processors/FileReader/KwikFileSource.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling KwikFileSource.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/FileSource_a1ad7002.o: ../../Source/Processors/FileReader/FileSource.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling FileSource.cpp"
@@ -423,26 +394,6 @@ $(OBJDIR)/RecordNode_cc21a82a.o: ../../Source/Processors/RecordNode/RecordNode.c
 	@echo "Compiling RecordNode.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/PeriStimulusTimeHistogramEditor_6be5bf55.o: ../../Source/Processors/PSTH/PeriStimulusTimeHistogramEditor.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling PeriStimulusTimeHistogramEditor.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/PeriStimulusTimeHistogramNode_9631ca2a.o: ../../Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling PeriStimulusTimeHistogramNode.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/tictoc_cdca1ed.o: ../../Source/Processors/PSTH/tictoc.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling tictoc.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/TrialCircularBuffer_4a4cef0c.o: ../../Source/Processors/PSTH/TrialCircularBuffer.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling TrialCircularBuffer.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/SourceNode_de3985ea.o: ../../Source/Processors/SourceNode/SourceNode.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling SourceNode.cpp"
@@ -453,41 +404,6 @@ $(OBJDIR)/SourceNodeEditor_cdc90937.o: ../../Source/Processors/SourceNode/Source
 	@echo "Compiling SourceNodeEditor.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/SpikeDisplayCanvas_2219bd20.o: ../../Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeDisplayCanvas.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/SpikeDisplayEditor_6e1d56b5.o: ../../Source/Processors/SpikeDisplayNode/SpikeDisplayEditor.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeDisplayEditor.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/SpikeDisplayNode_be27b98a.o: ../../Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeDisplayNode.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/SpikeSortBoxes_17f37282.o: ../../Source/Processors/SpikeSorter/SpikeSortBoxes.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeSortBoxes.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/SpikeSorter_5f160cae.o: ../../Source/Processors/SpikeSorter/SpikeSorter.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeSorter.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/SpikeSorterCanvas_f0ead366.o: ../../Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeSorterCanvas.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/SpikeSorterEditor_3cee6cfb.o: ../../Source/Processors/SpikeSorter/SpikeSorterEditor.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling SpikeSorterEditor.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/Splitter_889c68aa.o: ../../Source/Processors/Splitter/Splitter.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling Splitter.cpp"
diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
index ee6c93c04066266045a902eb87a2df6f0b0116cc..3d0aabe4b181655a70e841b0ef6ee50ab76f74b9 100644
--- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
@@ -28,8 +28,6 @@
 		02AAF08AB7A31598784F5EAF = {isa = PBXBuildFile; fileRef = 7B42B28FDB2E3AC67EF296F8; };
 		0AE243437B40602D35435C32 = {isa = PBXBuildFile; fileRef = B04D87ED6AA4897B6CD3CCF6; };
 		425B09B8D50623B880FD03D6 = {isa = PBXBuildFile; fileRef = E79259F2164D16553A69B458; };
-		B13C6EC99E616FE203479C2D = {isa = PBXBuildFile; fileRef = 285C98B6358F7E096B2F317A; };
-		96BFF19817240A0D9062A1A2 = {isa = PBXBuildFile; fileRef = DF95F463F806B844A3D6AF59; };
 		AE80C3A6186F3A4D537489A0 = {isa = PBXBuildFile; fileRef = 66D578EAADBAD326A09FD25E; };
 		07A712AC1BFF4BBB74914575 = {isa = PBXBuildFile; fileRef = D39560BC785A81E49F6C502D; };
 		D761F014D76825DEFE0A7582 = {isa = PBXBuildFile; fileRef = FCA5573BA018F7E8106B89FF; };
@@ -93,8 +91,6 @@
 		3135B9FED0BF40A73C5EFE84 = {isa = PBXBuildFile; fileRef = C51CD15B311D0AAC08D0B908; };
 		AA16BE5A6BBD024C8FCFCDA8 = {isa = PBXBuildFile; fileRef = CAA3B9396EA62166234DAEF1; };
 		46511E0CF49A1F753F2EC949 = {isa = PBXBuildFile; fileRef = B23E6EBB5F99CF7FC72FAC4E; };
-		C0925B26A0267FE011445FCB = {isa = PBXBuildFile; fileRef = C54F63E163E9F8DE60EEA1EE; };
-		5C00155E151C8AF4C3C08FFF = {isa = PBXBuildFile; fileRef = 1C567FD773309E8CE216EC9A; };
 		4976529FC367F5F6A0D04370 = {isa = PBXBuildFile; fileRef = A76B04F4829C862D4B8F66B3; };
 		3F6A34906F13DE5E65F9F785 = {isa = PBXBuildFile; fileRef = 1A05C5AF5447448AAF869508; };
 		68EBB4CEB08BD3DEAC450B95 = {isa = PBXBuildFile; fileRef = 34834859523571912C55AC94; };
@@ -125,32 +121,10 @@
 		D909F61CF9323366A2143DB2 = {isa = PBXBuildFile; fileRef = 25B79E00075CCF59F0A4A7D7; };
 		B806F023DF817BB2D59FEEFD = {isa = PBXBuildFile; fileRef = 949422DF0532222450E95926; };
 		1419982AA3FEFD48742EC391 = {isa = PBXBuildFile; fileRef = B657AEAFB3404A5CB270C413; };
-		B8E8A7F22DCE37B735E65C43 = {isa = PBXBuildFile; fileRef = 0D29270F94FE7878DDF891AA; };
-		9FD92FEF340DC46C56216FC5 = {isa = PBXBuildFile; fileRef = 239AD53591DA0B5B4796A3DF; };
-		093F0BA37D6C91C7E92AB658 = {isa = PBXBuildFile; fileRef = 25B9B8D5E54B9C547197E414; };
-		3B0E6D1750C7ABA614451522 = {isa = PBXBuildFile; fileRef = 6DA5EDE1BF0E8D396EAE23FC; };
-		620CF6292EFB911F15916EA6 = {isa = PBXBuildFile; fileRef = 547C76794FAC1BC349163509; };
-		CCFF38BDBD01CB3623B68A97 = {isa = PBXBuildFile; fileRef = CCE779E203974113A80D6D85; };
-		7B50AD44D4F9610CE4A43414 = {isa = PBXBuildFile; fileRef = FB827FEEA15A274E5F7577DB; };
-		A41078823B3B4B995770C39E = {isa = PBXBuildFile; fileRef = 76D8904379362E11CA4EA11D; };
 		7B69E73AF79BB2B10BAA559C = {isa = PBXBuildFile; fileRef = 242B80832B3C8FF4F3CC18F1; };
 		30D2FF80A059C4F2F2641452 = {isa = PBXBuildFile; fileRef = A7BF9312D81FF5DCEAB8AC47; };
 		74A14124A3B0C5FB13583B57 = {isa = PBXBuildFile; fileRef = 326F8386BCD4E4189D0CC00F; };
 		BABD91F2DC4EDF91E155CC42 = {isa = PBXBuildFile; fileRef = B5D805B691B1C38D959F6B54; };
-		84BB28DDFF317D243DDC7FA2 = {isa = PBXBuildFile; fileRef = AAC6EC29963717E95428D7D2; };
-		DC1505106186A011077FC0B4 = {isa = PBXBuildFile; fileRef = C2CB484954A536E782B4A8E7; };
-		A14CA9089A09267E95C93E1D = {isa = PBXBuildFile; fileRef = 2F0C721AB2973FAD23C7F47B; };
-		9DE3E3BA75AAA0872C7F2A25 = {isa = PBXBuildFile; fileRef = 34CF4D00D785338941AB9590; };
-		DED0D08EFA1EFF4F1D4D3BEF = {isa = PBXBuildFile; fileRef = AC9E30922A14330704FB2573; };
-		33433C097E276713BAA2266D = {isa = PBXBuildFile; fileRef = AE1FC768C646A0EFEC3E3A11; };
-		9635A954DB8FDD6E19B977C3 = {isa = PBXBuildFile; fileRef = 92F51CF12E0C21F38D5E61E8; };
-		8D37FF507C77CC8EA831C5AE = {isa = PBXBuildFile; fileRef = FBF2BF7B97C2FF8557CF39E6; };
-		B9718533E5255AEC3F6C7B2F = {isa = PBXBuildFile; fileRef = D45EF9812FBC284BCB7EEB7C; };
-		5C54E5C528ECD500842038EB = {isa = PBXBuildFile; fileRef = 78400C0FB79F6B0D1A27A6D4; };
-		58EC9F834448B334410385EB = {isa = PBXBuildFile; fileRef = 6DF620BE87EA9F7F25A1144A; };
-		5842C5403AF4A2A6BD87F83B = {isa = PBXBuildFile; fileRef = B66B8CFF619CBF2D66F031E3; };
-		027A01C5025DEA9DAFF605D3 = {isa = PBXBuildFile; fileRef = F46365D8E42099148B843C95; };
-		145E3116F63B7BCBDB30EC96 = {isa = PBXBuildFile; fileRef = F753A8E9CE0C51998066EA07; };
 		4910924155F31E96B9BAD050 = {isa = PBXBuildFile; fileRef = B9068FF0373FA8321C33C42C; };
 		FE0BEC4F57D0EA019EF6D24A = {isa = PBXBuildFile; fileRef = E1E9FAB63BD90C10F2BEF74C; };
 		66DE280C28A69B2002C40A86 = {isa = PBXBuildFile; fileRef = 607CC2BFCB0622B3348FA1AD; };
@@ -261,7 +235,6 @@
 		0BF3932F3EA1149C2F7E31F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; };
 		0C646E9950FB580B21E1F2BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WindowsMediaAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; };
 		0CCB1C4D687001E04DE1DD9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; };
-		0D29270F94FE7878DDF891AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PeriStimulusTimeHistogramEditor.cpp; path = ../../Source/Processors/PSTH/PeriStimulusTimeHistogramEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		0D3C20D1F00B7B1381E6B987 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; };
 		0D884C2CF25F23CE6B99B2A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Singleton.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Singleton.h"; sourceTree = "SOURCE_ROOT"; };
 		0D8ECE32F7D0FE74185F6EF4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; };
@@ -329,7 +302,6 @@
 		1BF01252E3A30560525CE057 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		1C4227B9237C06B69587F551 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V3.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"; sourceTree = "SOURCE_ROOT"; };
 		1C474C73937D98E9D3FFEEC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; };
-		1C567FD773309E8CE216EC9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = KwikFileSource.h; path = ../../Source/Processors/FileReader/KwikFileSource.h; sourceTree = "SOURCE_ROOT"; };
 		1C639F4C139C8D7753AA9BB6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; };
 		1CB0D7AC988EDEC838A1C546 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; };
 		1CCC1D4213B17ABF6222EC82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -354,7 +326,6 @@
 		21D3C1095D2B5A834D998B74 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_OpenSL.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp"; sourceTree = "SOURCE_ROOT"; };
 		222AC2E9BEFE12BE7FF88879 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; };
 		23609D430A25F54723269E91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
-		239AD53591DA0B5B4796A3DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PeriStimulusTimeHistogramEditor.h; path = ../../Source/Processors/PSTH/PeriStimulusTimeHistogramEditor.h; sourceTree = "SOURCE_ROOT"; };
 		23C7EA9C89CC98A5EFEC12FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; };
 		23D82A4C165DD596474F30E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourSelector.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_ColourSelector.h"; sourceTree = "SOURCE_ROOT"; };
 		23F048594D4C9AD8C3399877 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -365,7 +336,6 @@
 		2560987BB222D7CED27EAC87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; };
 		256E22D98B16B09BD521C4A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; };
 		25B79E00075CCF59F0A4A7D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RecordEngine.h; path = ../../Source/Processors/RecordNode/RecordEngine.h; sourceTree = "SOURCE_ROOT"; };
-		25B9B8D5E54B9C547197E414 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PeriStimulusTimeHistogramNode.cpp; path = ../../Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp; sourceTree = "SOURCE_ROOT"; };
 		25DCA4D0E86DFB51AF637D21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; };
 		25F7BEADC001FA3D1EA9B32C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; };
 		261B5AA82F2A86CC5500D8D2 = {isa = PBXFileReference; lastKnownFileType = image.png; name = ArduinoIcon.png; path = ../../Resources/Images/Icons/ArduinoIcon.png; sourceTree = "SOURCE_ROOT"; };
@@ -376,7 +346,6 @@
 		27DC0E650D6D54DF29E6DB68 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
 		2847E92BB432EEB9D5A59260 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; };
 		284F3E94F0C96EA1DD89E606 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileFilter.cpp"; sourceTree = "SOURCE_ROOT"; };
-		285C98B6358F7E096B2F317A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkEventsEditor.cpp; path = ../../Source/Processors/NetworkEvents/NetworkEventsEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		28847C807E6B05303FB8FB34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Strings.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm"; sourceTree = "SOURCE_ROOT"; };
 		28CCF04CCC028BAE0AEE5840 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ElectrodeButtons.cpp; path = ../../Source/Processors/Editors/ElectrodeButtons.cpp; sourceTree = "SOURCE_ROOT"; };
 		28D5AEEEFC4FA8877419C829 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -393,7 +362,6 @@
 		2D20F49E12A7D313049E0258 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; };
 		2D577016FEEE23DD5703C924 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DialogWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DialogWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
 		2DA0032B6DF10345C4842BF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; };
-		2F0C721AB2973FAD23C7F47B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayEditor.cpp; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		2F2EDBE0623561191234AF21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; };
 		2F8252D3FF527D6559B12615 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsSoftwareRenderer.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"; sourceTree = "SOURCE_ROOT"; };
 		2F9BB379BCFCFE0D88CC0408 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorGraph.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h"; sourceTree = "SOURCE_ROOT"; };
@@ -415,7 +383,6 @@
 		33A69BDDCFCD4A4DC14A9961 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPress.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp"; sourceTree = "SOURCE_ROOT"; };
 		34834859523571912C55AC94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FileReader.cpp; path = ../../Source/Processors/FileReader/FileReader.cpp; sourceTree = "SOURCE_ROOT"; };
 		349C9FCEDC32E73DCB7AE806 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsRegistry.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_WindowsRegistry.h"; sourceTree = "SOURCE_ROOT"; };
-		34CF4D00D785338941AB9590 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayEditor.h; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayEditor.h; sourceTree = "SOURCE_ROOT"; };
 		353937A4E68C8C6916C6D1F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		35AEAE0CC0B546625E163B9B = {isa = PBXFileReference; lastKnownFileType = image.png; name = "sine_wave.png"; path = "../../Resources/Images/Icons/sine_wave.png"; sourceTree = "SOURCE_ROOT"; };
 		35C0963BAB9A82F12CDC9F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedValueSet.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -436,7 +403,6 @@
 		390EA3109658E8C51EFC8F61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; };
 		393801D2B91773D376D874B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; };
 		39422C7D01635DD9C00B5136 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; };
-		395602FE1717BD2E4E0A9150 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NetworkEventsEditor.h; path = ../../Source/Processors/NetworkEvents/NetworkEventsEditor.h; sourceTree = "SOURCE_ROOT"; };
 		398BF0B03B719107E6093F98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EngineConfigWindow.h; path = ../../Source/Processors/RecordNode/EngineConfigWindow.h; sourceTree = "SOURCE_ROOT"; };
 		39F287BE4C0B4F3BD4A949FD = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
 		3A2C762575D9728B1F822ED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AsyncUpdater.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -556,7 +522,6 @@
 		5379FC603780F30A2F05FE78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; };
 		53C8A2696FE4389E4AB4441C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; };
 		54339ADDCB6F8E9E7721A986 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; };
-		547C76794FAC1BC349163509 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = tictoc.cpp; path = ../../Source/Processors/PSTH/tictoc.cpp; sourceTree = "SOURCE_ROOT"; };
 		54B7796F6DCF5531789CCF43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Types.h; path = ../../Source/Processors/Dsp/Types.h; sourceTree = "SOURCE_ROOT"; };
 		55811E331B55E0547326CF22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
 		558E925DAC57ADF8810559AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -612,7 +577,6 @@
 		5FEFF62D585CF777C950E569 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; };
 		601654292170CD2D60E912A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; };
 		603764889DE750F8E87F6428 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; };
-		60494102600DD1F7AABCD309 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NetworkEvents.h; path = ../../Source/Processors/NetworkEvents/NetworkEvents.h; sourceTree = "SOURCE_ROOT"; };
 		605C7ACB09E7739EBE4F1539 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_AudioSource.h"; sourceTree = "SOURCE_ROOT"; };
 		607CC2BFCB0622B3348FA1AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SplitterEditor.cpp; path = ../../Source/Processors/Splitter/SplitterEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		60B1BDA3E9E14F9515963082 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BasicNativeHeaders.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_BasicNativeHeaders.h"; sourceTree = "SOURCE_ROOT"; };
@@ -675,11 +639,9 @@
 		6D4DFC260B2966E3EBFC0C79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		6D619C7A3A14981DC4EFF223 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; };
 		6D77949E9C7C9B5A7795C0E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; };
-		6DA5EDE1BF0E8D396EAE23FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PeriStimulusTimeHistogramNode.h; path = ../../Source/Processors/PSTH/PeriStimulusTimeHistogramNode.h; sourceTree = "SOURCE_ROOT"; };
 		6DA8EC2F779DEBB701FE33CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; };
 		6DCDFF2618CFEECEACE87630 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_GraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_android_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; };
 		6DD526F86CBF2C3B3487FFE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; };
-		6DF620BE87EA9F7F25A1144A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeSorterCanvas.cpp; path = ../../Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp; sourceTree = "SOURCE_ROOT"; };
 		6E2F243D8F70CC92391204A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; };
 		6EA1CC7DACDDBA863179521A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; };
 		6EF4EFD6D74D2573AC6B6A6F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_module_info"; sourceTree = "SOURCE_ROOT"; };
@@ -709,7 +671,6 @@
 		75FCE8908DD9055F90E93716 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		76140C0485FDDA98C3D98E2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OldSchoolLookAndFeel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/lookandfeel/juce_OldSchoolLookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; };
 		766923F74E30FF5D6B12E7CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; };
-		76D8904379362E11CA4EA11D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TrialCircularBuffer.h; path = ../../Source/Processors/PSTH/TrialCircularBuffer.h; sourceTree = "SOURCE_ROOT"; };
 		76E89CBE70BF8F2476B7AA34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; };
 		7719FB81DDF23CF0164B131D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; };
 		777D9B0FE3C110ADA980BD09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Butterworth.cpp; path = ../../Source/Processors/Dsp/Butterworth.cpp; sourceTree = "SOURCE_ROOT"; };
@@ -717,7 +678,6 @@
 		77B3E84324445076F1F907E9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Threads.cpp"; sourceTree = "SOURCE_ROOT"; };
 		7814050BBF14AF7D45872768 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Dsp.h; path = ../../Source/Processors/Dsp/Dsp.h; sourceTree = "SOURCE_ROOT"; };
 		783D8922D5C687E170FA1A2C = {isa = PBXFileReference; lastKnownFileType = file.otf; name = "cpmono_plain.otf"; path = "../../Resources/Fonts/cpmono_plain.otf"; sourceTree = "SOURCE_ROOT"; };
-		78400C0FB79F6B0D1A27A6D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeSorter.h; path = ../../Source/Processors/SpikeSorter/SpikeSorter.h; sourceTree = "SOURCE_ROOT"; };
 		784233150B26826701C09103 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiKeyboardComponent.h"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h"; sourceTree = "SOURCE_ROOT"; };
 		786A97B2B4E2BB6406546647 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPathListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h"; sourceTree = "SOURCE_ROOT"; };
 		786F6A40506C2094B812F4D5 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; };
@@ -845,7 +805,6 @@
 		92E07CA13571893873565AC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SplashScreen.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SplashScreen.cpp"; sourceTree = "SOURCE_ROOT"; };
 		92E3405CB31ACFE3F80BBAD4 = {isa = PBXFileReference; lastKnownFileType = image.png; name = OpenEphysBoardLogoBlack.png; path = ../../Resources/Images/Icons/OpenEphysBoardLogoBlack.png; sourceTree = "SOURCE_ROOT"; };
 		92EC6BB8A8C4C5A61F43C233 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; };
-		92F51CF12E0C21F38D5E61E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeSortBoxes.cpp; path = ../../Source/Processors/SpikeSorter/SpikeSortBoxes.cpp; sourceTree = "SOURCE_ROOT"; };
 		934B37E2BECD69E6E27051F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ParameterEditor.cpp; path = ../../Source/Processors/Parameter/ParameterEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		9360657FDE33FA37D80075D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnection.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.cpp"; sourceTree = "SOURCE_ROOT"; };
 		9380932BED279F91B8C1C04B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; };
@@ -935,13 +894,11 @@
 		AA3209223925B66A97AB4509 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; };
 		AA3DAC9A4A3FF9E7D279FB23 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-03.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-03.png"; sourceTree = "SOURCE_ROOT"; };
 		AA7F6609B897B9E134377A62 = {isa = PBXFileReference; lastKnownFileType = file.otf; name = "cpmono_light.otf"; path = "../../Resources/Fonts/cpmono_light.otf"; sourceTree = "SOURCE_ROOT"; };
-		AAC6EC29963717E95428D7D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayCanvas.cpp; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp; sourceTree = "SOURCE_ROOT"; };
 		AADBA8C0AD524CE677428AFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; };
 		AAF5C27D2EEDD254A3652717 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Bessel.h; path = ../../Source/Processors/Dsp/Bessel.h; sourceTree = "SOURCE_ROOT"; };
 		AB4C7059669AC385B02179C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; };
 		ABA3FCD5D762336535D56D94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; };
 		AC116E6590D49AB2EF19CB9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLImage.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLImage.cpp"; sourceTree = "SOURCE_ROOT"; };
-		AC9E30922A14330704FB2573 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayNode.cpp; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp; sourceTree = "SOURCE_ROOT"; };
 		ACA28D2B1FECD2C57F0250A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; };
 		ACAE4A2D65AAC6A36DA9DBCF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; };
 		ACCACAE59079FDECF799BE8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConnectedChildProcess.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -951,7 +908,6 @@
 		AD960F561259904BA68DDA73 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; };
 		ADCB42E4C5641007A4B78025 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeObject.h; path = ../../Source/Processors/Visualization/SpikeObject.h; sourceTree = "SOURCE_ROOT"; };
 		AE1EA04666EAD34D0CA0373D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_opengl.h"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_opengl.h"; sourceTree = "SOURCE_ROOT"; };
-		AE1FC768C646A0EFEC3E3A11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayNode.h; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h; sourceTree = "SOURCE_ROOT"; };
 		AE3D7946F13CE32AE41DD1B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MatlabLikePlot.h; path = ../../Source/Processors/Visualization/MatlabLikePlot.h; sourceTree = "SOURCE_ROOT"; };
 		AE6786E4659DAC92F52E9FA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Toolbar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Toolbar.h"; sourceTree = "SOURCE_ROOT"; };
 		AE9359DBA841F88EF3DA9700 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPath.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1004,7 +960,6 @@
 		B64893F699A10B03AA4AFF6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_ASCII.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_ASCII.h"; sourceTree = "SOURCE_ROOT"; };
 		B6567CAE2B538E79E7DA814C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
 		B657AEAFB3404A5CB270C413 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RecordNode.h; path = ../../Source/Processors/RecordNode/RecordNode.h; sourceTree = "SOURCE_ROOT"; };
-		B66B8CFF619CBF2D66F031E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeSorterCanvas.h; path = ../../Source/Processors/SpikeSorter/SpikeSorterCanvas.h; sourceTree = "SOURCE_ROOT"; };
 		B674DCA2C2A6AF6B58AA7820 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; };
 		B678CFC6B378A58834D2E41F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; };
 		B695B24906116ADEFC9D9B5C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessorGraph.h; path = ../../Source/Processors/ProcessorGraph/ProcessorGraph.h; sourceTree = "SOURCE_ROOT"; };
@@ -1065,7 +1020,6 @@
 		C209C7633D01E525231EE894 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; };
 		C2746A86EC16D3EA9FAC2C1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; };
 		C29E664781AA2396C8D59543 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../JuceLibraryCode/modules/juce_events/juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
-		C2CB484954A536E782B4A8E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayCanvas.h; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.h; sourceTree = "SOURCE_ROOT"; };
 		C2D1409D20E154E43569C725 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		C2F9D279FCC5C4AD56A0C1DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Decibels.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_Decibels.h"; sourceTree = "SOURCE_ROOT"; };
 		C41504F388D0B181B003B627 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1075,7 +1029,6 @@
 		C51CD15B311D0AAC08D0B908 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ImageIcon.h; path = ../../Source/Processors/Editors/ImageIcon.h; sourceTree = "SOURCE_ROOT"; };
 		C5287F057A6A88BC33D5498A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableComposite.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"; sourceTree = "SOURCE_ROOT"; };
 		C54760E4888674CF3CF022E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; };
-		C54F63E163E9F8DE60EEA1EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = KwikFileSource.cpp; path = ../../Source/Processors/FileReader/KwikFileSource.cpp; sourceTree = "SOURCE_ROOT"; };
 		C5654EAA7B65445CF1340983 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GenericProcessor.cpp; path = ../../Source/Processors/GenericProcessor/GenericProcessor.cpp; sourceTree = "SOURCE_ROOT"; };
 		C59B01C8DB5B3B4773032E12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CustomArrowButton.h; path = ../../Source/UI/CustomArrowButton.h; sourceTree = "SOURCE_ROOT"; };
 		C5D0E0996D20BEEEDBFD64FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ValueTree.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1104,7 +1057,6 @@
 		CC35C78D5B446ABF57DDDAE0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; };
 		CC42C4D4230BE4F1071CB2D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableEdgeComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"; sourceTree = "SOURCE_ROOT"; };
 		CC62E20B1189C697DD238810 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; };
-		CCE779E203974113A80D6D85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tictoc.h; path = ../../Source/Processors/PSTH/tictoc.h; sourceTree = "SOURCE_ROOT"; };
 		CD2E26CFD0DC7F6090E15A20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; };
 		CD41C1D09F6D73FA33993F45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; };
 		CD492AC7B458FA6C321B9D0B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_core/juce_module_info"; sourceTree = "SOURCE_ROOT"; };
@@ -1137,7 +1089,6 @@
 		D39560BC785A81E49F6C502D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PluginManager.cpp; path = ../../Source/Processors/PluginManager/PluginManager.cpp; sourceTree = "SOURCE_ROOT"; };
 		D3AE8303545E28D793312F46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GenericEditor.cpp; path = ../../Source/Processors/Editors/GenericEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		D41ED9ADBE3B27E185B2E3F3 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-05.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-05.png"; sourceTree = "SOURCE_ROOT"; };
-		D45EF9812FBC284BCB7EEB7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeSorter.cpp; path = ../../Source/Processors/SpikeSorter/SpikeSorter.cpp; sourceTree = "SOURCE_ROOT"; };
 		D48EB74E1B5AAC7846196B01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_linux_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; };
 		D4B0BD47094D79AB6382228B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLTexture.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.h"; sourceTree = "SOURCE_ROOT"; };
 		D4F94F0232F0CD426DFC44C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PreferencesPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_PreferencesPanel.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1189,7 +1140,6 @@
 		DEBED6F7B61A1801FD5A4CAF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LuaCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; };
 		DEE2959DBBC84EA8448A0F77 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; };
 		DF3C9A1DD67E879E4E0A2727 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_basics.mm"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
-		DF95F463F806B844A3D6AF59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkEvents.cpp; path = ../../Source/Processors/NetworkEvents/NetworkEvents.cpp; sourceTree = "SOURCE_ROOT"; };
 		DFAA7B563CEFB94D9ADB5D6A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; };
 		DFFB7396DCE9DF1253217584 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnailCache.h"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h"; sourceTree = "SOURCE_ROOT"; };
 		E040EA8B5BB61ABBBD14F12F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OggVorbisAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1203,48 +1153,48 @@
 		E21CA41B44E191F1804F9662 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_module_info"; sourceTree = "SOURCE_ROOT"; };
 		E23FA5E940A1434B0305875D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; };
 		E31563D2E7DDD8315F369233 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
+		E33F167E4AA1C44596A1EBED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; };
 		E34E535DA9CBF248E32F7B45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E37140E9E8F7CFDDEEEF6148 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; };
+		E39CC410838072043E3C30DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = OriginalRecording.cpp; path = ../../Source/Processors/RecordNode/OriginalRecording.cpp; sourceTree = "SOURCE_ROOT"; };
 		E3C4B6B362320594789E1297 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E3D9DABE0A9C1DCE6A6515CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MixerAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E419C9DA3202B8B6EC2DB723 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; };
+		E48A7B152993BCF473725A19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CameraDevice.h"; path = "../../JuceLibraryCode/modules/juce_video/capture/juce_CameraDevice.h"; sourceTree = "SOURCE_ROOT"; };
 		E4A2E203101AF37C169F1569 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h"; sourceTree = "SOURCE_ROOT"; };
 		E53FEAA3754E6B5D99516D56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E58A18793D25A1D75811A052 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImagePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; };
+		E5B10AA248D400FDB2645084 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E5C1D021C0FD6FAD082C5D75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GraphViewer.cpp; path = ../../Source/UI/GraphViewer.cpp; sourceTree = "SOURCE_ROOT"; };
 		E5FA033C407367AE0793258B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Cascade.cpp; path = ../../Source/Processors/Dsp/Cascade.cpp; sourceTree = "SOURCE_ROOT"; };
 		E666E60CC07666669FC77C7D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; };
+		E67C5ACDC8208CDE200EC8C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; };
 		E6D3A973D5CEF18CA2BAFF59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E7366E169158F5A2D1D7B55A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; };
 		E7460F066237871A704733E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; };
 		E79259F2164D16553A69B458 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioComponent.h; path = ../../Source/Audio/AudioComponent.h; sourceTree = "SOURCE_ROOT"; };
+		E79B7DC03F81DA1F8CDE21CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"; sourceTree = "SOURCE_ROOT"; };
 		E7ACE8C1456403A574236451 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-bold-serialized"; path = "../../Resources/Fonts/cpmono-bold-serialized"; sourceTree = "SOURCE_ROOT"; };
 		E7EE416EF527C7506B499070 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; };
 		E835BEB3C42E4B241804BE13 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-light-serialized"; path = "../../Resources/Fonts/cpmono-light-serialized"; sourceTree = "SOURCE_ROOT"; };
-		E8D51D470C9955D7D03D5469 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ChebyshevII.h; path = ../../Source/Processors/Dsp/ChebyshevII.h; sourceTree = "SOURCE_ROOT"; };
-		F5A00ACFA3D76168F22F1205 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
-		99E1BC08B886CFDD2CCFD462 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "open-ephys.app"; sourceTree = "BUILT_PRODUCTS_DIR"; };
-		E33F167E4AA1C44596A1EBED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; };
-		E39CC410838072043E3C30DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = OriginalRecording.cpp; path = ../../Source/Processors/RecordNode/OriginalRecording.cpp; sourceTree = "SOURCE_ROOT"; };
-		E48A7B152993BCF473725A19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CameraDevice.h"; path = "../../JuceLibraryCode/modules/juce_video/capture/juce_CameraDevice.h"; sourceTree = "SOURCE_ROOT"; };
-		E5B10AA248D400FDB2645084 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; };
-		E67C5ACDC8208CDE200EC8C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; };
-		E79B7DC03F81DA1F8CDE21CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"; sourceTree = "SOURCE_ROOT"; };
 		E8964C0BE264A55753BC6B7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; };
+		E8D51D470C9955D7D03D5469 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ChebyshevII.h; path = ../../Source/Processors/Dsp/ChebyshevII.h; sourceTree = "SOURCE_ROOT"; };
 		E91923510CB2280C3A3B9E9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; };
 		E91A272EF06892937CB4B9CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E93BE115650B1CB80EACB841 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EditorViewportButtons.h; path = ../../Source/UI/EditorViewportButtons.h; sourceTree = "SOURCE_ROOT"; };
 		E946426F95E0240683CB3337 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; };
 		E97684DCE824DEDA6683C6CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; };
 		EA2FC92CECD1EDA1F07DC59C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; };
-		EA354D7D8E48D461415D52D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; };
 		EA73332E3D5AEC04ADDFBB2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; };
 		EA9518CDEA7049C21D5CE2D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; };
-		EAB2319C7AA57E06A2247CDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; };
-		EAB637B566FEBBDADA654262 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; };
 		EAB6A66678B122C578B16445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; };
 		EAC262A83CD2BEA14542AE89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; };
 		EAC7A64301F0BF2C5E33A1F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; };
+		F5A00ACFA3D76168F22F1205 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+		99E1BC08B886CFDD2CCFD462 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "open-ephys.app"; sourceTree = "BUILT_PRODUCTS_DIR"; };
+		EA354D7D8E48D461415D52D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; };
+		EAB2319C7AA57E06A2247CDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; };
+		EAB637B566FEBBDADA654262 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; };
 		EAEA49B9394D802B79CA8164 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; };
 		EB5F9A50EB53A57D6AE303C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; };
 		EBD8622EAEF10558809888B7 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-01.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-01.png"; sourceTree = "SOURCE_ROOT"; };
@@ -1283,7 +1233,6 @@
 		F345254DE7F499036FB17995 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Layout.h; path = ../../Source/Processors/Dsp/Layout.h; sourceTree = "SOURCE_ROOT"; };
 		F3D0224E4247BCB06A9E4DDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPressMappingSet.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp"; sourceTree = "SOURCE_ROOT"; };
 		F3F48717927A4E24F7373C09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedValueSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.h"; sourceTree = "SOURCE_ROOT"; };
-		F46365D8E42099148B843C95 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeSorterEditor.cpp; path = ../../Source/Processors/SpikeSorter/SpikeSorterEditor.cpp; sourceTree = "SOURCE_ROOT"; };
 		F463A19E6EFEB2837582B117 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_processors.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h"; sourceTree = "SOURCE_ROOT"; };
 		F46843B979D0385C733C797A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		F4D2A03314AB1CF852CC4F2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1293,7 +1242,6 @@
 		F70B7D65EF56B8A0ED36478C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WavAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h"; sourceTree = "SOURCE_ROOT"; };
 		F716728550EBD8FA7B9CA7EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = RecordEngine.cpp; path = ../../Source/Processors/RecordNode/RecordEngine.cpp; sourceTree = "SOURCE_ROOT"; };
 		F73A22F20AE71DA0153E274A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; };
-		F753A8E9CE0C51998066EA07 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeSorterEditor.h; path = ../../Source/Processors/SpikeSorter/SpikeSorterEditor.h; sourceTree = "SOURCE_ROOT"; };
 		F79395F3D9FC2E03DFC7B7DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessorManager.h; path = ../../Source/Processors/ProcessorManager/ProcessorManager.h; sourceTree = "SOURCE_ROOT"; };
 		F796260525BD82FFC1D1732C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Uuid.cpp"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Uuid.cpp"; sourceTree = "SOURCE_ROOT"; };
 		F7979AFD5780D9B2208736EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TooltipWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -1315,8 +1263,6 @@
 		FB33617B5082CC0CDC189F2C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyboardFocusTraverser.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h"; sourceTree = "SOURCE_ROOT"; };
 		FB65FCCCBEE5FCEA2BFD045D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; };
 		FB7E91937D3BBE00F64F0B72 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; };
-		FB827FEEA15A274E5F7577DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TrialCircularBuffer.cpp; path = ../../Source/Processors/PSTH/TrialCircularBuffer.cpp; sourceTree = "SOURCE_ROOT"; };
-		FBF2BF7B97C2FF8557CF39E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeSortBoxes.h; path = ../../Source/Processors/SpikeSorter/SpikeSortBoxes.h; sourceTree = "SOURCE_ROOT"; };
 		FC080F7DF94ABCB7EA09224A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; };
 		FC20BDD5357D39AC43DFC255 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LADSPAPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; };
 		FC85D30C66E7A4E4A6CA29AE = {isa = PBXFileReference; lastKnownFileType = file.otf; name = "cpmono_bold.otf"; path = "../../Resources/Fonts/cpmono_bold.otf"; sourceTree = "SOURCE_ROOT"; };
@@ -1411,11 +1357,6 @@
 		C451728043944D40C69166C1 = {isa = PBXGroup; children = (
 					B04D87ED6AA4897B6CD3CCF6,
 					E79259F2164D16553A69B458, ); name = Audio; sourceTree = "<group>"; };
-		E1B6F7855EA134AA74EE9E52 = {isa = PBXGroup; children = (
-					285C98B6358F7E096B2F317A,
-					395602FE1717BD2E4E0A9150,
-					DF95F463F806B844A3D6AF59,
-					60494102600DD1F7AABCD309, ); name = NetworkEvents; sourceTree = "<group>"; };
 		6689710CC7F2E03991677D85 = {isa = PBXGroup; children = (
 					66D578EAADBAD326A09FD25E,
 					F79395F3D9FC2E03DFC7B7DA, ); name = ProcessorManager; sourceTree = "<group>"; };
@@ -1489,8 +1430,6 @@
 					CAA3B9396EA62166234DAEF1,
 					B23E6EBB5F99CF7FC72FAC4E, ); name = Editors; sourceTree = "<group>"; };
 		10488A99117FC063889F25C7 = {isa = PBXGroup; children = (
-					C54F63E163E9F8DE60EEA1EE,
-					1C567FD773309E8CE216EC9A,
 					A76B04F4829C862D4B8F66B3,
 					1A05C5AF5447448AAF869508,
 					34834859523571912C55AC94,
@@ -1527,36 +1466,11 @@
 					25B79E00075CCF59F0A4A7D7,
 					949422DF0532222450E95926,
 					B657AEAFB3404A5CB270C413, ); name = RecordNode; sourceTree = "<group>"; };
-		70AFD6EB1539BF938821F7A8 = {isa = PBXGroup; children = (
-					0D29270F94FE7878DDF891AA,
-					239AD53591DA0B5B4796A3DF,
-					25B9B8D5E54B9C547197E414,
-					6DA5EDE1BF0E8D396EAE23FC,
-					547C76794FAC1BC349163509,
-					CCE779E203974113A80D6D85,
-					FB827FEEA15A274E5F7577DB,
-					76D8904379362E11CA4EA11D, ); name = PSTH; sourceTree = "<group>"; };
 		CB7739DB9922F30C029B2A02 = {isa = PBXGroup; children = (
 					242B80832B3C8FF4F3CC18F1,
 					A7BF9312D81FF5DCEAB8AC47,
 					326F8386BCD4E4189D0CC00F,
 					B5D805B691B1C38D959F6B54, ); name = SourceNode; sourceTree = "<group>"; };
-		7B2364D82845C97E7A1B1924 = {isa = PBXGroup; children = (
-					AAC6EC29963717E95428D7D2,
-					C2CB484954A536E782B4A8E7,
-					2F0C721AB2973FAD23C7F47B,
-					34CF4D00D785338941AB9590,
-					AC9E30922A14330704FB2573,
-					AE1FC768C646A0EFEC3E3A11, ); name = SpikeDisplayNode; sourceTree = "<group>"; };
-		D3F8D770C9E60B5BA2CCBC68 = {isa = PBXGroup; children = (
-					92F51CF12E0C21F38D5E61E8,
-					FBF2BF7B97C2FF8557CF39E6,
-					D45EF9812FBC284BCB7EEB7C,
-					78400C0FB79F6B0D1A27A6D4,
-					6DF620BE87EA9F7F25A1144A,
-					B66B8CFF619CBF2D66F031E3,
-					F46365D8E42099148B843C95,
-					F753A8E9CE0C51998066EA07, ); name = SpikeSorter; sourceTree = "<group>"; };
 		E2624A71F15AE5C96B34505B = {isa = PBXGroup; children = (
 					B9068FF0373FA8321C33C42C,
 					E1E9FAB63BD90C10F2BEF74C,
@@ -1572,7 +1486,6 @@
 					F115ED75E977A54AAF036B2C,
 					AE3D7946F13CE32AE41DD1B7, ); name = Visualization; sourceTree = "<group>"; };
 		83A3E005DDFCC55F277EEDA5 = {isa = PBXGroup; children = (
-					E1B6F7855EA134AA74EE9E52,
 					6689710CC7F2E03991677D85,
 					8CCA9145D97AAACB0A0D24AD,
 					9C7703C01E449614C1CD884D,
@@ -1587,10 +1500,7 @@
 					2AC55A2E70C6CF50A8C46F6B,
 					1AD84CD59ADC8ACA5C6A1551,
 					0E7092A11A3C96E5ECA71CDA,
-					70AFD6EB1539BF938821F7A8,
 					CB7739DB9922F30C029B2A02,
-					7B2364D82845C97E7A1B1924,
-					D3F8D770C9E60B5BA2CCBC68,
 					E2624A71F15AE5C96B34505B,
 					C4B85C0286AC2510730355E3, ); name = Processors; sourceTree = "<group>"; };
 		1D78FCCF430CD91FD1DBD95B = {isa = PBXGroup; children = (
@@ -2825,8 +2735,6 @@
 					02AAF08AB7A31598784F5EAF,
 					0AE243437B40602D35435C32,
 					425B09B8D50623B880FD03D6,
-					B13C6EC99E616FE203479C2D,
-					96BFF19817240A0D9062A1A2,
 					AE80C3A6186F3A4D537489A0,
 					07A712AC1BFF4BBB74914575,
 					D761F014D76825DEFE0A7582,
@@ -2890,8 +2798,6 @@
 					3135B9FED0BF40A73C5EFE84,
 					AA16BE5A6BBD024C8FCFCDA8,
 					46511E0CF49A1F753F2EC949,
-					C0925B26A0267FE011445FCB,
-					5C00155E151C8AF4C3C08FFF,
 					4976529FC367F5F6A0D04370,
 					3F6A34906F13DE5E65F9F785,
 					68EBB4CEB08BD3DEAC450B95,
@@ -2922,32 +2828,10 @@
 					D909F61CF9323366A2143DB2,
 					B806F023DF817BB2D59FEEFD,
 					1419982AA3FEFD48742EC391,
-					B8E8A7F22DCE37B735E65C43,
-					9FD92FEF340DC46C56216FC5,
-					093F0BA37D6C91C7E92AB658,
-					3B0E6D1750C7ABA614451522,
-					620CF6292EFB911F15916EA6,
-					CCFF38BDBD01CB3623B68A97,
-					7B50AD44D4F9610CE4A43414,
-					A41078823B3B4B995770C39E,
 					7B69E73AF79BB2B10BAA559C,
 					30D2FF80A059C4F2F2641452,
 					74A14124A3B0C5FB13583B57,
 					BABD91F2DC4EDF91E155CC42,
-					84BB28DDFF317D243DDC7FA2,
-					DC1505106186A011077FC0B4,
-					A14CA9089A09267E95C93E1D,
-					9DE3E3BA75AAA0872C7F2A25,
-					DED0D08EFA1EFF4F1D4D3BEF,
-					33433C097E276713BAA2266D,
-					9635A954DB8FDD6E19B977C3,
-					8D37FF507C77CC8EA831C5AE,
-					B9718533E5255AEC3F6C7B2F,
-					5C54E5C528ECD500842038EB,
-					58EC9F834448B334410385EB,
-					5842C5403AF4A2A6BD87F83B,
-					027A01C5025DEA9DAFF605D3,
-					145E3116F63B7BCBDB30EC96,
 					4910924155F31E96B9BAD050,
 					FE0BEC4F57D0EA019EF6D24A,
 					66DE280C28A69B2002C40A86,
diff --git a/Builds/VisualStudio2012/open-ephys.vcxproj b/Builds/VisualStudio2012/open-ephys.vcxproj
index eaa3b706f82b2b1d635b744f83a8bb8b408a13e0..fd4f37d1c1e0f4aff903ea6209b745838ad8cd2f 100644
--- a/Builds/VisualStudio2012/open-ephys.vcxproj
+++ b/Builds/VisualStudio2012/open-ephys.vcxproj
@@ -62,19 +62,15 @@
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">.\Debug64\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">.\Release64\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64</LibraryPath>
     <PlatformToolset>v110</PlatformToolset>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -88,8 +84,8 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;ZEROMQ;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -112,9 +108,8 @@
       <SubSystem>Windows</SubSystem>
       <TargetMachine>MachineX86</TargetMachine>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -134,8 +129,8 @@
     </Midl>
     <ClCompile>
       <Optimization>Full</Optimization>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;ZEROMQ;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -159,9 +154,8 @@
       <TargetMachine>MachineX86</TargetMachine>
       <OptimizeReferences>true</OptimizeReferences>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -182,8 +176,8 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;ZEROMQ;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -204,9 +198,8 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(IntDir)\open-ephys.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -226,8 +219,8 @@
     </Midl>
     <ClCompile>
       <Optimization>Full</Optimization>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;ZEROMQ;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -250,9 +243,8 @@
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -267,8 +259,6 @@
     <ClCompile Include="..\..\Source\AccessClass.cpp"/>
     <ClCompile Include="..\..\Source\Network\PracticalSocket.cpp"/>
     <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.cpp"/>
     <ClCompile Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.cpp"/>
     <ClCompile Include="..\..\Source\Processors\PluginManager\PluginManager.cpp"/>
     <ClCompile Include="..\..\Source\Processors\AudioNode\AudioEditor.cpp"/>
@@ -298,7 +288,6 @@
     <ClCompile Include="..\..\Source\Processors\Editors\GenericEditor.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Editors\ImageIcon.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Editors\VisualizerEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\FileReader\KwikFileSource.cpp"/>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileSource.cpp"/>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileReader.cpp"/>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileReaderEditor.cpp"/>
@@ -314,19 +303,8 @@
     <ClCompile Include="..\..\Source\Processors\RecordNode\OriginalRecording.cpp"/>
     <ClCompile Include="..\..\Source\Processors\RecordNode\RecordEngine.cpp"/>
     <ClCompile Include="..\..\Source\Processors\RecordNode\RecordNode.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\tictoc.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp"/>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNode.cpp"/>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Splitter\Splitter.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Splitter\SplitterEditor.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Visualization\Visualizer.cpp"/>
@@ -1475,8 +1453,6 @@
     <ClInclude Include="..\..\Source\AccessClass.h"/>
     <ClInclude Include="..\..\Source\Network\PracticalSocket.h"/>
     <ClInclude Include="..\..\Source\Audio\AudioComponent.h"/>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.h"/>
     <ClInclude Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.h"/>
     <ClInclude Include="..\..\Source\Processors\PluginManager\OpenEphysPlugin.h"/>
     <ClInclude Include="..\..\Source\Processors\PluginManager\PluginManager.h"/>
@@ -1513,7 +1489,6 @@
     <ClInclude Include="..\..\Source\Processors\Editors\GenericEditor.h"/>
     <ClInclude Include="..\..\Source\Processors\Editors\ImageIcon.h"/>
     <ClInclude Include="..\..\Source\Processors\Editors\VisualizerEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\FileReader\KwikFileSource.h"/>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileSource.h"/>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileReader.h"/>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileReaderEditor.h"/>
@@ -1529,19 +1504,8 @@
     <ClInclude Include="..\..\Source\Processors\RecordNode\OriginalRecording.h"/>
     <ClInclude Include="..\..\Source\Processors\RecordNode\RecordEngine.h"/>
     <ClInclude Include="..\..\Source\Processors\RecordNode\RecordNode.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\tictoc.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h"/>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNode.h"/>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.h"/>
     <ClInclude Include="..\..\Source\Processors\Splitter\Splitter.h"/>
     <ClInclude Include="..\..\Source\Processors\Splitter\SplitterEditor.h"/>
     <ClInclude Include="..\..\Source\Processors\Visualization\DataWindow.h"/>
diff --git a/Builds/VisualStudio2012/open-ephys.vcxproj.filters b/Builds/VisualStudio2012/open-ephys.vcxproj.filters
index d067afc9879465051f031be075e8ba04f885eb30..796444ae41981f079c63918d02cc9c8df8ed87f5 100644
--- a/Builds/VisualStudio2012/open-ephys.vcxproj.filters
+++ b/Builds/VisualStudio2012/open-ephys.vcxproj.filters
@@ -32,9 +32,6 @@
     <Filter Include="open-ephys\Source\Processors">
       <UniqueIdentifier>{3DDEC88C-BAA5-2DDA-A59F-0FB74070AB82}</UniqueIdentifier>
     </Filter>
-    <Filter Include="open-ephys\Source\Processors\NetworkEvents">
-      <UniqueIdentifier>{C41A0CBC-4C1C-5AC2-CAED-3EC41B4BAB37}</UniqueIdentifier>
-    </Filter>
     <Filter Include="open-ephys\Source\Processors\ProcessorManager">
       <UniqueIdentifier>{C84577BE-2445-2454-C134-006B7BCF320C}</UniqueIdentifier>
     </Filter>
@@ -77,18 +74,9 @@
     <Filter Include="open-ephys\Source\Processors\RecordNode">
       <UniqueIdentifier>{185877A6-9FE6-DD2E-BC41-93EE3C608CFC}</UniqueIdentifier>
     </Filter>
-    <Filter Include="open-ephys\Source\Processors\PSTH">
-      <UniqueIdentifier>{2714D3F1-1A51-5CEC-5EE2-26686D9EEAF8}</UniqueIdentifier>
-    </Filter>
     <Filter Include="open-ephys\Source\Processors\SourceNode">
       <UniqueIdentifier>{83A3043C-94AE-ADED-C72B-394EB4BAE6B4}</UniqueIdentifier>
     </Filter>
-    <Filter Include="open-ephys\Source\Processors\SpikeDisplayNode">
-      <UniqueIdentifier>{818E5C85-5930-DC8D-A3C2-0443F4C35B47}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="open-ephys\Source\Processors\SpikeSorter">
-      <UniqueIdentifier>{11B5BECA-5948-83BC-3C0F-DEB527800990}</UniqueIdentifier>
-    </Filter>
     <Filter Include="open-ephys\Source\Processors\Splitter">
       <UniqueIdentifier>{2AAA8664-72AA-EC5C-92E2-3392067B058F}</UniqueIdentifier>
     </Filter>
@@ -409,12 +397,6 @@
     <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp">
       <Filter>open-ephys\Source\Audio</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.cpp">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.cpp">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.cpp">
       <Filter>open-ephys\Source\Processors\ProcessorManager</Filter>
     </ClCompile>
@@ -502,9 +484,6 @@
     <ClCompile Include="..\..\Source\Processors\Editors\VisualizerEditor.cpp">
       <Filter>open-ephys\Source\Processors\Editors</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\FileReader\KwikFileSource.cpp">
-      <Filter>open-ephys\Source\Processors\FileReader</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileSource.cpp">
       <Filter>open-ephys\Source\Processors\FileReader</Filter>
     </ClCompile>
@@ -550,45 +529,12 @@
     <ClCompile Include="..\..\Source\Processors\RecordNode\RecordNode.cpp">
       <Filter>open-ephys\Source\Processors\RecordNode</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\tictoc.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNode.cpp">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClCompile>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.cpp">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\Splitter\Splitter.cpp">
       <Filter>open-ephys\Source\Processors\Splitter</Filter>
     </ClCompile>
@@ -1890,12 +1836,6 @@
     <ClInclude Include="..\..\Source\Audio\AudioComponent.h">
       <Filter>open-ephys\Source\Audio</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.h">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.h">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.h">
       <Filter>open-ephys\Source\Processors\ProcessorManager</Filter>
     </ClInclude>
@@ -2004,9 +1944,6 @@
     <ClInclude Include="..\..\Source\Processors\Editors\VisualizerEditor.h">
       <Filter>open-ephys\Source\Processors\Editors</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\FileReader\KwikFileSource.h">
-      <Filter>open-ephys\Source\Processors\FileReader</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileSource.h">
       <Filter>open-ephys\Source\Processors\FileReader</Filter>
     </ClInclude>
@@ -2052,45 +1989,12 @@
     <ClInclude Include="..\..\Source\Processors\RecordNode\RecordNode.h">
       <Filter>open-ephys\Source\Processors\RecordNode</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\tictoc.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNode.h">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClInclude>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.h">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.h">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.h">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.h">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\Splitter\Splitter.h">
       <Filter>open-ephys\Source\Processors\Splitter</Filter>
     </ClInclude>
diff --git a/Builds/VisualStudio2013/Plugins/KWIKFormat/KWIKFormat.vcxproj b/Builds/VisualStudio2013/Plugins/KWIKFormat/KWIKFormat.vcxproj
index 6c2a189cad5d91541db3d46052837ea2a1216477..655c551c4b08572767132b64c02176ec7738924c 100644
--- a/Builds/VisualStudio2013/Plugins/KWIKFormat/KWIKFormat.vcxproj
+++ b/Builds/VisualStudio2013/Plugins/KWIKFormat/KWIKFormat.vcxproj
@@ -18,6 +18,17 @@
       <Platform>x64</Platform>
     </ProjectConfiguration>
   </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\Source\Plugins\KWIKFormat\FileSource\KwikFileSource.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\KWIKFormat\OpenEphysLib.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\KWIKFormat\RecordEngine\HDF5FileFormat.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\KWIKFormat\RecordEngine\HDF5Recording.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\Source\Plugins\KWIKFormat\FileSource\KwikFileSource.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\KWIKFormat\RecordEngine\HDF5FileFormat.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\KWIKFormat\RecordEngine\HDF5Recording.h" />
+  </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{554C8744-32CD-427C-A9E5-BF9A44440CED}</ProjectGuid>
     <RootNamespace>KWIKRecordEngine</RootNamespace>
@@ -131,15 +142,6 @@
       <AdditionalLibraryDirectories>../../../../Resources/windows-libs/HDF5/lib/x64;..\..\x64\Debug64\bin</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\..\..\Source\Processors\RecordNode\KWIKEngine\HDF5FileFormat.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\RecordNode\KWIKEngine\HDF5Recording.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\RecordNode\KWIKEngine\OpenEphysLib.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\..\..\Source\Processors\RecordNode\KWIKEngine\HDF5FileFormat.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\RecordNode\KWIKEngine\HDF5Recording.h" />
-  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj b/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj
index 31290f45fb0b433314661fef7074bd91eb33be2c..8ff0027238202d64c50c54b6cdda590fac501792 100644
--- a/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj
+++ b/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj
@@ -18,6 +18,17 @@
       <Platform>x64</Platform>
     </ProjectConfiguration>
   </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayCanvas.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayEditor.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayNode.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\OpenEphysLib.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayCanvas.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayEditor.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayNode.h" />
+  </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{41BD734E-4939-47AD-9714-9629538F7206}</ProjectGuid>
     <RootNamespace>LFP_Viewer</RootNamespace>
@@ -118,17 +129,6 @@
       <OptimizeReferences>true</OptimizeReferences>
     </Link>
   </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\OpenEphysLib.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.h" />
-  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj.filters b/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj.filters
index f64fb3f6ae4ce6a21ae899fa1ce057a76fee2181..082585fed9b946c023603261e758680c5b42a957 100644
--- a/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj.filters
+++ b/Builds/VisualStudio2013/Plugins/LFP_Viewer/LFP_Viewer.vcxproj.filters
@@ -15,27 +15,27 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayCanvas.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayEditor.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayNode.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\LfpDisplayNode\OpenEphysLib.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\LfpDisplayNode\OpenEphysLib.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayCanvas.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayEditor.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\LfpDisplayNode\LfpDisplayNode.h">
       <Filter>Source Files</Filter>
     </ClInclude>
   </ItemGroup>
diff --git a/Builds/VisualStudio2013/Plugins/Plugins.sdf b/Builds/VisualStudio2013/Plugins/Plugins.sdf
index 13413e059c72100ae25c973bb97c24c2f0c482bb..cb64bcd3a87ddd7bd0dccde3df35a0096d8598f5 100644
Binary files a/Builds/VisualStudio2013/Plugins/Plugins.sdf and b/Builds/VisualStudio2013/Plugins/Plugins.sdf differ
diff --git a/Builds/VisualStudio2013/Plugins/Plugins.v12.suo b/Builds/VisualStudio2013/Plugins/Plugins.v12.suo
index c1a868093b1abb3980781d06e93f1b6321b8dbe9..665f26ad5dc561cc83eb806ff65609698040650f 100644
Binary files a/Builds/VisualStudio2013/Plugins/Plugins.v12.suo and b/Builds/VisualStudio2013/Plugins/Plugins.v12.suo differ
diff --git a/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj b/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj
index 075178f1a18e68fcd16fd6ec0b9dea576d68ec3d..d39a230575241d7e120bf0e1d18fc8ea6da18ee3 100644
--- a/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj
+++ b/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj
@@ -18,6 +18,23 @@
       <Platform>x64</Platform>
     </ProjectConfiguration>
   </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\OpenEphysLib.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Editor.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Thread.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\okFrontPanelDLL.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000datablock.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000evalboard.cpp" />
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000registers.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Editor.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Thread.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\okFrontPanelDLL.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000datablock.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000evalboard.h" />
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000registers.h" />
+  </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{BD074727-DD1A-4475-9B3F-EF519446403C}</ProjectGuid>
     <RootNamespace>Rhythm_FPGA</RootNamespace>
@@ -120,23 +137,6 @@
       <AdditionalLibraryDirectories>..\..\x64\Debug64\bin</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\OpenEphysLib.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Editor.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Thread.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\okFrontPanelDLL.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000datablock.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000evalboard.cpp" />
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000registers.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Editor.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Thread.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\okFrontPanelDLL.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000datablock.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000evalboard.h" />
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000registers.h" />
-  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj.filters b/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj.filters
index 2702e14a77217640f0837cf2822661ecc41e66f9..7a46b641e7cebfc5feeef9235562c15670120635 100644
--- a/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj.filters
+++ b/Builds/VisualStudio2013/Plugins/Rhythm_FPGA/Rhythm_FPGA.vcxproj.filters
@@ -18,45 +18,45 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\OpenEphysLib.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\OpenEphysLib.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Editor.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Editor.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Thread.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Thread.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\okFrontPanelDLL.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\okFrontPanelDLL.cpp">
       <Filter>Source Files\rhythm-api</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000datablock.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000datablock.cpp">
       <Filter>Source Files\rhythm-api</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000evalboard.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000evalboard.cpp">
       <Filter>Source Files\rhythm-api</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000registers.cpp">
+    <ClCompile Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000registers.cpp">
       <Filter>Source Files\rhythm-api</Filter>
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Editor.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Editor.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\RHD2000Thread.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\RHD2000Thread.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\okFrontPanelDLL.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\okFrontPanelDLL.h">
       <Filter>Source Files\rhythm-api</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000datablock.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000datablock.h">
       <Filter>Source Files\rhythm-api</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000evalboard.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000evalboard.h">
       <Filter>Source Files\rhythm-api</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\..\Source\Processors\DataThreads\Rhythm\rhythm-api\rhd2000registers.h">
+    <ClInclude Include="..\..\..\..\Source\Plugins\RhythmNode\rhythm-api\rhd2000registers.h">
       <Filter>Source Files\rhythm-api</Filter>
     </ClInclude>
   </ItemGroup>
diff --git a/Builds/VisualStudio2013/open-ephys.vcxproj b/Builds/VisualStudio2013/open-ephys.vcxproj
index 8b4ca8afb7f18646591eee74c96734093d1b5fd5..f565c50b0e3b186ebfb4e0781935cf48d2dc212f 100644
--- a/Builds/VisualStudio2013/open-ephys.vcxproj
+++ b/Builds/VisualStudio2013/open-ephys.vcxproj
@@ -62,19 +62,15 @@
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">.\x64\Debug64\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">.\x64\Release64\bin\</OutDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">open-ephys</TargetName>
     <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</GenerateManifest>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">$(LibraryPath);../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64</LibraryPath>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -88,8 +84,8 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;ZEROMQ;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -113,9 +109,8 @@
       <SubSystem>Windows</SubSystem>
       <TargetMachine>MachineX86</TargetMachine>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -135,8 +130,8 @@
     </Midl>
     <ClCompile>
       <Optimization>Full</Optimization>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;ZEROMQ;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -161,9 +156,8 @@
       <TargetMachine>MachineX86</TargetMachine>
       <OptimizeReferences>true</OptimizeReferences>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x86;../../Resources/windows-libs/ZeroMQ/lib_x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -184,8 +178,8 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;ZEROMQ;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -207,9 +201,8 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(IntDir)\open-ephys.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -229,8 +222,8 @@
     </Midl>
     <ClCompile>
       <Optimization>Full</Optimization>
-      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;../../Resources/windows-libs/ZeroMQ/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;ZEROMQ;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCE_API=__declspec(dllexport);JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.5;JUCE_APP_VERSION_HEX=0x305;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <PrecompiledHeader/>
@@ -254,9 +247,8 @@
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <AdditionalLibraryDirectories>../../Resources/windows-libs/HDF5/lib/x64;../../Resources/windows-libs/ZeroMQ/lib_x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <LargeAddressAware>true</LargeAddressAware>
-      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;hdf5.lib;hdf5_cpp.lib;libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
@@ -271,8 +263,6 @@
     <ClCompile Include="..\..\Source\AccessClass.cpp"/>
     <ClCompile Include="..\..\Source\Network\PracticalSocket.cpp"/>
     <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.cpp"/>
     <ClCompile Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.cpp"/>
     <ClCompile Include="..\..\Source\Processors\PluginManager\PluginManager.cpp"/>
     <ClCompile Include="..\..\Source\Processors\AudioNode\AudioEditor.cpp"/>
@@ -302,7 +292,6 @@
     <ClCompile Include="..\..\Source\Processors\Editors\GenericEditor.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Editors\ImageIcon.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Editors\VisualizerEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\FileReader\KwikFileSource.cpp"/>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileSource.cpp"/>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileReader.cpp"/>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileReaderEditor.cpp"/>
@@ -318,19 +307,8 @@
     <ClCompile Include="..\..\Source\Processors\RecordNode\OriginalRecording.cpp"/>
     <ClCompile Include="..\..\Source\Processors\RecordNode\RecordEngine.cpp"/>
     <ClCompile Include="..\..\Source\Processors\RecordNode\RecordNode.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\tictoc.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp"/>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNode.cpp"/>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.cpp"/>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Splitter\Splitter.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Splitter\SplitterEditor.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Visualization\Visualizer.cpp"/>
@@ -1479,8 +1457,6 @@
     <ClInclude Include="..\..\Source\AccessClass.h"/>
     <ClInclude Include="..\..\Source\Network\PracticalSocket.h"/>
     <ClInclude Include="..\..\Source\Audio\AudioComponent.h"/>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.h"/>
     <ClInclude Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.h"/>
     <ClInclude Include="..\..\Source\Processors\PluginManager\OpenEphysPlugin.h"/>
     <ClInclude Include="..\..\Source\Processors\PluginManager\PluginManager.h"/>
@@ -1517,7 +1493,6 @@
     <ClInclude Include="..\..\Source\Processors\Editors\GenericEditor.h"/>
     <ClInclude Include="..\..\Source\Processors\Editors\ImageIcon.h"/>
     <ClInclude Include="..\..\Source\Processors\Editors\VisualizerEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\FileReader\KwikFileSource.h"/>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileSource.h"/>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileReader.h"/>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileReaderEditor.h"/>
@@ -1533,19 +1508,8 @@
     <ClInclude Include="..\..\Source\Processors\RecordNode\OriginalRecording.h"/>
     <ClInclude Include="..\..\Source\Processors\RecordNode\RecordEngine.h"/>
     <ClInclude Include="..\..\Source\Processors\RecordNode\RecordNode.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\tictoc.h"/>
-    <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h"/>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNode.h"/>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.h"/>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.h"/>
     <ClInclude Include="..\..\Source\Processors\Splitter\Splitter.h"/>
     <ClInclude Include="..\..\Source\Processors\Splitter\SplitterEditor.h"/>
     <ClInclude Include="..\..\Source\Processors\Visualization\DataWindow.h"/>
diff --git a/Builds/VisualStudio2013/open-ephys.vcxproj.filters b/Builds/VisualStudio2013/open-ephys.vcxproj.filters
index 298fb977c9c392374c1d2a5a24db56eb6839c529..dec0240c80939f97cdf91317b27a0bf2e98ce035 100644
--- a/Builds/VisualStudio2013/open-ephys.vcxproj.filters
+++ b/Builds/VisualStudio2013/open-ephys.vcxproj.filters
@@ -32,9 +32,6 @@
     <Filter Include="open-ephys\Source\Processors">
       <UniqueIdentifier>{3DDEC88C-BAA5-2DDA-A59F-0FB74070AB82}</UniqueIdentifier>
     </Filter>
-    <Filter Include="open-ephys\Source\Processors\NetworkEvents">
-      <UniqueIdentifier>{C41A0CBC-4C1C-5AC2-CAED-3EC41B4BAB37}</UniqueIdentifier>
-    </Filter>
     <Filter Include="open-ephys\Source\Processors\ProcessorManager">
       <UniqueIdentifier>{C84577BE-2445-2454-C134-006B7BCF320C}</UniqueIdentifier>
     </Filter>
@@ -77,18 +74,9 @@
     <Filter Include="open-ephys\Source\Processors\RecordNode">
       <UniqueIdentifier>{185877A6-9FE6-DD2E-BC41-93EE3C608CFC}</UniqueIdentifier>
     </Filter>
-    <Filter Include="open-ephys\Source\Processors\PSTH">
-      <UniqueIdentifier>{2714D3F1-1A51-5CEC-5EE2-26686D9EEAF8}</UniqueIdentifier>
-    </Filter>
     <Filter Include="open-ephys\Source\Processors\SourceNode">
       <UniqueIdentifier>{83A3043C-94AE-ADED-C72B-394EB4BAE6B4}</UniqueIdentifier>
     </Filter>
-    <Filter Include="open-ephys\Source\Processors\SpikeDisplayNode">
-      <UniqueIdentifier>{818E5C85-5930-DC8D-A3C2-0443F4C35B47}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="open-ephys\Source\Processors\SpikeSorter">
-      <UniqueIdentifier>{11B5BECA-5948-83BC-3C0F-DEB527800990}</UniqueIdentifier>
-    </Filter>
     <Filter Include="open-ephys\Source\Processors\Splitter">
       <UniqueIdentifier>{2AAA8664-72AA-EC5C-92E2-3392067B058F}</UniqueIdentifier>
     </Filter>
@@ -409,12 +397,6 @@
     <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp">
       <Filter>open-ephys\Source\Audio</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.cpp">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.cpp">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.cpp">
       <Filter>open-ephys\Source\Processors\ProcessorManager</Filter>
     </ClCompile>
@@ -502,9 +484,6 @@
     <ClCompile Include="..\..\Source\Processors\Editors\VisualizerEditor.cpp">
       <Filter>open-ephys\Source\Processors\Editors</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\FileReader\KwikFileSource.cpp">
-      <Filter>open-ephys\Source\Processors\FileReader</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\FileReader\FileSource.cpp">
       <Filter>open-ephys\Source\Processors\FileReader</Filter>
     </ClCompile>
@@ -550,45 +529,12 @@
     <ClCompile Include="..\..\Source\Processors\RecordNode\RecordNode.cpp">
       <Filter>open-ephys\Source\Processors\RecordNode</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\tictoc.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNode.cpp">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClCompile>
     <ClCompile Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.cpp">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.cpp">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\Splitter\Splitter.cpp">
       <Filter>open-ephys\Source\Processors\Splitter</Filter>
     </ClCompile>
@@ -1890,12 +1836,6 @@
     <ClInclude Include="..\..\Source\Audio\AudioComponent.h">
       <Filter>open-ephys\Source\Audio</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEventsEditor.h">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\NetworkEvents\NetworkEvents.h">
-      <Filter>open-ephys\Source\Processors\NetworkEvents</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\ProcessorManager\ProcessorManager.h">
       <Filter>open-ephys\Source\Processors\ProcessorManager</Filter>
     </ClInclude>
@@ -2004,9 +1944,6 @@
     <ClInclude Include="..\..\Source\Processors\Editors\VisualizerEditor.h">
       <Filter>open-ephys\Source\Processors\Editors</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\FileReader\KwikFileSource.h">
-      <Filter>open-ephys\Source\Processors\FileReader</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\FileReader\FileSource.h">
       <Filter>open-ephys\Source\Processors\FileReader</Filter>
     </ClInclude>
@@ -2052,45 +1989,12 @@
     <ClInclude Include="..\..\Source\Processors\RecordNode\RecordNode.h">
       <Filter>open-ephys\Source\Processors\RecordNode</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramEditor.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\tictoc.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h">
-      <Filter>open-ephys\Source\Processors\PSTH</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNode.h">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClInclude>
     <ClInclude Include="..\..\Source\Processors\SourceNode\SourceNodeEditor.h">
       <Filter>open-ephys\Source\Processors\SourceNode</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayCanvas.h">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayEditor.h">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode\SpikeDisplayNode.h">
-      <Filter>open-ephys\Source\Processors\SpikeDisplayNode</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSortBoxes.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorter.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterCanvas.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Source\Processors\SpikeSorter\SpikeSorterEditor.h">
-      <Filter>open-ephys\Source\Processors\SpikeSorter</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\Splitter\Splitter.h">
       <Filter>open-ephys\Source\Processors\Splitter</Filter>
     </ClInclude>
diff --git a/Source/Processors/FileReader/KwikFileSource.cpp b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.cpp
similarity index 100%
rename from Source/Processors/FileReader/KwikFileSource.cpp
rename to Source/Plugins/KWIKFormat/FileSource/KwikFileSource.cpp
diff --git a/Source/Processors/FileReader/KwikFileSource.h b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h
similarity index 93%
rename from Source/Processors/FileReader/KwikFileSource.h
rename to Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h
index b70d98e377549b9dd4577c3ddc6b08de822c7706..810559109601e175053851c4e7eb58eef80d357a 100644
--- a/Source/Processors/FileReader/KwikFileSource.h
+++ b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h
@@ -24,8 +24,8 @@
 #ifndef KWIKFILESOURCE_H_INCLUDED
 #define KWIKFILESOURCE_H_INCLUDED
 
-#include "../../../JuceLibraryCode/JuceHeader.h"
-#include "FileSource.h"
+#include "../../../../JuceLibraryCode/JuceHeader.h"
+#include "../../../Processors/FileReader/FileSource.h"
 
 #define MIN_KWIK_VERSION 2
 #define MAX_KWIK_VERSION 2
diff --git a/Source/Processors/RecordNode/KWIKEngine/OpenEphysLib.cpp b/Source/Plugins/KWIKFormat/OpenEphysLib.cpp
similarity index 80%
rename from Source/Processors/RecordNode/KWIKEngine/OpenEphysLib.cpp
rename to Source/Plugins/KWIKFormat/OpenEphysLib.cpp
index bb23d4dbcb1a938b245930d673315ec9a5617356..0f1bcc90d6ca7c834c8008e519c7c0b22a200482 100644
--- a/Source/Processors/RecordNode/KWIKEngine/OpenEphysLib.cpp
+++ b/Source/Plugins/KWIKFormat/OpenEphysLib.cpp
@@ -21,8 +21,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 
-#include "../../PluginManager/OpenEphysPlugin.h"
-#include "HDF5Recording.h"
+#include "../../Processors/PluginManager/OpenEphysPlugin.h"
+#include "RecordEngine/HDF5Recording.h"
+#include "FileSource/KwikFileSource.h"
 #include <string>
 #ifdef WIN32
 #include <Windows.h>
@@ -33,7 +34,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 using namespace Plugin;
-#define NUM_PLUGINS 1
+#define NUM_PLUGINS 2
 
 extern "C" EXPORT void getLibInfo(Plugin::LibraryInfo* info)
 {
@@ -51,6 +52,12 @@ extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info)
 		strcpy(info->recordEngine.name, "Kwik");
 		info->recordEngine.creator = &(Plugin::createRecordEngine<HDF5Recording>);
 		break;
+	case 1:
+		info->type = Plugin::FileSourcePlugin;
+		strcpy(info->fileSource.name, "Kwd file");
+		strcpy(info->fileSource.extensions, "kwd");
+		info->fileSource.creator = &(Plugin::createFileSource<KWIKFileSource>);
+		break;
 	default:
 		return -1;
 	}
diff --git a/Source/Processors/RecordNode/KWIKEngine/HDF5FileFormat.cpp b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp
similarity index 100%
rename from Source/Processors/RecordNode/KWIKEngine/HDF5FileFormat.cpp
rename to Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp
diff --git a/Source/Processors/RecordNode/KWIKEngine/HDF5FileFormat.h b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h
similarity index 100%
rename from Source/Processors/RecordNode/KWIKEngine/HDF5FileFormat.h
rename to Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h
diff --git a/Source/Processors/RecordNode/KWIKEngine/HDF5Recording.cpp b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp
similarity index 100%
rename from Source/Processors/RecordNode/KWIKEngine/HDF5Recording.cpp
rename to Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp
diff --git a/Source/Processors/RecordNode/KWIKEngine/HDF5Recording.h b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h
similarity index 97%
rename from Source/Processors/RecordNode/KWIKEngine/HDF5Recording.h
rename to Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h
index 7e236251b7d54367bc4b91229545518a3689c4e7..d0707d5a6dc09f5b8fae717e4cbba5b63849d661 100644
--- a/Source/Processors/RecordNode/KWIKEngine/HDF5Recording.h
+++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h
@@ -24,7 +24,7 @@
 #ifndef HDF5RECORDING_H_INCLUDED
 #define HDF5RECORDING_H_INCLUDED
 
-#include "../RecordEngine.h"
+#include "../../../Processors/RecordNode/RecordEngine.h"
 #include "HDF5FileFormat.h"
 
 class HDF5Recording : public RecordEngine
diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp
old mode 100755
new mode 100644
similarity index 96%
rename from Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp
rename to Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp
index fbd097fcd20d07fdf3fbbf972f85b146666f6e44..87b9778be62e780b8f7c57b9aa3e9b14920e65fa
--- a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp
+++ b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp
@@ -1,2141 +1,2141 @@
-/*
-------------------------------------------------------------------
-
-This file is part of the Open Ephys GUI
-Copyright (C) 2013 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 "LfpDisplayCanvas.h"
-
-#include <math.h>
-
-LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) :
-     timebase(1.0f), displayGain(1.0f),   timeOffset(0.0f),
-    processor(processor_), selectedChannelType(HEADSTAGE_CHANNEL)
-{
-
-    nChans = processor->getNumInputs();
-    std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl;
-
-    displayBuffer = processor->getDisplayBufferAddress();
-    displayBufferSize = displayBuffer->getNumSamples();
-    std::cout << "Setting displayBufferSize on LfpDisplayCanvas to " << displayBufferSize << std::endl;
-
-    screenBuffer = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
-    screenBuffer->clear();
-
-    screenBufferMin = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
-    screenBufferMin->clear();
-    screenBufferMean = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
-    screenBufferMean->clear();
-    screenBufferMax = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
-    screenBufferMax->clear();
-
-    viewport = new LfpViewport(this);
-    lfpDisplay = new LfpDisplay(this, viewport);
-    timescale = new LfpTimescale(this);
-
-    timescale->setTimebase(timebase);
-
-    viewport->setViewedComponent(lfpDisplay, false);
-    viewport->setScrollBarsShown(true, false);
-
-    scrollBarThickness = viewport->getScrollBarThickness();
-
-    isChannelEnabled.insertMultiple(0,true,10000); // max 10k channels
-
-    //viewport->getVerticalScrollBar()->addListener(this->scrollBarMoved(viewport->getVerticalScrollBar(), 1.0));
-
-    UtilityButton* tbut;
-
-    addAndMakeVisible(viewport);
-    addAndMakeVisible(timescale);
-
-    //Ranges for neural data
-     voltageRanges[HEADSTAGE_CHANNEL].add("25");
-    voltageRanges[HEADSTAGE_CHANNEL].add("50");
-    voltageRanges[HEADSTAGE_CHANNEL].add("100");
-    voltageRanges[HEADSTAGE_CHANNEL].add("250");
-    voltageRanges[HEADSTAGE_CHANNEL].add("400");
-    voltageRanges[HEADSTAGE_CHANNEL].add("500");
-    voltageRanges[HEADSTAGE_CHANNEL].add("750");
-    voltageRanges[HEADSTAGE_CHANNEL].add("1000");
-    voltageRanges[HEADSTAGE_CHANNEL].add("2000");
-    voltageRanges[HEADSTAGE_CHANNEL].add("5000");
-    voltageRanges[HEADSTAGE_CHANNEL].add("10000");
-    selectedVoltageRange[HEADSTAGE_CHANNEL] = 8;
-    rangeGain[HEADSTAGE_CHANNEL] = 1; //uV
-    rangeSteps[HEADSTAGE_CHANNEL] = 10;
-    rangeUnits.add("uV");
-    typeNames.add("DATA");
-
-    tbut = new UtilityButton("DATA",Font("Small Text", 9, Font::plain));
-    tbut->setEnabledState(true);
-    tbut->setCorners(false,false,false,false);
-    tbut->addListener(this);
-    tbut->setClickingTogglesState(true);
-    tbut->setRadioGroupId(100,dontSendNotification);
-    tbut->setToggleState(true,dontSendNotification);
-    addAndMakeVisible(tbut);
-    typeButtons.add(tbut);
-    
-    //Ranges for AUX/accelerometer data
-    voltageRanges[AUX_CHANNEL].add("25");
-    voltageRanges[AUX_CHANNEL].add("50");
-    voltageRanges[AUX_CHANNEL].add("100");
-    voltageRanges[AUX_CHANNEL].add("250");
-    voltageRanges[AUX_CHANNEL].add("400");
-    voltageRanges[AUX_CHANNEL].add("500");
-    voltageRanges[AUX_CHANNEL].add("750");
-    voltageRanges[AUX_CHANNEL].add("1000");
-    voltageRanges[AUX_CHANNEL].add("2000");
-    //voltageRanges[AUX_CHANNEL].add("5000");
-    selectedVoltageRange[AUX_CHANNEL] = 9;
-    rangeGain[AUX_CHANNEL] = 0.001; //mV
-    rangeSteps[AUX_CHANNEL] = 10;
-    rangeUnits.add("mV");
-    typeNames.add("AUX");
-
-    tbut = new UtilityButton("AUX",Font("Small Text", 9, Font::plain));
-    tbut->setEnabledState(true);
-    tbut->setCorners(false,false,false,false);
-    tbut->addListener(this);
-    tbut->setClickingTogglesState(true);
-    tbut->setRadioGroupId(100,dontSendNotification);
-    tbut->setToggleState(false,dontSendNotification);
-    addAndMakeVisible(tbut);
-    typeButtons.add(tbut);
-
-    //Ranges for ADC data
-     voltageRanges[ADC_CHANNEL].add("0.01");
-    voltageRanges[ADC_CHANNEL].add("0.05");
-    voltageRanges[ADC_CHANNEL].add("0.1");
-    voltageRanges[ADC_CHANNEL].add("0.5");
-    voltageRanges[ADC_CHANNEL].add("1.0");
-    voltageRanges[ADC_CHANNEL].add("2.0");
-    voltageRanges[ADC_CHANNEL].add("5.0");
-    voltageRanges[ADC_CHANNEL].add("10.0");
-    selectedVoltageRange[ADC_CHANNEL] = 8;
-    rangeGain[ADC_CHANNEL] = 1; //V
-    rangeSteps[ADC_CHANNEL] = 0.1; //in V
-    rangeUnits.add("V");
-    typeNames.add("ADC");
-
-    tbut = new UtilityButton("ADC",Font("Small Text", 9, Font::plain));
-    tbut->setEnabledState(true);
-    tbut->setCorners(false,false,false,false);
-    tbut->addListener(this);
-    tbut->setClickingTogglesState(true);
-    tbut->setRadioGroupId(100,dontSendNotification);
-    tbut->setToggleState(false,dontSendNotification);
-    addAndMakeVisible(tbut);
-    typeButtons.add(tbut);
-
-    selectedVoltageRangeValues[HEADSTAGE_CHANNEL] = voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1];
-    selectedVoltageRangeValues[AUX_CHANNEL] = voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL]-1];
-    selectedVoltageRangeValues[ADC_CHANNEL] = voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL]-1];
-
-    timebases.add("0.25");
-    timebases.add("0.5");
-    timebases.add("1.0");
-    timebases.add("2.0");
-    timebases.add("3.0");
-    timebases.add("4.0");
-    timebases.add("5.0");
-    timebases.add("10.0");
-    timebases.add("20.0");
-    selectedTimebase = 4;
-    selectedTimebaseValue = timebases[selectedTimebase-1];
-
-    spreads.add("10");
-    spreads.add("20");
-    spreads.add("30");
-    spreads.add("40");
-    spreads.add("50");
-    spreads.add("60");
-    spreads.add("70");
-    spreads.add("80");
-    spreads.add("90");
-    spreads.add("100");
-    selectedSpread = 5;
-    selectedSpreadValue = spreads[selectedSpread-1];
-
-    colorGroupings.add("1");
-    colorGroupings.add("2");
-    colorGroupings.add("4");
-    colorGroupings.add("8");
-    colorGroupings.add("16");
-
-
-    rangeSelection = new ComboBox("Voltage range");
-    rangeSelection->addItemList(voltageRanges[HEADSTAGE_CHANNEL], 1);
-    rangeSelection->setSelectedId(selectedVoltageRange[HEADSTAGE_CHANNEL], sendNotification);
-    rangeSelection->setEditableText(true);
-    rangeSelection->addListener(this);
-    addAndMakeVisible(rangeSelection);
-
-
-    timebaseSelection = new ComboBox("Timebase");
-    timebaseSelection->addItemList(timebases, 1);
-    timebaseSelection->setSelectedId(selectedTimebase, sendNotification);
-    timebaseSelection->setEditableText(true);
-    timebaseSelection->addListener(this);
-    addAndMakeVisible(timebaseSelection);
-
-
-    spreadSelection = new ComboBox("Spread");
-    spreadSelection->addItemList(spreads, 1);
-    spreadSelection->setSelectedId(selectedSpread,sendNotification);
-    spreadSelection->addListener(this);
-    spreadSelection->setEditableText(true);
-    addAndMakeVisible(spreadSelection);
-
-    colorGroupingSelection = new ComboBox("Color Grouping");
-    colorGroupingSelection->addItemList(colorGroupings, 1);
-    colorGroupingSelection->setSelectedId(1,sendNotification);
-    colorGroupingSelection->addListener(this);
-    addAndMakeVisible(colorGroupingSelection);
-
-    invertInputButton = new UtilityButton("Invert", Font("Small Text", 13, Font::plain));
-    invertInputButton->setRadius(5.0f);
-    invertInputButton->setEnabledState(true);
-    invertInputButton->setCorners(true, true, true, true);
-    invertInputButton->addListener(this);
-    invertInputButton->setClickingTogglesState(true);
-    invertInputButton->setToggleState(false, sendNotification);
-    addAndMakeVisible(invertInputButton);
-
-    //button for controlling drawing algorithm - old line-style or new per-pixel style
-    drawMethodButton = new UtilityButton("DrawMethod", Font("Small Text", 13, Font::plain));
-    drawMethodButton->setRadius(5.0f);
-    drawMethodButton->setEnabledState(true);
-    drawMethodButton->setCorners(true, true, true, true);
-    drawMethodButton->addListener(this);
-    drawMethodButton->setClickingTogglesState(true);
-    drawMethodButton->setToggleState(false, sendNotification);
-    addAndMakeVisible(drawMethodButton);
-
-    //button for pausing the display - works by skipping buffer updates. This way scrolling etc still works
-    pauseButton = new UtilityButton("Pause", Font("Small Text", 13, Font::plain));
-    pauseButton->setRadius(5.0f);
-    pauseButton->setEnabledState(true);
-    pauseButton->setCorners(true, true, true, true);
-    pauseButton->addListener(this);
-    pauseButton->setClickingTogglesState(true);
-    pauseButton->setToggleState(false, sendNotification);
-    addAndMakeVisible(pauseButton);
-
-
-    lfpDisplay->setNumChannels(nChans);
-    lfpDisplay->setRange(voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1].getFloatValue()*rangeGain[HEADSTAGE_CHANNEL]
-        ,HEADSTAGE_CHANNEL);
-	lfpDisplay->setRange(voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL] - 1].getFloatValue()*rangeGain[ADC_CHANNEL]
-		, ADC_CHANNEL);
-	lfpDisplay->setRange(voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL] - 1].getFloatValue()*rangeGain[AUX_CHANNEL]
-		, AUX_CHANNEL);
-
-    // add event display-specific controls (currently just an enable/disable button)
-    for (int i = 0; i < 8; i++)
-    {
-
-        EventDisplayInterface* eventOptions = new EventDisplayInterface(lfpDisplay, this, i);
-        eventDisplayInterfaces.add(eventOptions);
-        addAndMakeVisible(eventOptions);
-        eventOptions->setBounds(500+(floor(i/2)*20), getHeight()-20-(i%2)*20, 40, 20);
-
-        lfpDisplay->setEventDisplayState(i,true);
-
-    }
-
-    TopLevelWindow::getTopLevelWindow(0)->addKeyListener(this);
-}
-
-LfpDisplayCanvas::~LfpDisplayCanvas()
-{
-
-    deleteAndZero(screenBuffer);
-    deleteAndZero(screenBufferMin);
-    deleteAndZero(screenBufferMean);
-    deleteAndZero(screenBufferMax);
-
-    TopLevelWindow::getTopLevelWindow(0)->removeKeyListener(this);
-}
-
-void LfpDisplayCanvas::resized()
-{
-
-    timescale->setBounds(leftmargin,0,getWidth()-scrollBarThickness-leftmargin,30);
-    viewport->setBounds(0,30,getWidth(),getHeight()-90);
-
-    if (lfpDisplay->getSingleChannelState())
-        lfpDisplay->setChannelHeight(viewport->getHeight(),false);
-
-    lfpDisplay->setBounds(0,0,getWidth()-scrollBarThickness, lfpDisplay->getChannelHeight()*nChans);
-
-    rangeSelection->setBounds(5,getHeight()-30,100,25);
-    timebaseSelection->setBounds(175,getHeight()-30,100,25);
-    spreadSelection->setBounds(345,getHeight()-30,100,25);
-    colorGroupingSelection->setBounds(620,getHeight()-30,100,25);
-
-    invertInputButton->setBounds(750,getHeight()-50,100,22);
-    drawMethodButton->setBounds(750,getHeight()-25,100,22);
-    pauseButton->setBounds(880,getHeight()-50,50,44);
-
-    for (int i = 0; i < 8; i++)
-    {
-        eventDisplayInterfaces[i]->setBounds(500+(floor(i/2)*20), getHeight()-40+(i%2)*20, 40, 20); // arrange event channel buttons in two rows
-        eventDisplayInterfaces[i]->repaint();
-    }
-
-    int bh = 25/typeButtons.size();
-    for (int i = 0; i < typeButtons.size(); i++)
-    {
-        typeButtons[i]->setBounds(110,getHeight()-30+i*bh,50,bh);
-    }
-    // std::cout << "Canvas thinks LfpDisplay should be this high: "
-    //  << lfpDisplay->getTotalHeight() << std::endl;
-
-}
-
-void LfpDisplayCanvas::beginAnimation()
-{
-    std::cout << "Beginning animation." << std::endl;
-
-    displayBufferSize = displayBuffer->getNumSamples();
-
-    for (int i = 0; i < screenBufferIndex.size(); i++)
-    {
-        screenBufferIndex.set(i,0);
-    }
-
-    startCallbacks();
-}
-
-void LfpDisplayCanvas::endAnimation()
-{
-    std::cout << "Ending animation." << std::endl;
-
-    stopCallbacks();
-}
-
-void LfpDisplayCanvas::update()
-{
-    nChans = jmax(processor->getNumInputs(),1);
-
-    sampleRate.clear();
-    screenBufferIndex.clear();
-    lastScreenBufferIndex.clear();
-    displayBufferIndex.clear();
-
-    for (int i = 0; i <= nChans; i++) // extra channel for events
-    {
-		if (processor->getNumInputs() > 0)
-		{
-			if (i < nChans)
-				sampleRate.add(processor->channels[i]->sampleRate);
-			else
-				sampleRate.add(processor->channels[i - 1]->sampleRate); // for event channel (IT'S A HACK -- BE CAREFUL!)
-		}
-		else
-			sampleRate.add(30000);
-        
-       // std::cout << "Sample rate for ch " << i << " = " << sampleRate[i] << std::endl; 
-        displayBufferIndex.add(0);
-        screenBufferIndex.add(0);
-        lastScreenBufferIndex.add(0);
-    }
-
-
-
-    if (nChans != lfpDisplay->getNumChannels())
-    {
-        //std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl;
-
-        refreshScreenBuffer();
-
-        lfpDisplay->setNumChannels(nChans); // add an extra channel for events
-
-        // update channel names
-        for (int i = 0; i < processor->getNumInputs(); i++)
-        {
-
-            String chName = processor->channels[i]->getName();
-
-            //std::cout << chName << std::endl;
-
-            lfpDisplay->channelInfo[i]->setName(chName);
-            lfpDisplay->enableChannel(isChannelEnabled[i], i);
-
-        }
-
-        lfpDisplay->setBounds(0,0,getWidth()-scrollBarThickness*2, lfpDisplay->getTotalHeight());
-
-        resized();
-    }
-    else
-    {
-        for (int i = 0; i < processor->getNumInputs(); i++)
-        {
-            lfpDisplay->channels[i]->updateType();
-            lfpDisplay->channelInfo[i]->updateType();
-        }
-        
-    }
-
-}
-
-void LfpDisplayCanvas::buttonClicked(Button* b)
-{
-    if (b == invertInputButton)
-    {
-        lfpDisplay->setInputInverted(b->getToggleState());
-        return;
-    }
-    if (b == drawMethodButton)
-    {
-        lfpDisplay->setDrawMethod(b->getToggleState());
-        return;
-    }
-    if (b == pauseButton)
-    {
-        lfpDisplay->isPaused = b->getToggleState();
-        return;
-    }
-
-    int idx = typeButtons.indexOf((UtilityButton*)b);
-    if ((idx >= 0) && (b->getToggleState()))
-    {
-        for (int i = 0; i < processor->getNumInputs(); i++)
-        {
-            if (lfpDisplay->channels[i]->getSelected())
-            {
-                lfpDisplay->channels[i]->deselect();
-                lfpDisplay->channels[i]->repaint();
-            }
-        }  
-        setSelectedType((ChannelType) idx, false);
-    }
-
-}
-
-
-void LfpDisplayCanvas::comboBoxChanged(ComboBox* cb)
-{
-
-    if (cb == timebaseSelection)
-    {
-        if (cb->getSelectedId())
-        {
-            timebase = timebases[cb->getSelectedId()-1].getFloatValue();
-        }
-        else
-        {
-            timebase = cb->getText().getFloatValue();
-            if (timebase)
-            {
-                if (timebase < timebases[0].getFloatValue())
-                {
-                    cb->setSelectedId(1,dontSendNotification);
-                    timebase = timebases[0].getFloatValue();
-                }
-                else if (timebase > timebases[timebases.size()-1].getFloatValue())
-                {
-                    cb->setSelectedId(timebases.size(),dontSendNotification);
-                    timebase = timebases[timebases.size()-1].getFloatValue();
-                }
-                else
-                    cb->setText(String(timebase,1),dontSendNotification);
-            }
-            else
-            {
-                if (selectedSpread == 0)
-                {
-                    cb->setText(selectedTimebaseValue,dontSendNotification);
-                    timebase = selectedTimebaseValue.getFloatValue();
-                }
-                else
-                {
-                    cb->setSelectedId(selectedTimebase,dontSendNotification);
-                    timebase = timebases[selectedTimebase-1].getFloatValue();
-                }
-
-            }
-        }
-    }
-    else if (cb == rangeSelection)
-    {
-        if (cb->getSelectedId())
-        {
-        lfpDisplay->setRange(voltageRanges[selectedChannelType][cb->getSelectedId()-1].getFloatValue()*rangeGain[selectedChannelType]
-            ,selectedChannelType);
-        }
-        else
-        {
-            float vRange = cb->getText().getFloatValue();
-            if (vRange)
-            {
-                if (vRange < voltageRanges[selectedChannelType][0].getFloatValue())
-                {
-                    cb->setSelectedId(1,dontSendNotification);
-                    vRange = voltageRanges[selectedChannelType][0].getFloatValue();
-                }
-                else if (vRange > voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue())
-                {
-                    cb->setSelectedId(voltageRanges[selectedChannelType].size(),dontSendNotification);
-                    vRange = voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue();
-                }
-                else
-                {
-                    if (rangeGain[selectedChannelType] > 1)
-                        cb->setText(String(vRange,1),dontSendNotification);
-                    else
-                        cb->setText(String(vRange),dontSendNotification);
-                }
-                lfpDisplay->setRange(vRange*rangeGain[selectedChannelType],selectedChannelType);
-            }
-            else
-            {
-                if (selectedVoltageRange[selectedChannelType])
-                    cb->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification);
-                else
-                    cb->setSelectedId(selectedVoltageRange[selectedChannelType],dontSendNotification);
-            }
-        }
-        selectedVoltageRange[selectedChannelType] = cb->getSelectedId();
-        selectedVoltageRangeValues[selectedChannelType] = cb->getText();
-        //std::cout << "Setting range to " << voltageRanges[cb->getSelectedId()-1].getFloatValue() << std::endl;
-    }
-    else if (cb == spreadSelection)
-    {
-        if (cb->getSelectedId())
-        {
-            lfpDisplay->setChannelHeight(spreads[cb->getSelectedId()-1].getIntValue());
-            resized();
-        }
-        else
-        {
-            int spread = cb->getText().getIntValue();
-            if (spread)
-            {
-                if (spread < spreads[0].getFloatValue())
-                {
-                    cb->setSelectedId(1,dontSendNotification);
-                    spread = spreads[0].getFloatValue();
-                }
-                else if (spread > spreads[spreads.size()-1].getFloatValue())
-                {
-                    cb->setSelectedId(spreads.size(),dontSendNotification);
-                    spread = spreads[spreads.size()-1].getFloatValue();
-                }
-                else
-                {
-                    cb->setText(String(spread),dontSendNotification);
-                }
-                lfpDisplay->setChannelHeight(spread);
-                resized();
-            }
-            else
-            {
-                if (selectedSpread == 0)
-                    cb->setText(selectedSpreadValue,dontSendNotification);
-                else
-                    cb->setSelectedId(selectedSpread,dontSendNotification);
-            }
-        }
-        selectedSpread = cb->getSelectedId();
-        selectedSpreadValue = cb->getText();
-        //std::cout << "Setting spread to " << spreads[cb->getSelectedId()-1].getFloatValue() << std::endl;
-    }
-    else if (cb == colorGroupingSelection)
-    {
-        // set color grouping hre
-
-        lfpDisplay->setColorGrouping(colorGroupings[cb->getSelectedId()-1].getIntValue());// so that channel colors get re-assigned
-
-    }
-
-    timescale->setTimebase(timebase);
-}
-
-
-int LfpDisplayCanvas::getChannelHeight()
-{
-    return spreads[spreadSelection->getSelectedId()-1].getIntValue();
-}
-
-
-void LfpDisplayCanvas::setParameter(int param, float val)
-{
-    // not used for anything, since LfpDisplayCanvas is not a processor
-}
-
-void LfpDisplayCanvas:: setRangeSelection(float range, bool canvasMustUpdate)
-{
-    if (canvasMustUpdate)
-    {
-        rangeSelection->setText(String(range/rangeGain[selectedChannelType]), sendNotification); 
-    }
-    else
-    {
-        rangeSelection->setText(String(range/rangeGain[selectedChannelType]),dontSendNotification);
-        selectedVoltageRange[selectedChannelType]=rangeSelection->getSelectedId();
-        selectedVoltageRangeValues[selectedChannelType]=rangeSelection->getText();
-
-        repaint();
-        refresh();
-    }
-
-}
-
-void LfpDisplayCanvas:: setSpreadSelection(int spread, bool canvasMustUpdate)
-{
-    if (canvasMustUpdate)
-    {
-        spreadSelection->setText(String(spread),sendNotification);
-    }
-    else
-    {
-        spreadSelection->setText(String(spread),dontSendNotification);
-        selectedSpread=spreadSelection->getSelectedId();
-        selectedSpreadValue=spreadSelection->getText();
-
-        repaint();
-        refresh();
-    }
-}
-
-void LfpDisplayCanvas::refreshState()
-{
-    // called when the component's tab becomes visible again
-
-    for (int i = 0; i <= displayBufferIndex.size(); i++) // include event channel
-    {
-
-        displayBufferIndex.set(i, processor->getDisplayBufferIndex(i));
-        screenBufferIndex.set(i,0);
-    }
-
-}
-
-void LfpDisplayCanvas::refreshScreenBuffer()
-{
-
-    for (int i = 0; i < screenBufferIndex.size(); i++)
-        screenBufferIndex.set(i,0);
-
-    screenBuffer->clear();
-    screenBufferMin->clear();
-    screenBufferMean->clear();
-    screenBufferMax->clear();
-
-
-    // int w = lfpDisplay->getWidth();
-    // //std::cout << "Refreshing buffer size to " << w << "pixels." << std::endl;
-
-    // for (int i = 0; i < w; i++)
-    // {
-    //  float x = float(i);
-
-    //  for (int n = 0; n < nChans; n++)
-    //  {
-    //      waves[n][i*2] = x;
-    //      waves[n][i*2+1] = 0.5f; // line in center of display
-    //  }
-    // }
-
-}
-
-void LfpDisplayCanvas::updateScreenBuffer()
-{
-
-    // copy new samples from the displayBuffer into the screenBuffer
-    int maxSamples = lfpDisplay->getWidth() - leftmargin;
-
-	ScopedLock displayLock(*processor->getMutex());
-
-    for (int channel = 0; channel <= nChans; channel++) // pull one extra channel for event display
-    {
-
-        if (screenBufferIndex[channel] >= maxSamples) // wrap around if we reached right edge before
-            screenBufferIndex.set(channel, 0);
-
-         // hold these values locally for each channel
-        int sbi = screenBufferIndex[channel];
-        int dbi = displayBufferIndex[channel];
-
-        lastScreenBufferIndex.set(channel,sbi);
-
-        int index = processor->getDisplayBufferIndex(channel);
-
-        int nSamples =  index - dbi; // N new samples (not pixels) to be added to displayBufferIndex
-
-        if (nSamples < 0) // buffer has reset to 0
-        {
-            nSamples = (displayBufferSize - dbi) + index;
-        }
-
-        //if (channel == 15 || channel == 16)
-        //     std::cout << channel << " " << sbi << " " << dbi << " " << nSamples << std::endl;
-
-
-        float ratio = sampleRate[channel] * timebase / float(getWidth() - leftmargin - scrollBarThickness); // samples / pixel
-        // this number is crucial: converting from samples to values (in px) for the screen buffer
-        int valuesNeeded = (int) float(nSamples) / ratio; // N pixels needed for this update
-
-        if (sbi + valuesNeeded > maxSamples)  // crop number of samples to fit canvas width
-        {
-            valuesNeeded = maxSamples - sbi;
-        }
-        float subSampleOffset = 0.0;
-
-        dbi %= displayBufferSize; // make sure we're not overshooting
-        int nextPos = (dbi + 1) % displayBufferSize; //  position next to displayBufferIndex in display buffer to copy from
-
-        // if (channel == 0)
-        //     std::cout << "Channel " 
-        //               << channel << " : " 
-        //               << sbi << " : " 
-        //               << index << " : " 
-        //               << dbi << " : " 
-        //               << valuesNeeded << " : " 
-        //               << ratio 
-        //                             << std::endl;
-
-        if (valuesNeeded > 0 && valuesNeeded < 10000)
-        {
-            for (int i = 0; i < valuesNeeded; i++) // also fill one extra sample for line drawing interpolation to match across draws
-            {
-                //If paused don't update screen buffers, but update all indexes as needed
-                if (!lfpDisplay->isPaused)
-                {
-                    float gain = 1.0;
-                    float alpha = (float) subSampleOffset;
-                    float invAlpha = 1.0f - alpha;
-
-                    screenBuffer->clear(channel, sbi, 1);
-                    screenBufferMin->clear(channel, sbi, 1);
-                    screenBufferMean->clear(channel, sbi, 1);
-                    screenBufferMax->clear(channel, sbi, 1);
-
-                     dbi %= displayBufferSize; // just to be sure
-
-                    // interpolate between two samples with invAlpha and alpha
-                    screenBuffer->addFrom(channel, // destChannel
-                                          sbi, // destStartSample
-                                          displayBuffer->getReadPointer(channel, dbi), // source
-                                          1, // numSamples
-                                          invAlpha*gain); // gain
-
-
-                    screenBuffer->addFrom(channel, // destChannel
-                                          sbi, // destStartSample
-                                          displayBuffer->getReadPointer(channel, nextPos), // source
-                                          1, // numSamples
-                                          alpha*gain); // gain
-
-                    // same thing again, but this time add the min,mean, and max of all samples in current pixel
-                    float sample_min   =  1000000;
-                    float sample_max   = -1000000;
-                    float sample_mean  =  0;
-                    int c = 0;
-                    int nextpix = (dbi +(int)ratio) % displayBufferSize; //  position to next pixels index
-                    
-                    for (int j = dbi; j < nextpix; j++)
-                    {
-                        float sample_current = displayBuffer->getSample(channel, j);
-                        sample_mean = sample_mean + sample_current;
-
-                        if (sample_min>sample_current)
-                        {
-                            sample_min=sample_current;
-                        }
-
-                        if (sample_max<sample_current)
-                        {
-                            sample_max=sample_current;
-                        }
-                        c++;
-
-                    }
-
-                    sample_mean = sample_mean/c;
-                    screenBufferMean->addSample(channel, sbi, sample_mean*gain);
-                    screenBufferMin->addSample(channel, sbi, sample_min*gain);
-                    screenBufferMax->addSample(channel, sbi, sample_max*gain);
-                
-                sbi++;
-                }
-            
-            subSampleOffset += ratio;
-
-            while (subSampleOffset >= 1.0)
-            {
-                if (++dbi > displayBufferSize)
-                    dbi = 0;
-
-                nextPos = (dbi + 1) % displayBufferSize;
-                subSampleOffset -= 1.0;
-            }
-
-        }
-
-        // update values after we're done
-        screenBufferIndex.set(channel, sbi);
-        displayBufferIndex.set(channel, dbi);
-        }
-
-    }
-
-}
-
-const float LfpDisplayCanvas::getXCoord(int chan, int samp)
-{
-    return samp;
-}
-
-int LfpDisplayCanvas::getNumChannels()
-{
-    return nChans;
-}
-
-const float LfpDisplayCanvas::getYCoord(int chan, int samp)
-{
-    return *screenBuffer->getReadPointer(chan, samp);
-}
-
-const float LfpDisplayCanvas::getYCoordMean(int chan, int samp)
-{
-    return *screenBufferMean->getReadPointer(chan, samp);
-}
-const float LfpDisplayCanvas::getYCoordMin(int chan, int samp)
-{
-    return *screenBufferMin->getReadPointer(chan, samp);
-}
-const float LfpDisplayCanvas::getYCoordMax(int chan, int samp)
-{
-    return *screenBufferMax->getReadPointer(chan, samp);
-}
-
-
-bool LfpDisplayCanvas::getInputInvertedState()
-{
-    return invertInputButton->getToggleState();
-}
-
-bool LfpDisplayCanvas::getDrawMethodState()
-{
-    return drawMethodButton->getToggleState();
-}
-
-void LfpDisplayCanvas::paint(Graphics& g)
-{
-
-    //std::cout << "Painting" << std::endl;
-    g.setColour(Colour(0,18,43)); //background color
-    g.fillRect(0, 0, getWidth(), getHeight());
-
-    g.setGradientFill(ColourGradient(Colour(50,50,50),0,0,
-                                     Colour(25,25,25),0,30,
-                                     false));
-
-    g.fillRect(0, 0, getWidth()-scrollBarThickness, 30);
-
-    g.setColour(Colours::black);
-
-    g.drawLine(0,30,getWidth()-scrollBarThickness,30);
-
-    g.setColour(Colour(25,25,60)); // timing grid color
-
-    int w = getWidth()-scrollBarThickness-leftmargin;
-
-    for (int i = 0; i < 10; i++)
-    {
-        if (i == 5 || i == 0)
-            g.drawLine(w/10*i+leftmargin,0,w/10*i+leftmargin,getHeight()-60,3.0f);
-        else
-            g.drawLine(w/10*i+leftmargin,0,w/10*i+leftmargin,getHeight()-60,1.0f);
-    }
-
-    g.drawLine(0,getHeight()-60,getWidth(),getHeight()-60,3.0f);
-
-    g.setFont(Font("Default", 16, Font::plain));
-
-    g.setColour(Colour(100,100,100));
-
-    g.drawText("Voltage range ("+ rangeUnits[selectedChannelType] +")",5,getHeight()-55,300,20,Justification::left, false);
-    g.drawText("Timebase (s)",175,getHeight()-55,300,20,Justification::left, false);
-    g.drawText("Spread (px)",345,getHeight()-55,300,20,Justification::left, false);
-    g.drawText("Color grouping",620,getHeight()-55,300,20,Justification::left, false);
-
-    //g.drawText(typeNames[selectedChannelType],110,getHeight()-30,50,20,Justification::centredLeft,false);
-
-    g.drawText("Event disp.",500,getHeight()-55,300,20,Justification::left, false);
-
-
-
-}
-
-void LfpDisplayCanvas::refresh()
-{
-
-    updateScreenBuffer();
-
-    lfpDisplay->refresh(); // redraws only the new part of the screen buffer
-
-    //getPeer()->performAnyPendingRepaintsNow();
-
-}
-
-bool LfpDisplayCanvas::keyPressed(const KeyPress& key)
-{
-    if (key.getKeyCode() == key.spaceKey)
-    {
-        pauseButton->setToggleState(!pauseButton->getToggleState(), sendNotification);
-        return true;
-    }
-
-    return false;
-}
-
-bool LfpDisplayCanvas::keyPressed(const KeyPress& key, Component* orig)
-{
-    if (getTopLevelComponent() == orig && isVisible())
-    {
-        return keyPressed(key);
-    }
-    return false;
-}
-
-void LfpDisplayCanvas::saveVisualizerParameters(XmlElement* xml)
-{
-
-    XmlElement* xmlNode = xml->createNewChildElement("LFPDISPLAY");
-
-
-    xmlNode->setAttribute("Range",selectedVoltageRangeValues[0]+","+selectedVoltageRangeValues[1]+
-        ","+selectedVoltageRangeValues[2]);
-    xmlNode->setAttribute("Timebase",timebaseSelection->getText());
-    xmlNode->setAttribute("Spread",spreadSelection->getText());
-    xmlNode->setAttribute("colorGrouping",colorGroupingSelection->getSelectedId());
-    xmlNode->setAttribute("isInverted",invertInputButton->getToggleState());
-    xmlNode->setAttribute("drawMethod",drawMethodButton->getToggleState());
-
-    int eventButtonState = 0;
-
-    for (int i = 0; i < 8; i++)
-    {
-        if (lfpDisplay->eventDisplayEnabled[i])
-        {
-            eventButtonState += (1 << i);
-        }
-    }
-
-    xmlNode->setAttribute("EventButtonState", eventButtonState);
-
-    String channelDisplayState = "";
-
-    for (int i = 0; i < nChans; i++)
-    {
-        if (lfpDisplay->getEnabledState(i))
-        {
-            channelDisplayState += "1";
-        }
-        else
-        {
-            channelDisplayState += "0";
-        }
-    }
-
-    xmlNode->setAttribute("ChannelDisplayState", channelDisplayState);
-
-    xmlNode->setAttribute("ScrollX",viewport->getViewPositionX());
-    xmlNode->setAttribute("ScrollY",viewport->getViewPositionY());
-}
-
-
-void LfpDisplayCanvas::loadVisualizerParameters(XmlElement* xml)
-{
-    forEachXmlChildElement(*xml, xmlNode)
-    {
-        if (xmlNode->hasTagName("LFPDISPLAY"))
-        {
-            StringArray ranges;
-            ranges.addTokens(xmlNode->getStringAttribute("Range"),",",String::empty);
-            selectedVoltageRangeValues[0] = ranges[0];
-            selectedVoltageRangeValues[1] = ranges[1];
-            selectedVoltageRangeValues[2] = ranges[2];
-            selectedVoltageRange[0] = voltageRanges[0].indexOf(ranges[0])+1;
-            selectedVoltageRange[1] = voltageRanges[1].indexOf(ranges[1])+1;
-            selectedVoltageRange[2] = voltageRanges[2].indexOf(ranges[2])+1;
-            rangeSelection->setText(ranges[0]);
-
-            timebaseSelection->setText(xmlNode->getStringAttribute("Timebase"));
-            spreadSelection->setText(xmlNode->getStringAttribute("Spread"));
-            if (xmlNode->hasAttribute("colorGrouping"))
-            {
-                colorGroupingSelection->setSelectedId(xmlNode->getIntAttribute("colorGrouping"));
-            }
-            else
-            {
-                colorGroupingSelection->setSelectedId(1);
-            }
-
-            invertInputButton->setToggleState(xmlNode->getBoolAttribute("isInverted", true), sendNotification);
-
-            drawMethodButton->setToggleState(xmlNode->getBoolAttribute("drawMethod", true), sendNotification);
-
-            viewport->setViewPosition(xmlNode->getIntAttribute("ScrollX"),
-                                      xmlNode->getIntAttribute("ScrollY"));
-
-            int eventButtonState = xmlNode->getIntAttribute("EventButtonState");
-
-            for (int i = 0; i < 8; i++)
-            {
-                lfpDisplay->eventDisplayEnabled[i] = (eventButtonState >> i) & 1;
-
-                eventDisplayInterfaces[i]->checkEnabledState();
-            }
-
-            String channelDisplayState = xmlNode->getStringAttribute("ChannelDisplayState");
-
-            for (int i = 0; i < channelDisplayState.length(); i++)
-            {
-
-                if (channelDisplayState.substring(i,i+1).equalsIgnoreCase("1"))
-                {
-                    //std::cout << "LfpDisplayCanvas enabling channel " << i << std::endl;
-                    lfpDisplay->enableChannel(true, i);
-                    isChannelEnabled.set(i,true); //lfpDisplay->enableChannel(true, i);
-                }
-                else
-                {
-                    //std::cout << "LfpDisplayCanvas disabling channel " << i << std::endl;
-                    lfpDisplay->enableChannel(false, i);
-                    isChannelEnabled.set(i,false);
-                }
-
-
-            }
-        }
-    }
-
-}
-
-ChannelType LfpDisplayCanvas::getChannelType(int n)
-{
-	if (n < processor->getNumInputs())
-		return processor->channels[n]->getType();
-	else
-		return HEADSTAGE_CHANNEL;
-}
-
-ChannelType LfpDisplayCanvas::getSelectedType()
-{
-    return selectedChannelType;
-}
-
-void LfpDisplayCanvas::setSelectedType(ChannelType type, bool toggleButton)
-{
-    if (selectedChannelType == type)
-        return; //Nothing to do here
-    selectedChannelType = type;
-    rangeSelection->clear(dontSendNotification);
-    rangeSelection->addItemList(voltageRanges[type],1);
-    int id = selectedVoltageRange[type];
-    if (id)
-        rangeSelection->setSelectedId(id,sendNotification);
-    else
-        rangeSelection->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification);
-    repaint(5,getHeight()-55,300,100);
-
-    if (toggleButton)
-        typeButtons[type]->setToggleState(true,dontSendNotification);
-}
-
-String LfpDisplayCanvas::getTypeName(ChannelType type)
-{
-    return typeNames[type];
-}
-
-int LfpDisplayCanvas::getRangeStep(ChannelType type)
-{
-    return rangeSteps[type];
-}
-
-// -------------------------------------------------------------
-
-LfpTimescale::LfpTimescale(LfpDisplayCanvas* c) : canvas(c)
-{
-
-    font = Font("Default", 16, Font::plain);
-}
-
-LfpTimescale::~LfpTimescale()
-{
-
-}
-
-void LfpTimescale::paint(Graphics& g)
-{
-
-
-
-    g.setFont(font);
-
-    g.setColour(Colour(100,100,100));
-
-    g.drawText("ms:",5,0,100,getHeight(),Justification::left, false);
-
-    for (int i = 1; i < 10; i++)
-    {
-        if (i == 5)
-            g.drawLine(getWidth()/10*i,0,getWidth()/10*i,getHeight(),3.0f);
-        else
-            g.drawLine(getWidth()/10*i,0,getWidth()/10*i,getHeight(),1.0f);
-
-        g.drawText(labels[i-1],getWidth()/10*i+3,0,100,getHeight(),Justification::left, false);
-    }
-
-}
-
-void LfpTimescale::setTimebase(float t)
-{
-    timebase = t;
-
-    labels.clear();
-
-    for (float i = 1.0f; i < 10.0; i++)
-    {
-        String labelString = String(timebase/10.0f*1000.0f*i);
-
-        labels.add(labelString.substring(0,6));
-    }
-
-    repaint();
-
-}
-
-
-// ---------------------------------------------------------------
-
-LfpDisplay::LfpDisplay(LfpDisplayCanvas* c, Viewport* v) :
-    singleChan(-1), canvas(c), viewport(v)
-{
-    totalHeight = 0;
-    colorGrouping=1;
-
-    range[0] = 1000;
-    range[1] = 500;
-    range[2] = 500000;
-
-    addMouseListener(this, true);
-
-    // hue cycle
-    //for (int i = 0; i < 15; i++)
-    //{
-    //    channelColours.add(Colour(float(sin((3.14/2)*(float(i)/15))),float(1.0),float(1),float(1.0)));
-    //}
-
-    //hand-built palette
-    channelColours.add(Colour(224,185,36));
-    channelColours.add(Colour(214,210,182));
-    channelColours.add(Colour(243,119,33));
-    channelColours.add(Colour(186,157,168));
-    channelColours.add(Colour(237,37,36));
-    channelColours.add(Colour(179,122,79));
-    channelColours.add(Colour(217,46,171));
-    channelColours.add(Colour(217, 139,196));
-    channelColours.add(Colour(101,31,255));
-    channelColours.add(Colour(141,111,181));
-    channelColours.add(Colour(48,117,255));
-    channelColours.add(Colour(184,198,224));
-    channelColours.add(Colour(116,227,156));
-    channelColours.add(Colour(150,158,155));
-    channelColours.add(Colour(82,173,0));
-    channelColours.add(Colour(125,99,32));
-
-    isPaused=false;
-
-}
-
-LfpDisplay::~LfpDisplay()
-{
-    deleteAllChildren();
-}
-
-
-
-int LfpDisplay::getNumChannels()
-{
-    return numChans;
-}
-
-
-
-int LfpDisplay::getColorGrouping()
-{
-    return colorGrouping;
-}
-
-void LfpDisplay::setColorGrouping(int i)
-{
-    colorGrouping=i;
-    setColors(); // so that channel colors get re-assigned
-
-}
-
-
-void LfpDisplay::setNumChannels(int numChannels)
-{
-    numChans = numChannels;
-
-    deleteAllChildren();
-
-    channels.clear();
-    channelInfo.clear();
-
-    totalHeight = 0;
-
-    for (int i = 0; i < numChans; i++)
-    {
-
-        //std::cout << "Adding new display for channel " << i << std::endl;
-
-        LfpChannelDisplay* lfpChan = new LfpChannelDisplay(canvas, this, i);
-
-        //lfpChan->setColour(channelColours[i % channelColours.size()]);
-        lfpChan->setRange(range[canvas->getChannelType(i)]);
-        lfpChan->setChannelHeight(canvas->getChannelHeight());
-
-        addAndMakeVisible(lfpChan);
-
-        channels.add(lfpChan);
-
-        LfpChannelDisplayInfo* lfpInfo = new LfpChannelDisplayInfo(canvas, this, i);
-
-        //lfpInfo->setColour(channelColours[i % channelColours.size()]);
-        lfpInfo->setRange(range[canvas->getChannelType(i)]);
-        lfpInfo->setChannelHeight(canvas->getChannelHeight());
-
-        addAndMakeVisible(lfpInfo);
-
-        channelInfo.add(lfpInfo);
-
-		savedChannelState.add(true);
-
-        totalHeight += lfpChan->getChannelHeight();
-
-    }
-
-    setColors();
-
-    //std::cout << "TOTAL HEIGHT = " << totalHeight << std::endl;
-
-    // // this doesn't seem to do anything:
-    //canvas->fullredraw = true;
-    //refresh();
-
-}
-
-void LfpDisplay::setColors()
-{
-    for (int i = 0; i < numChans; i++)
-    {
-
-        channels[i]->setColour(channelColours[(int(i/colorGrouping)+1) % channelColours.size()]);
-        channelInfo[i]->setColour(channelColours[(int(i/colorGrouping)+1)  % channelColours.size()]);
-    }
-
-}
-
-
-int LfpDisplay::getTotalHeight()
-{
-    return totalHeight;
-}
-
-void LfpDisplay::resized()
-{
-
-    int totalHeight = 0;
-
-    for (int i = 0; i < channels.size(); i++)
-    {
-
-        LfpChannelDisplay* disp = channels[i];
-
-        disp->setBounds(canvas->leftmargin,
-                        totalHeight-disp->getChannelOverlap()/2,
-                        getWidth(),
-                        disp->getChannelHeight()+disp->getChannelOverlap());
-
-        LfpChannelDisplayInfo* info = channelInfo[i];
-
-        info->setBounds(0,
-                        totalHeight-disp->getChannelHeight()/4,
-                        canvas->leftmargin,
-                        disp->getChannelHeight());
-
-        totalHeight += disp->getChannelHeight();
-
-    }
-
-    canvas->fullredraw = true; //issue full redraw
-    if (singleChan != -1)
-        viewport->setViewPosition(Point<int>(0,singleChan*getChannelHeight()));
-
-    refresh();
-
-    // std::cout << "Total height: " << totalHeight << std::endl;
-
-}
-
-void LfpDisplay::paint(Graphics& g)
-{
-
-}
-
-void LfpDisplay::refresh()
-{
-
-
-    int topBorder = viewport->getViewPositionY();
-    int bottomBorder = viewport->getViewHeight() + topBorder;
-
-    // ensure that only visible channels are redrawn
-    for (int i = 0; i < numChans; i++)
-    {
-
-        int componentTop = channels[i]->getY();
-        int componentBottom = channels[i]->getHeight() + componentTop;
-
-        if ((topBorder <= componentBottom && bottomBorder >= componentTop))
-        {
-            if (canvas->fullredraw)
-            {
-                channels[i]->fullredraw = true;
-                channels[i]->repaint();
-                channelInfo[i]->repaint();
-
-            }
-            else
-            {
-                channels[i]->repaint(canvas->lastScreenBufferIndex[i]-2, 0, (canvas->screenBufferIndex[i]-canvas->lastScreenBufferIndex[i])+3, getChildComponent(i)->getHeight());  //repaint only the updated portion
-                // we redraw from -2 to +1 relative to the real redraw window, the -2 makes sure that the lines join nicely, and the +1 draws the vertical update line
-            }
-            //std::cout << i << std::endl;
-        }
-
-    }
-
-    canvas->fullredraw = false;
-}
-
-void LfpDisplay::setRange(float r, ChannelType type)
-{
-    range[type] = r;
-
-    for (int i = 0; i < numChans; i++)
-    {
-        if (channels[i]->getType() == type)
-            channels[i]->setRange(range[type]);
-    }
-    canvas->fullredraw = true; //issue full redraw
-}
-
-int LfpDisplay::getRange()
-{
-    return getRange(canvas->getSelectedType());
-}
-
-int LfpDisplay::getRange(ChannelType type)
-{
-    for (int i=0; i < numChans; i++)
-    {
-        if (channels[i]->getType() == type)
-            return channels[i]->getRange();
-    }
-    return 0;
-}
-
-
-void LfpDisplay::setChannelHeight(int r, bool resetSingle)
-{
-
-    for (int i = 0; i < numChans; i++)
-    {
-        channels[i]->setChannelHeight(r);
-        channelInfo[i]->setChannelHeight(r);
-    }
-    if (resetSingle && singleChan != -1)
-    {
-        setSize(getWidth(),numChans*getChannelHeight());
-        viewport->setScrollBarsShown(true,false);
-        viewport->setViewPosition(Point<int>(0,singleChan*r));
-        singleChan = -1;
-        for (int n = 0; n < numChans; n++)
-        {
-			channelInfo[n]->setEnabledState(savedChannelState[n]);
-        }
-    }
-
-    resized();
-
-}
-
-void LfpDisplay::setInputInverted(bool isInverted)
-{
-
-    for (int i = 0; i < numChans; i++)
-    {
-        channels[i]->setInputInverted(isInverted);
-    }
-
-    resized();
-
-}
-
-void LfpDisplay::setDrawMethod(bool isDrawMethod)
-{
-    for (int i = 0; i < numChans; i++)
-    {
-        channels[i]->setDrawMethod(isDrawMethod);
-    }
-    resized();
-
-}
-
-
-int LfpDisplay::getChannelHeight()
-{
-    return channels[0]->getChannelHeight();
-}
-
-
-
-void LfpDisplay::mouseWheelMove(const MouseEvent&  e, const MouseWheelDetails&   wheel)
-{
-
-    //std::cout << "Mouse wheel " <<  e.mods.isCommandDown() << "  " << wheel.deltaY << std::endl;
-    //TODO Changing ranges with the wheel is currently broken. With multiple ranges, most
-    //of the wheel range code needs updating
-    if (e.mods.isCommandDown())  // CTRL + scroll wheel -> change channel spacing
-    {
-        int h = getChannelHeight();
-        int hdiff=0;
-        
-        std::cout << wheel.deltaY << std::endl;
-        
-        if (wheel.deltaY > 0)
-        {
-            hdiff = 2;
-        }
-        else
-        {
-            if (h > 5)
-                hdiff = -2;
-        }
-
-        if (abs(h) > 100) // accelerate scrolling for large ranges
-            hdiff *= 3;
-
-        setChannelHeight(h+hdiff);
-        int oldX=viewport->getViewPositionX();
-        int oldY=viewport->getViewPositionY();
-
-        setBounds(0,0,getWidth()-0, getChannelHeight()*canvas->nChans); // update height so that the scrollbar is correct
-
-        int mouseY=e.getMouseDownY(); // should be y pos relative to inner viewport (0,0)
-        int scrollBy = (mouseY/h)*hdiff*2;// compensate for motion of point under current mouse position
-        viewport->setViewPosition(oldX,oldY+scrollBy); // set back to previous position plus offset
-
-        canvas->setSpreadSelection(h+hdiff); // update combobox
-
-    }
-    else
-    {
-        if (e.mods.isShiftDown())  // SHIFT + scroll wheel -> change channel range
-        {
-            int h = getRange();
-            int step = canvas->getRangeStep(canvas->getSelectedType());
-            
-            std::cout << wheel.deltaY << std::endl;
-            
-            if (wheel.deltaY > 0)
-            {
-                setRange(h+step,canvas->getSelectedType());
-            }
-            else
-            {
-                if (h > step+1)
-                    setRange(h-step,canvas->getSelectedType());
-            }
-
-            canvas->setRangeSelection(h); // update combobox
-
-        }
-        else    // just scroll
-        {
-            //  passes the event up to the viewport so the screen scrolls
-            if (viewport != nullptr && e.eventComponent == this) // passes only if it's not a listening event
-                viewport->mouseWheelMove(e.getEventRelativeTo(canvas), wheel);
-
-        }
-    }
-
-    canvas->fullredraw = true;//issue full redraw
-    refresh();
-
-}
-
-void LfpDisplay::toggleSingleChannel(int chan)
-{
-    //std::cout << "Toggle channel " << chan << std::endl;
-
-    if (chan != singleChan)
-    {
-        singleChan = chan;
-        int newHeight = viewport->getHeight();
-		channelInfo[chan]->setEnabledState(true);
-        setChannelHeight(newHeight, false);
-        setSize(getWidth(), numChans*getChannelHeight());
-        viewport->setScrollBarsShown(false,false);
-        viewport->setViewPosition(Point<int>(0,chan*newHeight));
-        for (int n = 0; n < numChans; n++)
-        {
-			savedChannelState.set(n, channels[n]->getEnabledState());
-            if (n != chan) channelInfo[n]->setEnabledState(false);
-        }
-
-    }
-    else
-    {
-        setChannelHeight(canvas->getChannelHeight());
-    }
-}
-
-bool LfpDisplay::getSingleChannelState()
-{
-    if (singleChan < 0) return false;
-    else return true;
-}
-
-
-void LfpDisplay::mouseDown(const MouseEvent& event)
-{
-    //int y = event.getMouseDownY(); //relative to each channel pos
-    MouseEvent canvasevent = event.getEventRelativeTo(viewport);
-    int y = canvasevent.getMouseDownY() + viewport->getViewPositionY(); // need to account for scrolling
-
-    int dist = 0;
-    int mindist = 10000;
-    int closest = 5;
-    for (int n = 0; n < numChans; n++) // select closest instead of relying on eventComponent
-    {
-        channels[n]->deselect();
-
-        int cpos = (channels[n]->getY() + (channels[n]->getHeight()/2));
-        dist = int(abs(y - cpos));
-
-        //std::cout << "Mouse down at " << y << " pos is "<< cpos << "n:" << n << "  dist " << dist << std::endl;
-
-        if (dist < mindist)
-        {
-            mindist = dist-1;
-            closest = n;
-        }
-    }
-
-    channels[closest]->select();
-    canvas->setSelectedType(channels[closest]->getType());
-
-    if (event.getNumberOfClicks() == 2)
-        toggleSingleChannel(closest);
-
-    if (event.mods.isRightButtonDown())
-    {
-        PopupMenu channelMenu = channels[closest]->getOptions();
-        const int result = channelMenu.show();
-        channels[closest]->changeParameter(result);
-    }
-
-    canvas->fullredraw = true;//issue full redraw
-
-    refresh();
-
-}
-
-
-bool LfpDisplay::setEventDisplayState(int ch, bool state)
-{
-    eventDisplayEnabled[ch] = state;
-    return eventDisplayEnabled[ch];
-}
-
-
-bool LfpDisplay::getEventDisplayState(int ch)
-{
-    return eventDisplayEnabled[ch];
-}
-
-void LfpDisplay::enableChannel(bool state, int chan)
-{
-
-    if (chan < numChans)
-    {
-        channelInfo[chan]->setEnabledState(state);
-        canvas->isChannelEnabled.set(chan, state);
-    }
-}
-
-void LfpDisplay::setEnabledState(bool state, int chan)
-{
-
-    if (chan < numChans)
-    {
-        channels[chan]->setEnabledState(state);
-        canvas->isChannelEnabled.set(chan, state);
-    }
-}
-
-bool LfpDisplay::getEnabledState(int chan)
-{
-    if (chan < numChans)
-    {
-        return channels[chan]->getEnabledState();
-    }
-
-    return false;
-}
-
-
-// ------------------------------------------------------------------
-
-LfpChannelDisplay::LfpChannelDisplay(LfpDisplayCanvas* c, LfpDisplay* d, int channelNumber) :
-    canvas(c), display(d), isSelected(false), chan(channelNumber),
-    channelOverlap(300), channelHeight(40), range(1000.0f),
-    isEnabled(true), inputInverted(false), canBeInverted(true), drawMethod(false)
-{
-
-
-    name = String(channelNumber+1); // default is to make the channelNumber the name
-
-
-    channelHeightFloat = (float) channelHeight;
-
-    channelFont = Font("Default", channelHeight*0.6, Font::plain);
-
-    lineColour = Colour(255,255,255);
-
-    type = c->getChannelType(channelNumber);
-    typeStr = c->getTypeName(type);
-
-}
-
-LfpChannelDisplay::~LfpChannelDisplay()
-{
-
-}
-
-void LfpChannelDisplay::updateType()
-{
-    type = canvas->getChannelType(chan);
-    typeStr = canvas->getTypeName(type);
-}
-
-void LfpChannelDisplay::setEnabledState(bool state)
-{
-
-    //if (state)
-    //std::cout << "Setting channel " << name << " to true." << std::endl;
-    //else
-    //std::cout << "Setting channel " << name << " to false." << std::endl;
-
-    isEnabled = state;
-
-}
-
-void LfpChannelDisplay::paint(Graphics& g)
-{
-
-    //g.fillAll(Colours::grey);
-
-    g.setColour(Colours::yellow);   // draw most recent drawn sample position
-    g.drawLine(canvas->screenBufferIndex[chan]+1, 0, canvas->screenBufferIndex[chan]+1, getHeight());
-
-
-    //g.setColour(Colours::red); // draw oldest drawn sample position
-    //g.drawLine(canvas->lastScreenBufferIndex, 0, canvas->lastScreenBufferIndex, getHeight()-channelOverlap);
-
-    if (isEnabled)
-    {
-
-        int center = getHeight()/2;
-
-        if (isSelected)
-        {
-
-            g.setColour(Colours::lightgrey);
-            g.fillRect(0,center-channelHeight/2,10,channelHeight);
-            g.drawLine(0,center+channelHeight/2,getWidth(),center+channelHeight/2);
-            g.drawLine(0,center-channelHeight/2,getWidth(),center-channelHeight/2);
-
-            if (!display->getSingleChannelState())
-            {
-                g.setColour(Colour(25,25,25));
-                g.drawLine(0,center+channelHeight/4,10,center+channelHeight/4);
-                g.drawLine(0,center-channelHeight/4,10,center-channelHeight/4);
-            }
-            else
-            {
-                g.setColour(Colour(70,70,70));
-                g.drawLine(0,center+channelHeight/4,getWidth(),center+channelHeight/4);
-                g.drawLine(0,center-channelHeight/4,getWidth(),center-channelHeight/4);
-            }
-
-
-        }
-
-        if (display->getSingleChannelState())
-        {
-
-            int leftEdge = 150;
-
-            float r = range;
-
-            g.setColour(Colours::lightgrey);
-            g.setFont(channelFont);
-            g.setFont(20);
-            String unitString;
-            if (getType() == ADC_CHANNEL)
-            {
-                unitString = " V";
-                //r = range / 1000.0f;
-            } else {
-                unitString = " uV";
-            }
-            g.drawText(String(0) + unitString, 20, center, leftEdge, 25, Justification::left, false);
-            g.drawText(String(r/2) + unitString, 20, center-channelHeight/2, leftEdge, 25, Justification::left, false);
-            g.drawText(String(-r/2) + unitString, 20, center+channelHeight/2-25, leftEdge, 25, Justification::left, false);
-            g.drawText(String(r/4) + unitString, 20, center-channelHeight/4, leftEdge, 25, Justification::left, false);
-            g.drawText(String(-r/4) + unitString, 20, center+channelHeight/4, leftEdge, 25, Justification::left, false);
-
-        }
-
-
-        g.setColour(Colour(40,40,40));
-        g.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);
-
-        int stepSize = 1;
-        int from = 0; // for vertical line drawing in the LFP data
-        int to = 0;
-
-        //for (int i = 0; i < getWidth()-stepSize; i += stepSize) // redraw entire display
-        int ifrom = canvas->lastScreenBufferIndex[chan] - 3; // need to start drawing a bit before the actual redraw windowfor the interpolated line to join correctly
-
-        if (ifrom < 0)
-            ifrom = 0;
-
-        int ito = canvas->screenBufferIndex[chan] - 1;
-
-        if (fullredraw)
-        {
-            ifrom = 0; //canvas->leftmargin;
-            ito = getWidth()-stepSize;
-            fullredraw = false;
-        }
-
-        for (int i = ifrom; i < ito ; i += stepSize) // redraw only changed portion
-        {
-
-            // draw event markers
-            int rawEventState = canvas->getYCoord(canvas->getNumChannels(), i);// get last channel+1 in buffer (represents events)
-            
-            //if (i == ifrom)
-            //    std::cout << rawEventState << std::endl;
-
-            for (int ev_ch = 0; ev_ch < 8 ; ev_ch++) // for all event channels
-            {
-                if (display->getEventDisplayState(ev_ch))  // check if plotting for this channel is enabled
-                {
-                    if (rawEventState & (1 << ev_ch))    // events are  representet by a bit code, so we have to extract the individual bits with a mask
-                    {
-                        //std::cout << "Drawing event." << std::endl;
-                        g.setColour(display->channelColours[ev_ch*2]); // get color from lfp color scheme
-                        g.setOpacity(0.35f);
-                        g.drawLine(i, center-channelHeight/2 , i, center+channelHeight/2);
-                    }
-                }
-            }
-
-            //std::cout << "e " << canvas->getYCoord(canvas->getNumChannels()-1, i) << std::endl;
-            g.setColour(lineColour);
-
-            if (drawMethod) // switched between to line drawing and pixel wise drawing
-            {
-
-                // drawLine makes for ok anti-aliased plots, but is pretty slow
-                g.drawLine(i,
-                           (canvas->getYCoord(chan, i)/range*channelHeightFloat)+getHeight()/2,
-                           i+stepSize,
-                           (canvas->getYCoord(chan, i+stepSize)/range*channelHeightFloat)+getHeight()/2);
-
-
-            }
-            else
-            {
-
-                // // pixel wise line plot has no anti-aliasing, but runs much faster
-                double a = (canvas->getYCoordMax(chan, i)/range*channelHeightFloat)+getHeight()/2;
-                double b = (canvas->getYCoordMin(chan, i)/range*channelHeightFloat)+getHeight()/2;
-                //double m = (canvas->getYCoordMean(chan, i)/range*channelHeightFloat)+getHeight()/2;
-                if (a<b)
-                {
-                    from = (a);
-                    to = (b);
-                }
-                else
-                {
-                    from = (b);
-                    to = (a);
-                }
-
-                //g.setColour(lineColour.withMultipliedBrightness( 1+(((((float)(to-from)*range)/getHeight())-0.01)*2)  )); // make spikes etc slightly brighter
-
-
-                if ((to-from) < 200)  // if there is too much vertical range in one pixel, don't draw the full line for speed reasons
-                {
-                    for (int j = from; j <= to; j += 1)
-                    {
-                        g.setPixel(i,j);
-                    }
-                }
-                else if ((to-from) < 400)
-                {
-                    for (int j = from; j <= to; j += 2)
-                    {
-                        g.setPixel(i,j);
-                    }
-                }
-                else
-                {
-                    g.setPixel(i,to);
-                    g.setPixel(i,from);
-                }
-
-                //draw mean
-                //g.setColour(Colours::black);
-                //g.setPixel(i,m);
-
-            }
-
-        }
-    }
-
-    // g.setColour(lineColour.withAlpha(0.7f)); // alpha on seems to decrease draw speed
-    // g.setFont(channelFont);
-    //  g.setFont(channelHeightFloat*0.6);
-
-    // g.drawText(String(chan+1), 10, center-channelHeight/2, 200, channelHeight, Justification::left, false);
-
-
-}
-
-
-PopupMenu LfpChannelDisplay::getOptions()
-{
-
-    PopupMenu menu;
-    menu.addItem(1, "Invert signal", true, inputInverted);
-
-    return menu;
-}
-
-void LfpChannelDisplay::changeParameter(int id)
-{
-    switch (id)
-    {
-        case 1:
-            setInputInverted(!inputInverted);
-        default:
-            break;
-    }
-}
-
-void LfpChannelDisplay::setRange(float r)
-{
-    
-    range = r;
-
-    //std::cout << "Range: " << r << std::endl;
-}
-
-int LfpChannelDisplay::getRange()
-{
-    return range;
-}
-
-
-void LfpChannelDisplay::select()
-{
-    isSelected = true;
-}
-
-void LfpChannelDisplay::deselect()
-{
-    isSelected = false;
-}
-
-bool LfpChannelDisplay::getSelected()
-{
-   return isSelected;
-}
-
-void LfpChannelDisplay::setColour(Colour c)
-{
-    lineColour = c;
-}
-
-
-void LfpChannelDisplay::setChannelHeight(int c)
-{
-    channelHeight = c;
-
-    channelHeightFloat = (float) channelHeight;
-
-    if (!inputInverted)
-        channelHeightFloat = -channelHeightFloat;
-
-    channelOverlap = channelHeight*5;
-}
-
-int LfpChannelDisplay::getChannelHeight()
-{
-
-    return channelHeight;
-}
-
-void LfpChannelDisplay::setChannelOverlap(int overlap)
-{
-    channelOverlap = overlap;
-}
-
-
-int LfpChannelDisplay::getChannelOverlap()
-{
-    return channelOverlap;
-}
-
-void LfpChannelDisplay::setCanBeInverted(bool _canBeInverted)
-{
-    canBeInverted = _canBeInverted;
-}
-
-void LfpChannelDisplay::setInputInverted(bool isInverted)
-{
-    if (canBeInverted)
-    {
-        inputInverted = isInverted;
-        setChannelHeight(channelHeight);
-    }
-}
-
-void LfpChannelDisplay::setDrawMethod(bool isDrawMethod)
-{
-
-    drawMethod = isDrawMethod;
-
-}
-
-
-void LfpChannelDisplay::setName(String name_)
-{
-    name = name_;
-}
-
-ChannelType LfpChannelDisplay::getType()
-{
-    return type;
-}
-
-// -------------------------------
-
-LfpChannelDisplayInfo::LfpChannelDisplayInfo(LfpDisplayCanvas* canvas_, LfpDisplay* display_, int ch)
-    : LfpChannelDisplay(canvas_, display_, ch)
-{
-
-    chan = ch;
-
-    enableButton = new UtilityButton(String(ch+1), Font("Small Text", 13, Font::plain));
-    enableButton->setRadius(5.0f);
-
-    enableButton->setEnabledState(true);
-    enableButton->setCorners(true, true, true, true);
-    enableButton->addListener(this);
-    enableButton->setClickingTogglesState(true);
-    enableButton->setToggleState(true, dontSendNotification);
-
-    addAndMakeVisible(enableButton);
-
-}
-
-void LfpChannelDisplayInfo::updateType()
-{
-    type = canvas->getChannelType(chan);
-    typeStr = canvas->getTypeName(type);
-    repaint();
-}
-
-void LfpChannelDisplayInfo::buttonClicked(Button* button)
-{
-
-    bool state = button->getToggleState();
-
-    display->setEnabledState(state, chan);
-
-    //UtilityButton* b = (UtilityButton*) button;
-
-    // if (state)
-    // {
-    //  b->setLabel("ON");
-    // } else {
-    //  b->setLabel("OFF");
-    // }
-
-    //std::cout << "Turn channel " << chan << " to " << button->getToggleState() << std::endl;
-
-}
-
-void LfpChannelDisplayInfo::setEnabledState(bool state)
-{
-    enableButton->setToggleState(state, sendNotification);
-}
-
-void LfpChannelDisplayInfo::paint(Graphics& g)
-{
-
-    int center = getHeight()/2;
-
-    g.setColour(lineColour);
-
-    //if (chan > 98)
-    //  g.fillRoundedRectangle(5,center-8,51,22,8.0f);
-    //else
-    g.fillRoundedRectangle(5,center-8,41,22,8.0f);
-
-      g.setFont(Font("Small Text", 13, Font::plain));
-      g.drawText(typeStr,5,center+16,41,10,Justification::centred,false);
-    // g.setFont(channelHeightFloat*0.3);
-
-    //  g.drawText(name, 10, center-channelHeight/2, 200, channelHeight, Justification::left, false);
-
-}
-
-void LfpChannelDisplayInfo::resized()
-{
-
-    int center = getHeight()/2;
-
-    //if (chan > 98)
-    //  enableButton->setBounds(8,center-5,45,16);
-    //else
-    enableButton->setBounds(8,center-5,35,16);
-}
-
-
-// Event display Options --------------------------------------------------------------------
-
-EventDisplayInterface::EventDisplayInterface(LfpDisplay* display_, LfpDisplayCanvas* canvas_, int chNum):
-    isEnabled(true), display(display_), canvas(canvas_)
-{
-
-    channelNumber = chNum;
-
-    chButton = new UtilityButton(String(channelNumber+1), Font("Small Text", 13, Font::plain));
-    chButton->setRadius(5.0f);
-    chButton->setBounds(4,4,14,14);
-    chButton->setEnabledState(true);
-    chButton->setCorners(true, false, true, false);
-    //chButton.color = display->channelColours[channelNumber*2];
-    chButton->addListener(this);
-    addAndMakeVisible(chButton);
-
-
-    checkEnabledState();
-
-}
-
-EventDisplayInterface::~EventDisplayInterface()
-{
-
-}
-
-void EventDisplayInterface::checkEnabledState()
-{
-    isEnabled = display->getEventDisplayState(channelNumber);
-
-    //repaint();
-}
-
-void EventDisplayInterface::buttonClicked(Button* button)
-{
-    checkEnabledState();
-    if (isEnabled)
-    {
-        display->setEventDisplayState(channelNumber, false);
-    }
-    else
-    {
-        display->setEventDisplayState(channelNumber, true);
-    }
-
-    repaint();
-
-}
-
-
-void EventDisplayInterface::paint(Graphics& g)
-{
-
-    checkEnabledState();
-
-    if (isEnabled)
-    {
-        g.setColour(display->channelColours[channelNumber*2]);
-        g.fillRoundedRectangle(2,2,18,18,5.0f);
-    }
-
-
-    //g.drawText(String(channelNumber), 8, 2, 200, 15, Justification::left, false);
-
-}
-
-// Lfp Viewport -------------------------------------------
-
-LfpViewport::LfpViewport(LfpDisplayCanvas *canvas)
-    : Viewport()
-{
-    this->canvas = canvas;
-}
-
-void LfpViewport::visibleAreaChanged(const Rectangle<int>& newVisibleArea)
-{
-    canvas->fullredraw = true;
-    canvas->refresh();
-}
+/*
+------------------------------------------------------------------
+
+This file is part of the Open Ephys GUI
+Copyright (C) 2013 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 "LfpDisplayCanvas.h"
+
+#include <math.h>
+
+LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) :
+     timebase(1.0f), displayGain(1.0f),   timeOffset(0.0f),
+    processor(processor_), selectedChannelType(HEADSTAGE_CHANNEL)
+{
+
+    nChans = processor->getNumInputs();
+    std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl;
+
+    displayBuffer = processor->getDisplayBufferAddress();
+    displayBufferSize = displayBuffer->getNumSamples();
+    std::cout << "Setting displayBufferSize on LfpDisplayCanvas to " << displayBufferSize << std::endl;
+
+    screenBuffer = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
+    screenBuffer->clear();
+
+    screenBufferMin = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
+    screenBufferMin->clear();
+    screenBufferMean = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
+    screenBufferMean->clear();
+    screenBufferMax = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP);
+    screenBufferMax->clear();
+
+    viewport = new LfpViewport(this);
+    lfpDisplay = new LfpDisplay(this, viewport);
+    timescale = new LfpTimescale(this);
+
+    timescale->setTimebase(timebase);
+
+    viewport->setViewedComponent(lfpDisplay, false);
+    viewport->setScrollBarsShown(true, false);
+
+    scrollBarThickness = viewport->getScrollBarThickness();
+
+    isChannelEnabled.insertMultiple(0,true,10000); // max 10k channels
+
+    //viewport->getVerticalScrollBar()->addListener(this->scrollBarMoved(viewport->getVerticalScrollBar(), 1.0));
+
+    UtilityButton* tbut;
+
+    addAndMakeVisible(viewport);
+    addAndMakeVisible(timescale);
+
+    //Ranges for neural data
+     voltageRanges[HEADSTAGE_CHANNEL].add("25");
+    voltageRanges[HEADSTAGE_CHANNEL].add("50");
+    voltageRanges[HEADSTAGE_CHANNEL].add("100");
+    voltageRanges[HEADSTAGE_CHANNEL].add("250");
+    voltageRanges[HEADSTAGE_CHANNEL].add("400");
+    voltageRanges[HEADSTAGE_CHANNEL].add("500");
+    voltageRanges[HEADSTAGE_CHANNEL].add("750");
+    voltageRanges[HEADSTAGE_CHANNEL].add("1000");
+    voltageRanges[HEADSTAGE_CHANNEL].add("2000");
+    voltageRanges[HEADSTAGE_CHANNEL].add("5000");
+    voltageRanges[HEADSTAGE_CHANNEL].add("10000");
+    selectedVoltageRange[HEADSTAGE_CHANNEL] = 8;
+    rangeGain[HEADSTAGE_CHANNEL] = 1; //uV
+    rangeSteps[HEADSTAGE_CHANNEL] = 10;
+    rangeUnits.add("uV");
+    typeNames.add("DATA");
+
+    tbut = new UtilityButton("DATA",Font("Small Text", 9, Font::plain));
+    tbut->setEnabledState(true);
+    tbut->setCorners(false,false,false,false);
+    tbut->addListener(this);
+    tbut->setClickingTogglesState(true);
+    tbut->setRadioGroupId(100,dontSendNotification);
+    tbut->setToggleState(true,dontSendNotification);
+    addAndMakeVisible(tbut);
+    typeButtons.add(tbut);
+    
+    //Ranges for AUX/accelerometer data
+    voltageRanges[AUX_CHANNEL].add("25");
+    voltageRanges[AUX_CHANNEL].add("50");
+    voltageRanges[AUX_CHANNEL].add("100");
+    voltageRanges[AUX_CHANNEL].add("250");
+    voltageRanges[AUX_CHANNEL].add("400");
+    voltageRanges[AUX_CHANNEL].add("500");
+    voltageRanges[AUX_CHANNEL].add("750");
+    voltageRanges[AUX_CHANNEL].add("1000");
+    voltageRanges[AUX_CHANNEL].add("2000");
+    //voltageRanges[AUX_CHANNEL].add("5000");
+    selectedVoltageRange[AUX_CHANNEL] = 9;
+    rangeGain[AUX_CHANNEL] = 0.001; //mV
+    rangeSteps[AUX_CHANNEL] = 10;
+    rangeUnits.add("mV");
+    typeNames.add("AUX");
+
+    tbut = new UtilityButton("AUX",Font("Small Text", 9, Font::plain));
+    tbut->setEnabledState(true);
+    tbut->setCorners(false,false,false,false);
+    tbut->addListener(this);
+    tbut->setClickingTogglesState(true);
+    tbut->setRadioGroupId(100,dontSendNotification);
+    tbut->setToggleState(false,dontSendNotification);
+    addAndMakeVisible(tbut);
+    typeButtons.add(tbut);
+
+    //Ranges for ADC data
+     voltageRanges[ADC_CHANNEL].add("0.01");
+    voltageRanges[ADC_CHANNEL].add("0.05");
+    voltageRanges[ADC_CHANNEL].add("0.1");
+    voltageRanges[ADC_CHANNEL].add("0.5");
+    voltageRanges[ADC_CHANNEL].add("1.0");
+    voltageRanges[ADC_CHANNEL].add("2.0");
+    voltageRanges[ADC_CHANNEL].add("5.0");
+    voltageRanges[ADC_CHANNEL].add("10.0");
+    selectedVoltageRange[ADC_CHANNEL] = 8;
+    rangeGain[ADC_CHANNEL] = 1; //V
+    rangeSteps[ADC_CHANNEL] = 0.1; //in V
+    rangeUnits.add("V");
+    typeNames.add("ADC");
+
+    tbut = new UtilityButton("ADC",Font("Small Text", 9, Font::plain));
+    tbut->setEnabledState(true);
+    tbut->setCorners(false,false,false,false);
+    tbut->addListener(this);
+    tbut->setClickingTogglesState(true);
+    tbut->setRadioGroupId(100,dontSendNotification);
+    tbut->setToggleState(false,dontSendNotification);
+    addAndMakeVisible(tbut);
+    typeButtons.add(tbut);
+
+    selectedVoltageRangeValues[HEADSTAGE_CHANNEL] = voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1];
+    selectedVoltageRangeValues[AUX_CHANNEL] = voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL]-1];
+    selectedVoltageRangeValues[ADC_CHANNEL] = voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL]-1];
+
+    timebases.add("0.25");
+    timebases.add("0.5");
+    timebases.add("1.0");
+    timebases.add("2.0");
+    timebases.add("3.0");
+    timebases.add("4.0");
+    timebases.add("5.0");
+    timebases.add("10.0");
+    timebases.add("20.0");
+    selectedTimebase = 4;
+    selectedTimebaseValue = timebases[selectedTimebase-1];
+
+    spreads.add("10");
+    spreads.add("20");
+    spreads.add("30");
+    spreads.add("40");
+    spreads.add("50");
+    spreads.add("60");
+    spreads.add("70");
+    spreads.add("80");
+    spreads.add("90");
+    spreads.add("100");
+    selectedSpread = 5;
+    selectedSpreadValue = spreads[selectedSpread-1];
+
+    colorGroupings.add("1");
+    colorGroupings.add("2");
+    colorGroupings.add("4");
+    colorGroupings.add("8");
+    colorGroupings.add("16");
+
+
+    rangeSelection = new ComboBox("Voltage range");
+    rangeSelection->addItemList(voltageRanges[HEADSTAGE_CHANNEL], 1);
+    rangeSelection->setSelectedId(selectedVoltageRange[HEADSTAGE_CHANNEL], sendNotification);
+    rangeSelection->setEditableText(true);
+    rangeSelection->addListener(this);
+    addAndMakeVisible(rangeSelection);
+
+
+    timebaseSelection = new ComboBox("Timebase");
+    timebaseSelection->addItemList(timebases, 1);
+    timebaseSelection->setSelectedId(selectedTimebase, sendNotification);
+    timebaseSelection->setEditableText(true);
+    timebaseSelection->addListener(this);
+    addAndMakeVisible(timebaseSelection);
+
+
+    spreadSelection = new ComboBox("Spread");
+    spreadSelection->addItemList(spreads, 1);
+    spreadSelection->setSelectedId(selectedSpread,sendNotification);
+    spreadSelection->addListener(this);
+    spreadSelection->setEditableText(true);
+    addAndMakeVisible(spreadSelection);
+
+    colorGroupingSelection = new ComboBox("Color Grouping");
+    colorGroupingSelection->addItemList(colorGroupings, 1);
+    colorGroupingSelection->setSelectedId(1,sendNotification);
+    colorGroupingSelection->addListener(this);
+    addAndMakeVisible(colorGroupingSelection);
+
+    invertInputButton = new UtilityButton("Invert", Font("Small Text", 13, Font::plain));
+    invertInputButton->setRadius(5.0f);
+    invertInputButton->setEnabledState(true);
+    invertInputButton->setCorners(true, true, true, true);
+    invertInputButton->addListener(this);
+    invertInputButton->setClickingTogglesState(true);
+    invertInputButton->setToggleState(false, sendNotification);
+    addAndMakeVisible(invertInputButton);
+
+    //button for controlling drawing algorithm - old line-style or new per-pixel style
+    drawMethodButton = new UtilityButton("DrawMethod", Font("Small Text", 13, Font::plain));
+    drawMethodButton->setRadius(5.0f);
+    drawMethodButton->setEnabledState(true);
+    drawMethodButton->setCorners(true, true, true, true);
+    drawMethodButton->addListener(this);
+    drawMethodButton->setClickingTogglesState(true);
+    drawMethodButton->setToggleState(false, sendNotification);
+    addAndMakeVisible(drawMethodButton);
+
+    //button for pausing the display - works by skipping buffer updates. This way scrolling etc still works
+    pauseButton = new UtilityButton("Pause", Font("Small Text", 13, Font::plain));
+    pauseButton->setRadius(5.0f);
+    pauseButton->setEnabledState(true);
+    pauseButton->setCorners(true, true, true, true);
+    pauseButton->addListener(this);
+    pauseButton->setClickingTogglesState(true);
+    pauseButton->setToggleState(false, sendNotification);
+    addAndMakeVisible(pauseButton);
+
+
+    lfpDisplay->setNumChannels(nChans);
+    lfpDisplay->setRange(voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1].getFloatValue()*rangeGain[HEADSTAGE_CHANNEL]
+        ,HEADSTAGE_CHANNEL);
+	lfpDisplay->setRange(voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL] - 1].getFloatValue()*rangeGain[ADC_CHANNEL]
+		, ADC_CHANNEL);
+	lfpDisplay->setRange(voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL] - 1].getFloatValue()*rangeGain[AUX_CHANNEL]
+		, AUX_CHANNEL);
+
+    // add event display-specific controls (currently just an enable/disable button)
+    for (int i = 0; i < 8; i++)
+    {
+
+        EventDisplayInterface* eventOptions = new EventDisplayInterface(lfpDisplay, this, i);
+        eventDisplayInterfaces.add(eventOptions);
+        addAndMakeVisible(eventOptions);
+        eventOptions->setBounds(500+(floor(i/2)*20), getHeight()-20-(i%2)*20, 40, 20);
+
+        lfpDisplay->setEventDisplayState(i,true);
+
+    }
+
+    TopLevelWindow::getTopLevelWindow(0)->addKeyListener(this);
+}
+
+LfpDisplayCanvas::~LfpDisplayCanvas()
+{
+
+    deleteAndZero(screenBuffer);
+    deleteAndZero(screenBufferMin);
+    deleteAndZero(screenBufferMean);
+    deleteAndZero(screenBufferMax);
+
+    TopLevelWindow::getTopLevelWindow(0)->removeKeyListener(this);
+}
+
+void LfpDisplayCanvas::resized()
+{
+
+    timescale->setBounds(leftmargin,0,getWidth()-scrollBarThickness-leftmargin,30);
+    viewport->setBounds(0,30,getWidth(),getHeight()-90);
+
+    if (lfpDisplay->getSingleChannelState())
+        lfpDisplay->setChannelHeight(viewport->getHeight(),false);
+
+    lfpDisplay->setBounds(0,0,getWidth()-scrollBarThickness, lfpDisplay->getChannelHeight()*nChans);
+
+    rangeSelection->setBounds(5,getHeight()-30,100,25);
+    timebaseSelection->setBounds(175,getHeight()-30,100,25);
+    spreadSelection->setBounds(345,getHeight()-30,100,25);
+    colorGroupingSelection->setBounds(620,getHeight()-30,100,25);
+
+    invertInputButton->setBounds(750,getHeight()-50,100,22);
+    drawMethodButton->setBounds(750,getHeight()-25,100,22);
+    pauseButton->setBounds(880,getHeight()-50,50,44);
+
+    for (int i = 0; i < 8; i++)
+    {
+        eventDisplayInterfaces[i]->setBounds(500+(floor(i/2)*20), getHeight()-40+(i%2)*20, 40, 20); // arrange event channel buttons in two rows
+        eventDisplayInterfaces[i]->repaint();
+    }
+
+    int bh = 25/typeButtons.size();
+    for (int i = 0; i < typeButtons.size(); i++)
+    {
+        typeButtons[i]->setBounds(110,getHeight()-30+i*bh,50,bh);
+    }
+    // std::cout << "Canvas thinks LfpDisplay should be this high: "
+    //  << lfpDisplay->getTotalHeight() << std::endl;
+
+}
+
+void LfpDisplayCanvas::beginAnimation()
+{
+    std::cout << "Beginning animation." << std::endl;
+
+    displayBufferSize = displayBuffer->getNumSamples();
+
+    for (int i = 0; i < screenBufferIndex.size(); i++)
+    {
+        screenBufferIndex.set(i,0);
+    }
+
+    startCallbacks();
+}
+
+void LfpDisplayCanvas::endAnimation()
+{
+    std::cout << "Ending animation." << std::endl;
+
+    stopCallbacks();
+}
+
+void LfpDisplayCanvas::update()
+{
+    nChans = jmax(processor->getNumInputs(),1);
+
+    sampleRate.clear();
+    screenBufferIndex.clear();
+    lastScreenBufferIndex.clear();
+    displayBufferIndex.clear();
+
+    for (int i = 0; i <= nChans; i++) // extra channel for events
+    {
+		if (processor->getNumInputs() > 0)
+		{
+			if (i < nChans)
+				sampleRate.add(processor->channels[i]->sampleRate);
+			else
+				sampleRate.add(processor->channels[i - 1]->sampleRate); // for event channel (IT'S A HACK -- BE CAREFUL!)
+		}
+		else
+			sampleRate.add(30000);
+        
+       // std::cout << "Sample rate for ch " << i << " = " << sampleRate[i] << std::endl; 
+        displayBufferIndex.add(0);
+        screenBufferIndex.add(0);
+        lastScreenBufferIndex.add(0);
+    }
+
+
+
+    if (nChans != lfpDisplay->getNumChannels())
+    {
+        //std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl;
+
+        refreshScreenBuffer();
+
+        lfpDisplay->setNumChannels(nChans); // add an extra channel for events
+
+        // update channel names
+        for (int i = 0; i < processor->getNumInputs(); i++)
+        {
+
+            String chName = processor->channels[i]->getName();
+
+            //std::cout << chName << std::endl;
+
+            lfpDisplay->channelInfo[i]->setName(chName);
+            lfpDisplay->enableChannel(isChannelEnabled[i], i);
+
+        }
+
+        lfpDisplay->setBounds(0,0,getWidth()-scrollBarThickness*2, lfpDisplay->getTotalHeight());
+
+        resized();
+    }
+    else
+    {
+        for (int i = 0; i < processor->getNumInputs(); i++)
+        {
+            lfpDisplay->channels[i]->updateType();
+            lfpDisplay->channelInfo[i]->updateType();
+        }
+        
+    }
+
+}
+
+void LfpDisplayCanvas::buttonClicked(Button* b)
+{
+    if (b == invertInputButton)
+    {
+        lfpDisplay->setInputInverted(b->getToggleState());
+        return;
+    }
+    if (b == drawMethodButton)
+    {
+        lfpDisplay->setDrawMethod(b->getToggleState());
+        return;
+    }
+    if (b == pauseButton)
+    {
+        lfpDisplay->isPaused = b->getToggleState();
+        return;
+    }
+
+    int idx = typeButtons.indexOf((UtilityButton*)b);
+    if ((idx >= 0) && (b->getToggleState()))
+    {
+        for (int i = 0; i < processor->getNumInputs(); i++)
+        {
+            if (lfpDisplay->channels[i]->getSelected())
+            {
+                lfpDisplay->channels[i]->deselect();
+                lfpDisplay->channels[i]->repaint();
+            }
+        }  
+        setSelectedType((ChannelType) idx, false);
+    }
+
+}
+
+
+void LfpDisplayCanvas::comboBoxChanged(ComboBox* cb)
+{
+
+    if (cb == timebaseSelection)
+    {
+        if (cb->getSelectedId())
+        {
+            timebase = timebases[cb->getSelectedId()-1].getFloatValue();
+        }
+        else
+        {
+            timebase = cb->getText().getFloatValue();
+            if (timebase)
+            {
+                if (timebase < timebases[0].getFloatValue())
+                {
+                    cb->setSelectedId(1,dontSendNotification);
+                    timebase = timebases[0].getFloatValue();
+                }
+                else if (timebase > timebases[timebases.size()-1].getFloatValue())
+                {
+                    cb->setSelectedId(timebases.size(),dontSendNotification);
+                    timebase = timebases[timebases.size()-1].getFloatValue();
+                }
+                else
+                    cb->setText(String(timebase,1),dontSendNotification);
+            }
+            else
+            {
+                if (selectedSpread == 0)
+                {
+                    cb->setText(selectedTimebaseValue,dontSendNotification);
+                    timebase = selectedTimebaseValue.getFloatValue();
+                }
+                else
+                {
+                    cb->setSelectedId(selectedTimebase,dontSendNotification);
+                    timebase = timebases[selectedTimebase-1].getFloatValue();
+                }
+
+            }
+        }
+    }
+    else if (cb == rangeSelection)
+    {
+        if (cb->getSelectedId())
+        {
+        lfpDisplay->setRange(voltageRanges[selectedChannelType][cb->getSelectedId()-1].getFloatValue()*rangeGain[selectedChannelType]
+            ,selectedChannelType);
+        }
+        else
+        {
+            float vRange = cb->getText().getFloatValue();
+            if (vRange)
+            {
+                if (vRange < voltageRanges[selectedChannelType][0].getFloatValue())
+                {
+                    cb->setSelectedId(1,dontSendNotification);
+                    vRange = voltageRanges[selectedChannelType][0].getFloatValue();
+                }
+                else if (vRange > voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue())
+                {
+                    cb->setSelectedId(voltageRanges[selectedChannelType].size(),dontSendNotification);
+                    vRange = voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue();
+                }
+                else
+                {
+                    if (rangeGain[selectedChannelType] > 1)
+                        cb->setText(String(vRange,1),dontSendNotification);
+                    else
+                        cb->setText(String(vRange),dontSendNotification);
+                }
+                lfpDisplay->setRange(vRange*rangeGain[selectedChannelType],selectedChannelType);
+            }
+            else
+            {
+                if (selectedVoltageRange[selectedChannelType])
+                    cb->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification);
+                else
+                    cb->setSelectedId(selectedVoltageRange[selectedChannelType],dontSendNotification);
+            }
+        }
+        selectedVoltageRange[selectedChannelType] = cb->getSelectedId();
+        selectedVoltageRangeValues[selectedChannelType] = cb->getText();
+        //std::cout << "Setting range to " << voltageRanges[cb->getSelectedId()-1].getFloatValue() << std::endl;
+    }
+    else if (cb == spreadSelection)
+    {
+        if (cb->getSelectedId())
+        {
+            lfpDisplay->setChannelHeight(spreads[cb->getSelectedId()-1].getIntValue());
+            resized();
+        }
+        else
+        {
+            int spread = cb->getText().getIntValue();
+            if (spread)
+            {
+                if (spread < spreads[0].getFloatValue())
+                {
+                    cb->setSelectedId(1,dontSendNotification);
+                    spread = spreads[0].getFloatValue();
+                }
+                else if (spread > spreads[spreads.size()-1].getFloatValue())
+                {
+                    cb->setSelectedId(spreads.size(),dontSendNotification);
+                    spread = spreads[spreads.size()-1].getFloatValue();
+                }
+                else
+                {
+                    cb->setText(String(spread),dontSendNotification);
+                }
+                lfpDisplay->setChannelHeight(spread);
+                resized();
+            }
+            else
+            {
+                if (selectedSpread == 0)
+                    cb->setText(selectedSpreadValue,dontSendNotification);
+                else
+                    cb->setSelectedId(selectedSpread,dontSendNotification);
+            }
+        }
+        selectedSpread = cb->getSelectedId();
+        selectedSpreadValue = cb->getText();
+        //std::cout << "Setting spread to " << spreads[cb->getSelectedId()-1].getFloatValue() << std::endl;
+    }
+    else if (cb == colorGroupingSelection)
+    {
+        // set color grouping hre
+
+        lfpDisplay->setColorGrouping(colorGroupings[cb->getSelectedId()-1].getIntValue());// so that channel colors get re-assigned
+
+    }
+
+    timescale->setTimebase(timebase);
+}
+
+
+int LfpDisplayCanvas::getChannelHeight()
+{
+    return spreads[spreadSelection->getSelectedId()-1].getIntValue();
+}
+
+
+void LfpDisplayCanvas::setParameter(int param, float val)
+{
+    // not used for anything, since LfpDisplayCanvas is not a processor
+}
+
+void LfpDisplayCanvas:: setRangeSelection(float range, bool canvasMustUpdate)
+{
+    if (canvasMustUpdate)
+    {
+        rangeSelection->setText(String(range/rangeGain[selectedChannelType]), sendNotification); 
+    }
+    else
+    {
+        rangeSelection->setText(String(range/rangeGain[selectedChannelType]),dontSendNotification);
+        selectedVoltageRange[selectedChannelType]=rangeSelection->getSelectedId();
+        selectedVoltageRangeValues[selectedChannelType]=rangeSelection->getText();
+
+        repaint();
+        refresh();
+    }
+
+}
+
+void LfpDisplayCanvas:: setSpreadSelection(int spread, bool canvasMustUpdate)
+{
+    if (canvasMustUpdate)
+    {
+        spreadSelection->setText(String(spread),sendNotification);
+    }
+    else
+    {
+        spreadSelection->setText(String(spread),dontSendNotification);
+        selectedSpread=spreadSelection->getSelectedId();
+        selectedSpreadValue=spreadSelection->getText();
+
+        repaint();
+        refresh();
+    }
+}
+
+void LfpDisplayCanvas::refreshState()
+{
+    // called when the component's tab becomes visible again
+
+    for (int i = 0; i <= displayBufferIndex.size(); i++) // include event channel
+    {
+
+        displayBufferIndex.set(i, processor->getDisplayBufferIndex(i));
+        screenBufferIndex.set(i,0);
+    }
+
+}
+
+void LfpDisplayCanvas::refreshScreenBuffer()
+{
+
+    for (int i = 0; i < screenBufferIndex.size(); i++)
+        screenBufferIndex.set(i,0);
+
+    screenBuffer->clear();
+    screenBufferMin->clear();
+    screenBufferMean->clear();
+    screenBufferMax->clear();
+
+
+    // int w = lfpDisplay->getWidth();
+    // //std::cout << "Refreshing buffer size to " << w << "pixels." << std::endl;
+
+    // for (int i = 0; i < w; i++)
+    // {
+    //  float x = float(i);
+
+    //  for (int n = 0; n < nChans; n++)
+    //  {
+    //      waves[n][i*2] = x;
+    //      waves[n][i*2+1] = 0.5f; // line in center of display
+    //  }
+    // }
+
+}
+
+void LfpDisplayCanvas::updateScreenBuffer()
+{
+
+    // copy new samples from the displayBuffer into the screenBuffer
+    int maxSamples = lfpDisplay->getWidth() - leftmargin;
+
+	ScopedLock displayLock(*processor->getMutex());
+
+    for (int channel = 0; channel <= nChans; channel++) // pull one extra channel for event display
+    {
+
+        if (screenBufferIndex[channel] >= maxSamples) // wrap around if we reached right edge before
+            screenBufferIndex.set(channel, 0);
+
+         // hold these values locally for each channel
+        int sbi = screenBufferIndex[channel];
+        int dbi = displayBufferIndex[channel];
+
+        lastScreenBufferIndex.set(channel,sbi);
+
+        int index = processor->getDisplayBufferIndex(channel);
+
+        int nSamples =  index - dbi; // N new samples (not pixels) to be added to displayBufferIndex
+
+        if (nSamples < 0) // buffer has reset to 0
+        {
+            nSamples = (displayBufferSize - dbi) + index;
+        }
+
+        //if (channel == 15 || channel == 16)
+        //     std::cout << channel << " " << sbi << " " << dbi << " " << nSamples << std::endl;
+
+
+        float ratio = sampleRate[channel] * timebase / float(getWidth() - leftmargin - scrollBarThickness); // samples / pixel
+        // this number is crucial: converting from samples to values (in px) for the screen buffer
+        int valuesNeeded = (int) float(nSamples) / ratio; // N pixels needed for this update
+
+        if (sbi + valuesNeeded > maxSamples)  // crop number of samples to fit canvas width
+        {
+            valuesNeeded = maxSamples - sbi;
+        }
+        float subSampleOffset = 0.0;
+
+        dbi %= displayBufferSize; // make sure we're not overshooting
+        int nextPos = (dbi + 1) % displayBufferSize; //  position next to displayBufferIndex in display buffer to copy from
+
+        // if (channel == 0)
+        //     std::cout << "Channel " 
+        //               << channel << " : " 
+        //               << sbi << " : " 
+        //               << index << " : " 
+        //               << dbi << " : " 
+        //               << valuesNeeded << " : " 
+        //               << ratio 
+        //                             << std::endl;
+
+        if (valuesNeeded > 0 && valuesNeeded < 10000)
+        {
+            for (int i = 0; i < valuesNeeded; i++) // also fill one extra sample for line drawing interpolation to match across draws
+            {
+                //If paused don't update screen buffers, but update all indexes as needed
+                if (!lfpDisplay->isPaused)
+                {
+                    float gain = 1.0;
+                    float alpha = (float) subSampleOffset;
+                    float invAlpha = 1.0f - alpha;
+
+                    screenBuffer->clear(channel, sbi, 1);
+                    screenBufferMin->clear(channel, sbi, 1);
+                    screenBufferMean->clear(channel, sbi, 1);
+                    screenBufferMax->clear(channel, sbi, 1);
+
+                     dbi %= displayBufferSize; // just to be sure
+
+                    // interpolate between two samples with invAlpha and alpha
+                    screenBuffer->addFrom(channel, // destChannel
+                                          sbi, // destStartSample
+                                          displayBuffer->getReadPointer(channel, dbi), // source
+                                          1, // numSamples
+                                          invAlpha*gain); // gain
+
+
+                    screenBuffer->addFrom(channel, // destChannel
+                                          sbi, // destStartSample
+                                          displayBuffer->getReadPointer(channel, nextPos), // source
+                                          1, // numSamples
+                                          alpha*gain); // gain
+
+                    // same thing again, but this time add the min,mean, and max of all samples in current pixel
+                    float sample_min   =  1000000;
+                    float sample_max   = -1000000;
+                    float sample_mean  =  0;
+                    int c = 0;
+                    int nextpix = (dbi +(int)ratio) % displayBufferSize; //  position to next pixels index
+                    
+                    for (int j = dbi; j < nextpix; j++)
+                    {
+                        float sample_current = displayBuffer->getSample(channel, j);
+                        sample_mean = sample_mean + sample_current;
+
+                        if (sample_min>sample_current)
+                        {
+                            sample_min=sample_current;
+                        }
+
+                        if (sample_max<sample_current)
+                        {
+                            sample_max=sample_current;
+                        }
+                        c++;
+
+                    }
+
+                    sample_mean = sample_mean/c;
+                    screenBufferMean->addSample(channel, sbi, sample_mean*gain);
+                    screenBufferMin->addSample(channel, sbi, sample_min*gain);
+                    screenBufferMax->addSample(channel, sbi, sample_max*gain);
+                
+                sbi++;
+                }
+            
+            subSampleOffset += ratio;
+
+            while (subSampleOffset >= 1.0)
+            {
+                if (++dbi > displayBufferSize)
+                    dbi = 0;
+
+                nextPos = (dbi + 1) % displayBufferSize;
+                subSampleOffset -= 1.0;
+            }
+
+        }
+
+        // update values after we're done
+        screenBufferIndex.set(channel, sbi);
+        displayBufferIndex.set(channel, dbi);
+        }
+
+    }
+
+}
+
+const float LfpDisplayCanvas::getXCoord(int chan, int samp)
+{
+    return samp;
+}
+
+int LfpDisplayCanvas::getNumChannels()
+{
+    return nChans;
+}
+
+const float LfpDisplayCanvas::getYCoord(int chan, int samp)
+{
+    return *screenBuffer->getReadPointer(chan, samp);
+}
+
+const float LfpDisplayCanvas::getYCoordMean(int chan, int samp)
+{
+    return *screenBufferMean->getReadPointer(chan, samp);
+}
+const float LfpDisplayCanvas::getYCoordMin(int chan, int samp)
+{
+    return *screenBufferMin->getReadPointer(chan, samp);
+}
+const float LfpDisplayCanvas::getYCoordMax(int chan, int samp)
+{
+    return *screenBufferMax->getReadPointer(chan, samp);
+}
+
+
+bool LfpDisplayCanvas::getInputInvertedState()
+{
+    return invertInputButton->getToggleState();
+}
+
+bool LfpDisplayCanvas::getDrawMethodState()
+{
+    return drawMethodButton->getToggleState();
+}
+
+void LfpDisplayCanvas::paint(Graphics& g)
+{
+
+    //std::cout << "Painting" << std::endl;
+    g.setColour(Colour(0,18,43)); //background color
+    g.fillRect(0, 0, getWidth(), getHeight());
+
+    g.setGradientFill(ColourGradient(Colour(50,50,50),0,0,
+                                     Colour(25,25,25),0,30,
+                                     false));
+
+    g.fillRect(0, 0, getWidth()-scrollBarThickness, 30);
+
+    g.setColour(Colours::black);
+
+    g.drawLine(0,30,getWidth()-scrollBarThickness,30);
+
+    g.setColour(Colour(25,25,60)); // timing grid color
+
+    int w = getWidth()-scrollBarThickness-leftmargin;
+
+    for (int i = 0; i < 10; i++)
+    {
+        if (i == 5 || i == 0)
+            g.drawLine(w/10*i+leftmargin,0,w/10*i+leftmargin,getHeight()-60,3.0f);
+        else
+            g.drawLine(w/10*i+leftmargin,0,w/10*i+leftmargin,getHeight()-60,1.0f);
+    }
+
+    g.drawLine(0,getHeight()-60,getWidth(),getHeight()-60,3.0f);
+
+    g.setFont(Font("Default", 16, Font::plain));
+
+    g.setColour(Colour(100,100,100));
+
+    g.drawText("Voltage range ("+ rangeUnits[selectedChannelType] +")",5,getHeight()-55,300,20,Justification::left, false);
+    g.drawText("Timebase (s)",175,getHeight()-55,300,20,Justification::left, false);
+    g.drawText("Spread (px)",345,getHeight()-55,300,20,Justification::left, false);
+    g.drawText("Color grouping",620,getHeight()-55,300,20,Justification::left, false);
+
+    //g.drawText(typeNames[selectedChannelType],110,getHeight()-30,50,20,Justification::centredLeft,false);
+
+    g.drawText("Event disp.",500,getHeight()-55,300,20,Justification::left, false);
+
+
+
+}
+
+void LfpDisplayCanvas::refresh()
+{
+
+    updateScreenBuffer();
+
+    lfpDisplay->refresh(); // redraws only the new part of the screen buffer
+
+    //getPeer()->performAnyPendingRepaintsNow();
+
+}
+
+bool LfpDisplayCanvas::keyPressed(const KeyPress& key)
+{
+    if (key.getKeyCode() == key.spaceKey)
+    {
+        pauseButton->setToggleState(!pauseButton->getToggleState(), sendNotification);
+        return true;
+    }
+
+    return false;
+}
+
+bool LfpDisplayCanvas::keyPressed(const KeyPress& key, Component* orig)
+{
+    if (getTopLevelComponent() == orig && isVisible())
+    {
+        return keyPressed(key);
+    }
+    return false;
+}
+
+void LfpDisplayCanvas::saveVisualizerParameters(XmlElement* xml)
+{
+
+    XmlElement* xmlNode = xml->createNewChildElement("LFPDISPLAY");
+
+
+    xmlNode->setAttribute("Range",selectedVoltageRangeValues[0]+","+selectedVoltageRangeValues[1]+
+        ","+selectedVoltageRangeValues[2]);
+    xmlNode->setAttribute("Timebase",timebaseSelection->getText());
+    xmlNode->setAttribute("Spread",spreadSelection->getText());
+    xmlNode->setAttribute("colorGrouping",colorGroupingSelection->getSelectedId());
+    xmlNode->setAttribute("isInverted",invertInputButton->getToggleState());
+    xmlNode->setAttribute("drawMethod",drawMethodButton->getToggleState());
+
+    int eventButtonState = 0;
+
+    for (int i = 0; i < 8; i++)
+    {
+        if (lfpDisplay->eventDisplayEnabled[i])
+        {
+            eventButtonState += (1 << i);
+        }
+    }
+
+    xmlNode->setAttribute("EventButtonState", eventButtonState);
+
+    String channelDisplayState = "";
+
+    for (int i = 0; i < nChans; i++)
+    {
+        if (lfpDisplay->getEnabledState(i))
+        {
+            channelDisplayState += "1";
+        }
+        else
+        {
+            channelDisplayState += "0";
+        }
+    }
+
+    xmlNode->setAttribute("ChannelDisplayState", channelDisplayState);
+
+    xmlNode->setAttribute("ScrollX",viewport->getViewPositionX());
+    xmlNode->setAttribute("ScrollY",viewport->getViewPositionY());
+}
+
+
+void LfpDisplayCanvas::loadVisualizerParameters(XmlElement* xml)
+{
+    forEachXmlChildElement(*xml, xmlNode)
+    {
+        if (xmlNode->hasTagName("LFPDISPLAY"))
+        {
+            StringArray ranges;
+            ranges.addTokens(xmlNode->getStringAttribute("Range"),",",String::empty);
+            selectedVoltageRangeValues[0] = ranges[0];
+            selectedVoltageRangeValues[1] = ranges[1];
+            selectedVoltageRangeValues[2] = ranges[2];
+            selectedVoltageRange[0] = voltageRanges[0].indexOf(ranges[0])+1;
+            selectedVoltageRange[1] = voltageRanges[1].indexOf(ranges[1])+1;
+            selectedVoltageRange[2] = voltageRanges[2].indexOf(ranges[2])+1;
+            rangeSelection->setText(ranges[0]);
+
+            timebaseSelection->setText(xmlNode->getStringAttribute("Timebase"));
+            spreadSelection->setText(xmlNode->getStringAttribute("Spread"));
+            if (xmlNode->hasAttribute("colorGrouping"))
+            {
+                colorGroupingSelection->setSelectedId(xmlNode->getIntAttribute("colorGrouping"));
+            }
+            else
+            {
+                colorGroupingSelection->setSelectedId(1);
+            }
+
+            invertInputButton->setToggleState(xmlNode->getBoolAttribute("isInverted", true), sendNotification);
+
+            drawMethodButton->setToggleState(xmlNode->getBoolAttribute("drawMethod", true), sendNotification);
+
+            viewport->setViewPosition(xmlNode->getIntAttribute("ScrollX"),
+                                      xmlNode->getIntAttribute("ScrollY"));
+
+            int eventButtonState = xmlNode->getIntAttribute("EventButtonState");
+
+            for (int i = 0; i < 8; i++)
+            {
+                lfpDisplay->eventDisplayEnabled[i] = (eventButtonState >> i) & 1;
+
+                eventDisplayInterfaces[i]->checkEnabledState();
+            }
+
+            String channelDisplayState = xmlNode->getStringAttribute("ChannelDisplayState");
+
+            for (int i = 0; i < channelDisplayState.length(); i++)
+            {
+
+                if (channelDisplayState.substring(i,i+1).equalsIgnoreCase("1"))
+                {
+                    //std::cout << "LfpDisplayCanvas enabling channel " << i << std::endl;
+                    lfpDisplay->enableChannel(true, i);
+                    isChannelEnabled.set(i,true); //lfpDisplay->enableChannel(true, i);
+                }
+                else
+                {
+                    //std::cout << "LfpDisplayCanvas disabling channel " << i << std::endl;
+                    lfpDisplay->enableChannel(false, i);
+                    isChannelEnabled.set(i,false);
+                }
+
+
+            }
+        }
+    }
+
+}
+
+ChannelType LfpDisplayCanvas::getChannelType(int n)
+{
+	if (n < processor->getNumInputs())
+		return processor->channels[n]->getType();
+	else
+		return HEADSTAGE_CHANNEL;
+}
+
+ChannelType LfpDisplayCanvas::getSelectedType()
+{
+    return selectedChannelType;
+}
+
+void LfpDisplayCanvas::setSelectedType(ChannelType type, bool toggleButton)
+{
+    if (selectedChannelType == type)
+        return; //Nothing to do here
+    selectedChannelType = type;
+    rangeSelection->clear(dontSendNotification);
+    rangeSelection->addItemList(voltageRanges[type],1);
+    int id = selectedVoltageRange[type];
+    if (id)
+        rangeSelection->setSelectedId(id,sendNotification);
+    else
+        rangeSelection->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification);
+    repaint(5,getHeight()-55,300,100);
+
+    if (toggleButton)
+        typeButtons[type]->setToggleState(true,dontSendNotification);
+}
+
+String LfpDisplayCanvas::getTypeName(ChannelType type)
+{
+    return typeNames[type];
+}
+
+int LfpDisplayCanvas::getRangeStep(ChannelType type)
+{
+    return rangeSteps[type];
+}
+
+// -------------------------------------------------------------
+
+LfpTimescale::LfpTimescale(LfpDisplayCanvas* c) : canvas(c)
+{
+
+    font = Font("Default", 16, Font::plain);
+}
+
+LfpTimescale::~LfpTimescale()
+{
+
+}
+
+void LfpTimescale::paint(Graphics& g)
+{
+
+
+
+    g.setFont(font);
+
+    g.setColour(Colour(100,100,100));
+
+    g.drawText("ms:",5,0,100,getHeight(),Justification::left, false);
+
+    for (int i = 1; i < 10; i++)
+    {
+        if (i == 5)
+            g.drawLine(getWidth()/10*i,0,getWidth()/10*i,getHeight(),3.0f);
+        else
+            g.drawLine(getWidth()/10*i,0,getWidth()/10*i,getHeight(),1.0f);
+
+        g.drawText(labels[i-1],getWidth()/10*i+3,0,100,getHeight(),Justification::left, false);
+    }
+
+}
+
+void LfpTimescale::setTimebase(float t)
+{
+    timebase = t;
+
+    labels.clear();
+
+    for (float i = 1.0f; i < 10.0; i++)
+    {
+        String labelString = String(timebase/10.0f*1000.0f*i);
+
+        labels.add(labelString.substring(0,6));
+    }
+
+    repaint();
+
+}
+
+
+// ---------------------------------------------------------------
+
+LfpDisplay::LfpDisplay(LfpDisplayCanvas* c, Viewport* v) :
+    singleChan(-1), canvas(c), viewport(v)
+{
+    totalHeight = 0;
+    colorGrouping=1;
+
+    range[0] = 1000;
+    range[1] = 500;
+    range[2] = 500000;
+
+    addMouseListener(this, true);
+
+    // hue cycle
+    //for (int i = 0; i < 15; i++)
+    //{
+    //    channelColours.add(Colour(float(sin((3.14/2)*(float(i)/15))),float(1.0),float(1),float(1.0)));
+    //}
+
+    //hand-built palette
+    channelColours.add(Colour(224,185,36));
+    channelColours.add(Colour(214,210,182));
+    channelColours.add(Colour(243,119,33));
+    channelColours.add(Colour(186,157,168));
+    channelColours.add(Colour(237,37,36));
+    channelColours.add(Colour(179,122,79));
+    channelColours.add(Colour(217,46,171));
+    channelColours.add(Colour(217, 139,196));
+    channelColours.add(Colour(101,31,255));
+    channelColours.add(Colour(141,111,181));
+    channelColours.add(Colour(48,117,255));
+    channelColours.add(Colour(184,198,224));
+    channelColours.add(Colour(116,227,156));
+    channelColours.add(Colour(150,158,155));
+    channelColours.add(Colour(82,173,0));
+    channelColours.add(Colour(125,99,32));
+
+    isPaused=false;
+
+}
+
+LfpDisplay::~LfpDisplay()
+{
+    deleteAllChildren();
+}
+
+
+
+int LfpDisplay::getNumChannels()
+{
+    return numChans;
+}
+
+
+
+int LfpDisplay::getColorGrouping()
+{
+    return colorGrouping;
+}
+
+void LfpDisplay::setColorGrouping(int i)
+{
+    colorGrouping=i;
+    setColors(); // so that channel colors get re-assigned
+
+}
+
+
+void LfpDisplay::setNumChannels(int numChannels)
+{
+    numChans = numChannels;
+
+    deleteAllChildren();
+
+    channels.clear();
+    channelInfo.clear();
+
+    totalHeight = 0;
+
+    for (int i = 0; i < numChans; i++)
+    {
+
+        //std::cout << "Adding new display for channel " << i << std::endl;
+
+        LfpChannelDisplay* lfpChan = new LfpChannelDisplay(canvas, this, i);
+
+        //lfpChan->setColour(channelColours[i % channelColours.size()]);
+        lfpChan->setRange(range[canvas->getChannelType(i)]);
+        lfpChan->setChannelHeight(canvas->getChannelHeight());
+
+        addAndMakeVisible(lfpChan);
+
+        channels.add(lfpChan);
+
+        LfpChannelDisplayInfo* lfpInfo = new LfpChannelDisplayInfo(canvas, this, i);
+
+        //lfpInfo->setColour(channelColours[i % channelColours.size()]);
+        lfpInfo->setRange(range[canvas->getChannelType(i)]);
+        lfpInfo->setChannelHeight(canvas->getChannelHeight());
+
+        addAndMakeVisible(lfpInfo);
+
+        channelInfo.add(lfpInfo);
+
+		savedChannelState.add(true);
+
+        totalHeight += lfpChan->getChannelHeight();
+
+    }
+
+    setColors();
+
+    //std::cout << "TOTAL HEIGHT = " << totalHeight << std::endl;
+
+    // // this doesn't seem to do anything:
+    //canvas->fullredraw = true;
+    //refresh();
+
+}
+
+void LfpDisplay::setColors()
+{
+    for (int i = 0; i < numChans; i++)
+    {
+
+        channels[i]->setColour(channelColours[(int(i/colorGrouping)+1) % channelColours.size()]);
+        channelInfo[i]->setColour(channelColours[(int(i/colorGrouping)+1)  % channelColours.size()]);
+    }
+
+}
+
+
+int LfpDisplay::getTotalHeight()
+{
+    return totalHeight;
+}
+
+void LfpDisplay::resized()
+{
+
+    int totalHeight = 0;
+
+    for (int i = 0; i < channels.size(); i++)
+    {
+
+        LfpChannelDisplay* disp = channels[i];
+
+        disp->setBounds(canvas->leftmargin,
+                        totalHeight-disp->getChannelOverlap()/2,
+                        getWidth(),
+                        disp->getChannelHeight()+disp->getChannelOverlap());
+
+        LfpChannelDisplayInfo* info = channelInfo[i];
+
+        info->setBounds(0,
+                        totalHeight-disp->getChannelHeight()/4,
+                        canvas->leftmargin,
+                        disp->getChannelHeight());
+
+        totalHeight += disp->getChannelHeight();
+
+    }
+
+    canvas->fullredraw = true; //issue full redraw
+    if (singleChan != -1)
+        viewport->setViewPosition(Point<int>(0,singleChan*getChannelHeight()));
+
+    refresh();
+
+    // std::cout << "Total height: " << totalHeight << std::endl;
+
+}
+
+void LfpDisplay::paint(Graphics& g)
+{
+
+}
+
+void LfpDisplay::refresh()
+{
+
+
+    int topBorder = viewport->getViewPositionY();
+    int bottomBorder = viewport->getViewHeight() + topBorder;
+
+    // ensure that only visible channels are redrawn
+    for (int i = 0; i < numChans; i++)
+    {
+
+        int componentTop = channels[i]->getY();
+        int componentBottom = channels[i]->getHeight() + componentTop;
+
+        if ((topBorder <= componentBottom && bottomBorder >= componentTop))
+        {
+            if (canvas->fullredraw)
+            {
+                channels[i]->fullredraw = true;
+                channels[i]->repaint();
+                channelInfo[i]->repaint();
+
+            }
+            else
+            {
+                channels[i]->repaint(canvas->lastScreenBufferIndex[i]-2, 0, (canvas->screenBufferIndex[i]-canvas->lastScreenBufferIndex[i])+3, getChildComponent(i)->getHeight());  //repaint only the updated portion
+                // we redraw from -2 to +1 relative to the real redraw window, the -2 makes sure that the lines join nicely, and the +1 draws the vertical update line
+            }
+            //std::cout << i << std::endl;
+        }
+
+    }
+
+    canvas->fullredraw = false;
+}
+
+void LfpDisplay::setRange(float r, ChannelType type)
+{
+    range[type] = r;
+
+    for (int i = 0; i < numChans; i++)
+    {
+        if (channels[i]->getType() == type)
+            channels[i]->setRange(range[type]);
+    }
+    canvas->fullredraw = true; //issue full redraw
+}
+
+int LfpDisplay::getRange()
+{
+    return getRange(canvas->getSelectedType());
+}
+
+int LfpDisplay::getRange(ChannelType type)
+{
+    for (int i=0; i < numChans; i++)
+    {
+        if (channels[i]->getType() == type)
+            return channels[i]->getRange();
+    }
+    return 0;
+}
+
+
+void LfpDisplay::setChannelHeight(int r, bool resetSingle)
+{
+
+    for (int i = 0; i < numChans; i++)
+    {
+        channels[i]->setChannelHeight(r);
+        channelInfo[i]->setChannelHeight(r);
+    }
+    if (resetSingle && singleChan != -1)
+    {
+        setSize(getWidth(),numChans*getChannelHeight());
+        viewport->setScrollBarsShown(true,false);
+        viewport->setViewPosition(Point<int>(0,singleChan*r));
+        singleChan = -1;
+        for (int n = 0; n < numChans; n++)
+        {
+			channelInfo[n]->setEnabledState(savedChannelState[n]);
+        }
+    }
+
+    resized();
+
+}
+
+void LfpDisplay::setInputInverted(bool isInverted)
+{
+
+    for (int i = 0; i < numChans; i++)
+    {
+        channels[i]->setInputInverted(isInverted);
+    }
+
+    resized();
+
+}
+
+void LfpDisplay::setDrawMethod(bool isDrawMethod)
+{
+    for (int i = 0; i < numChans; i++)
+    {
+        channels[i]->setDrawMethod(isDrawMethod);
+    }
+    resized();
+
+}
+
+
+int LfpDisplay::getChannelHeight()
+{
+    return channels[0]->getChannelHeight();
+}
+
+
+
+void LfpDisplay::mouseWheelMove(const MouseEvent&  e, const MouseWheelDetails&   wheel)
+{
+
+    //std::cout << "Mouse wheel " <<  e.mods.isCommandDown() << "  " << wheel.deltaY << std::endl;
+    //TODO Changing ranges with the wheel is currently broken. With multiple ranges, most
+    //of the wheel range code needs updating
+    if (e.mods.isCommandDown())  // CTRL + scroll wheel -> change channel spacing
+    {
+        int h = getChannelHeight();
+        int hdiff=0;
+        
+        std::cout << wheel.deltaY << std::endl;
+        
+        if (wheel.deltaY > 0)
+        {
+            hdiff = 2;
+        }
+        else
+        {
+            if (h > 5)
+                hdiff = -2;
+        }
+
+        if (abs(h) > 100) // accelerate scrolling for large ranges
+            hdiff *= 3;
+
+        setChannelHeight(h+hdiff);
+        int oldX=viewport->getViewPositionX();
+        int oldY=viewport->getViewPositionY();
+
+        setBounds(0,0,getWidth()-0, getChannelHeight()*canvas->nChans); // update height so that the scrollbar is correct
+
+        int mouseY=e.getMouseDownY(); // should be y pos relative to inner viewport (0,0)
+        int scrollBy = (mouseY/h)*hdiff*2;// compensate for motion of point under current mouse position
+        viewport->setViewPosition(oldX,oldY+scrollBy); // set back to previous position plus offset
+
+        canvas->setSpreadSelection(h+hdiff); // update combobox
+
+    }
+    else
+    {
+        if (e.mods.isShiftDown())  // SHIFT + scroll wheel -> change channel range
+        {
+            int h = getRange();
+            int step = canvas->getRangeStep(canvas->getSelectedType());
+            
+            std::cout << wheel.deltaY << std::endl;
+            
+            if (wheel.deltaY > 0)
+            {
+                setRange(h+step,canvas->getSelectedType());
+            }
+            else
+            {
+                if (h > step+1)
+                    setRange(h-step,canvas->getSelectedType());
+            }
+
+            canvas->setRangeSelection(h); // update combobox
+
+        }
+        else    // just scroll
+        {
+            //  passes the event up to the viewport so the screen scrolls
+            if (viewport != nullptr && e.eventComponent == this) // passes only if it's not a listening event
+                viewport->mouseWheelMove(e.getEventRelativeTo(canvas), wheel);
+
+        }
+    }
+
+    canvas->fullredraw = true;//issue full redraw
+    refresh();
+
+}
+
+void LfpDisplay::toggleSingleChannel(int chan)
+{
+    //std::cout << "Toggle channel " << chan << std::endl;
+
+    if (chan != singleChan)
+    {
+        singleChan = chan;
+        int newHeight = viewport->getHeight();
+		channelInfo[chan]->setEnabledState(true);
+        setChannelHeight(newHeight, false);
+        setSize(getWidth(), numChans*getChannelHeight());
+        viewport->setScrollBarsShown(false,false);
+        viewport->setViewPosition(Point<int>(0,chan*newHeight));
+        for (int n = 0; n < numChans; n++)
+        {
+			savedChannelState.set(n, channels[n]->getEnabledState());
+            if (n != chan) channelInfo[n]->setEnabledState(false);
+        }
+
+    }
+    else
+    {
+        setChannelHeight(canvas->getChannelHeight());
+    }
+}
+
+bool LfpDisplay::getSingleChannelState()
+{
+    if (singleChan < 0) return false;
+    else return true;
+}
+
+
+void LfpDisplay::mouseDown(const MouseEvent& event)
+{
+    //int y = event.getMouseDownY(); //relative to each channel pos
+    MouseEvent canvasevent = event.getEventRelativeTo(viewport);
+    int y = canvasevent.getMouseDownY() + viewport->getViewPositionY(); // need to account for scrolling
+
+    int dist = 0;
+    int mindist = 10000;
+    int closest = 5;
+    for (int n = 0; n < numChans; n++) // select closest instead of relying on eventComponent
+    {
+        channels[n]->deselect();
+
+        int cpos = (channels[n]->getY() + (channels[n]->getHeight()/2));
+        dist = int(abs(y - cpos));
+
+        //std::cout << "Mouse down at " << y << " pos is "<< cpos << "n:" << n << "  dist " << dist << std::endl;
+
+        if (dist < mindist)
+        {
+            mindist = dist-1;
+            closest = n;
+        }
+    }
+
+    channels[closest]->select();
+    canvas->setSelectedType(channels[closest]->getType());
+
+    if (event.getNumberOfClicks() == 2)
+        toggleSingleChannel(closest);
+
+    if (event.mods.isRightButtonDown())
+    {
+        PopupMenu channelMenu = channels[closest]->getOptions();
+        const int result = channelMenu.show();
+        channels[closest]->changeParameter(result);
+    }
+
+    canvas->fullredraw = true;//issue full redraw
+
+    refresh();
+
+}
+
+
+bool LfpDisplay::setEventDisplayState(int ch, bool state)
+{
+    eventDisplayEnabled[ch] = state;
+    return eventDisplayEnabled[ch];
+}
+
+
+bool LfpDisplay::getEventDisplayState(int ch)
+{
+    return eventDisplayEnabled[ch];
+}
+
+void LfpDisplay::enableChannel(bool state, int chan)
+{
+
+    if (chan < numChans)
+    {
+        channelInfo[chan]->setEnabledState(state);
+        canvas->isChannelEnabled.set(chan, state);
+    }
+}
+
+void LfpDisplay::setEnabledState(bool state, int chan)
+{
+
+    if (chan < numChans)
+    {
+        channels[chan]->setEnabledState(state);
+        canvas->isChannelEnabled.set(chan, state);
+    }
+}
+
+bool LfpDisplay::getEnabledState(int chan)
+{
+    if (chan < numChans)
+    {
+        return channels[chan]->getEnabledState();
+    }
+
+    return false;
+}
+
+
+// ------------------------------------------------------------------
+
+LfpChannelDisplay::LfpChannelDisplay(LfpDisplayCanvas* c, LfpDisplay* d, int channelNumber) :
+    canvas(c), display(d), isSelected(false), chan(channelNumber),
+    channelOverlap(300), channelHeight(40), range(1000.0f),
+    isEnabled(true), inputInverted(false), canBeInverted(true), drawMethod(false)
+{
+
+
+    name = String(channelNumber+1); // default is to make the channelNumber the name
+
+
+    channelHeightFloat = (float) channelHeight;
+
+    channelFont = Font("Default", channelHeight*0.6, Font::plain);
+
+    lineColour = Colour(255,255,255);
+
+    type = c->getChannelType(channelNumber);
+    typeStr = c->getTypeName(type);
+
+}
+
+LfpChannelDisplay::~LfpChannelDisplay()
+{
+
+}
+
+void LfpChannelDisplay::updateType()
+{
+    type = canvas->getChannelType(chan);
+    typeStr = canvas->getTypeName(type);
+}
+
+void LfpChannelDisplay::setEnabledState(bool state)
+{
+
+    //if (state)
+    //std::cout << "Setting channel " << name << " to true." << std::endl;
+    //else
+    //std::cout << "Setting channel " << name << " to false." << std::endl;
+
+    isEnabled = state;
+
+}
+
+void LfpChannelDisplay::paint(Graphics& g)
+{
+
+    //g.fillAll(Colours::grey);
+
+    g.setColour(Colours::yellow);   // draw most recent drawn sample position
+    g.drawLine(canvas->screenBufferIndex[chan]+1, 0, canvas->screenBufferIndex[chan]+1, getHeight());
+
+
+    //g.setColour(Colours::red); // draw oldest drawn sample position
+    //g.drawLine(canvas->lastScreenBufferIndex, 0, canvas->lastScreenBufferIndex, getHeight()-channelOverlap);
+
+    if (isEnabled)
+    {
+
+        int center = getHeight()/2;
+
+        if (isSelected)
+        {
+
+            g.setColour(Colours::lightgrey);
+            g.fillRect(0,center-channelHeight/2,10,channelHeight);
+            g.drawLine(0,center+channelHeight/2,getWidth(),center+channelHeight/2);
+            g.drawLine(0,center-channelHeight/2,getWidth(),center-channelHeight/2);
+
+            if (!display->getSingleChannelState())
+            {
+                g.setColour(Colour(25,25,25));
+                g.drawLine(0,center+channelHeight/4,10,center+channelHeight/4);
+                g.drawLine(0,center-channelHeight/4,10,center-channelHeight/4);
+            }
+            else
+            {
+                g.setColour(Colour(70,70,70));
+                g.drawLine(0,center+channelHeight/4,getWidth(),center+channelHeight/4);
+                g.drawLine(0,center-channelHeight/4,getWidth(),center-channelHeight/4);
+            }
+
+
+        }
+
+        if (display->getSingleChannelState())
+        {
+
+            int leftEdge = 150;
+
+            float r = range;
+
+            g.setColour(Colours::lightgrey);
+            g.setFont(channelFont);
+            g.setFont(20);
+            String unitString;
+            if (getType() == ADC_CHANNEL)
+            {
+                unitString = " V";
+                //r = range / 1000.0f;
+            } else {
+                unitString = " uV";
+            }
+            g.drawText(String(0) + unitString, 20, center, leftEdge, 25, Justification::left, false);
+            g.drawText(String(r/2) + unitString, 20, center-channelHeight/2, leftEdge, 25, Justification::left, false);
+            g.drawText(String(-r/2) + unitString, 20, center+channelHeight/2-25, leftEdge, 25, Justification::left, false);
+            g.drawText(String(r/4) + unitString, 20, center-channelHeight/4, leftEdge, 25, Justification::left, false);
+            g.drawText(String(-r/4) + unitString, 20, center+channelHeight/4, leftEdge, 25, Justification::left, false);
+
+        }
+
+
+        g.setColour(Colour(40,40,40));
+        g.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);
+
+        int stepSize = 1;
+        int from = 0; // for vertical line drawing in the LFP data
+        int to = 0;
+
+        //for (int i = 0; i < getWidth()-stepSize; i += stepSize) // redraw entire display
+        int ifrom = canvas->lastScreenBufferIndex[chan] - 3; // need to start drawing a bit before the actual redraw windowfor the interpolated line to join correctly
+
+        if (ifrom < 0)
+            ifrom = 0;
+
+        int ito = canvas->screenBufferIndex[chan] - 1;
+
+        if (fullredraw)
+        {
+            ifrom = 0; //canvas->leftmargin;
+            ito = getWidth()-stepSize;
+            fullredraw = false;
+        }
+
+        for (int i = ifrom; i < ito ; i += stepSize) // redraw only changed portion
+        {
+
+            // draw event markers
+            int rawEventState = canvas->getYCoord(canvas->getNumChannels(), i);// get last channel+1 in buffer (represents events)
+            
+            //if (i == ifrom)
+            //    std::cout << rawEventState << std::endl;
+
+            for (int ev_ch = 0; ev_ch < 8 ; ev_ch++) // for all event channels
+            {
+                if (display->getEventDisplayState(ev_ch))  // check if plotting for this channel is enabled
+                {
+                    if (rawEventState & (1 << ev_ch))    // events are  representet by a bit code, so we have to extract the individual bits with a mask
+                    {
+                        //std::cout << "Drawing event." << std::endl;
+                        g.setColour(display->channelColours[ev_ch*2]); // get color from lfp color scheme
+                        g.setOpacity(0.35f);
+                        g.drawLine(i, center-channelHeight/2 , i, center+channelHeight/2);
+                    }
+                }
+            }
+
+            //std::cout << "e " << canvas->getYCoord(canvas->getNumChannels()-1, i) << std::endl;
+            g.setColour(lineColour);
+
+            if (drawMethod) // switched between to line drawing and pixel wise drawing
+            {
+
+                // drawLine makes for ok anti-aliased plots, but is pretty slow
+                g.drawLine(i,
+                           (canvas->getYCoord(chan, i)/range*channelHeightFloat)+getHeight()/2,
+                           i+stepSize,
+                           (canvas->getYCoord(chan, i+stepSize)/range*channelHeightFloat)+getHeight()/2);
+
+
+            }
+            else
+            {
+
+                // // pixel wise line plot has no anti-aliasing, but runs much faster
+                double a = (canvas->getYCoordMax(chan, i)/range*channelHeightFloat)+getHeight()/2;
+                double b = (canvas->getYCoordMin(chan, i)/range*channelHeightFloat)+getHeight()/2;
+                //double m = (canvas->getYCoordMean(chan, i)/range*channelHeightFloat)+getHeight()/2;
+                if (a<b)
+                {
+                    from = (a);
+                    to = (b);
+                }
+                else
+                {
+                    from = (b);
+                    to = (a);
+                }
+
+                //g.setColour(lineColour.withMultipliedBrightness( 1+(((((float)(to-from)*range)/getHeight())-0.01)*2)  )); // make spikes etc slightly brighter
+
+
+                if ((to-from) < 200)  // if there is too much vertical range in one pixel, don't draw the full line for speed reasons
+                {
+                    for (int j = from; j <= to; j += 1)
+                    {
+                        g.setPixel(i,j);
+                    }
+                }
+                else if ((to-from) < 400)
+                {
+                    for (int j = from; j <= to; j += 2)
+                    {
+                        g.setPixel(i,j);
+                    }
+                }
+                else
+                {
+                    g.setPixel(i,to);
+                    g.setPixel(i,from);
+                }
+
+                //draw mean
+                //g.setColour(Colours::black);
+                //g.setPixel(i,m);
+
+            }
+
+        }
+    }
+
+    // g.setColour(lineColour.withAlpha(0.7f)); // alpha on seems to decrease draw speed
+    // g.setFont(channelFont);
+    //  g.setFont(channelHeightFloat*0.6);
+
+    // g.drawText(String(chan+1), 10, center-channelHeight/2, 200, channelHeight, Justification::left, false);
+
+
+}
+
+
+PopupMenu LfpChannelDisplay::getOptions()
+{
+
+    PopupMenu menu;
+    menu.addItem(1, "Invert signal", true, inputInverted);
+
+    return menu;
+}
+
+void LfpChannelDisplay::changeParameter(int id)
+{
+    switch (id)
+    {
+        case 1:
+            setInputInverted(!inputInverted);
+        default:
+            break;
+    }
+}
+
+void LfpChannelDisplay::setRange(float r)
+{
+    
+    range = r;
+
+    //std::cout << "Range: " << r << std::endl;
+}
+
+int LfpChannelDisplay::getRange()
+{
+    return range;
+}
+
+
+void LfpChannelDisplay::select()
+{
+    isSelected = true;
+}
+
+void LfpChannelDisplay::deselect()
+{
+    isSelected = false;
+}
+
+bool LfpChannelDisplay::getSelected()
+{
+   return isSelected;
+}
+
+void LfpChannelDisplay::setColour(Colour c)
+{
+    lineColour = c;
+}
+
+
+void LfpChannelDisplay::setChannelHeight(int c)
+{
+    channelHeight = c;
+
+    channelHeightFloat = (float) channelHeight;
+
+    if (!inputInverted)
+        channelHeightFloat = -channelHeightFloat;
+
+    channelOverlap = channelHeight*5;
+}
+
+int LfpChannelDisplay::getChannelHeight()
+{
+
+    return channelHeight;
+}
+
+void LfpChannelDisplay::setChannelOverlap(int overlap)
+{
+    channelOverlap = overlap;
+}
+
+
+int LfpChannelDisplay::getChannelOverlap()
+{
+    return channelOverlap;
+}
+
+void LfpChannelDisplay::setCanBeInverted(bool _canBeInverted)
+{
+    canBeInverted = _canBeInverted;
+}
+
+void LfpChannelDisplay::setInputInverted(bool isInverted)
+{
+    if (canBeInverted)
+    {
+        inputInverted = isInverted;
+        setChannelHeight(channelHeight);
+    }
+}
+
+void LfpChannelDisplay::setDrawMethod(bool isDrawMethod)
+{
+
+    drawMethod = isDrawMethod;
+
+}
+
+
+void LfpChannelDisplay::setName(String name_)
+{
+    name = name_;
+}
+
+ChannelType LfpChannelDisplay::getType()
+{
+    return type;
+}
+
+// -------------------------------
+
+LfpChannelDisplayInfo::LfpChannelDisplayInfo(LfpDisplayCanvas* canvas_, LfpDisplay* display_, int ch)
+    : LfpChannelDisplay(canvas_, display_, ch)
+{
+
+    chan = ch;
+
+    enableButton = new UtilityButton(String(ch+1), Font("Small Text", 13, Font::plain));
+    enableButton->setRadius(5.0f);
+
+    enableButton->setEnabledState(true);
+    enableButton->setCorners(true, true, true, true);
+    enableButton->addListener(this);
+    enableButton->setClickingTogglesState(true);
+    enableButton->setToggleState(true, dontSendNotification);
+
+    addAndMakeVisible(enableButton);
+
+}
+
+void LfpChannelDisplayInfo::updateType()
+{
+    type = canvas->getChannelType(chan);
+    typeStr = canvas->getTypeName(type);
+    repaint();
+}
+
+void LfpChannelDisplayInfo::buttonClicked(Button* button)
+{
+
+    bool state = button->getToggleState();
+
+    display->setEnabledState(state, chan);
+
+    //UtilityButton* b = (UtilityButton*) button;
+
+    // if (state)
+    // {
+    //  b->setLabel("ON");
+    // } else {
+    //  b->setLabel("OFF");
+    // }
+
+    //std::cout << "Turn channel " << chan << " to " << button->getToggleState() << std::endl;
+
+}
+
+void LfpChannelDisplayInfo::setEnabledState(bool state)
+{
+    enableButton->setToggleState(state, sendNotification);
+}
+
+void LfpChannelDisplayInfo::paint(Graphics& g)
+{
+
+    int center = getHeight()/2;
+
+    g.setColour(lineColour);
+
+    //if (chan > 98)
+    //  g.fillRoundedRectangle(5,center-8,51,22,8.0f);
+    //else
+    g.fillRoundedRectangle(5,center-8,41,22,8.0f);
+
+      g.setFont(Font("Small Text", 13, Font::plain));
+      g.drawText(typeStr,5,center+16,41,10,Justification::centred,false);
+    // g.setFont(channelHeightFloat*0.3);
+
+    //  g.drawText(name, 10, center-channelHeight/2, 200, channelHeight, Justification::left, false);
+
+}
+
+void LfpChannelDisplayInfo::resized()
+{
+
+    int center = getHeight()/2;
+
+    //if (chan > 98)
+    //  enableButton->setBounds(8,center-5,45,16);
+    //else
+    enableButton->setBounds(8,center-5,35,16);
+}
+
+
+// Event display Options --------------------------------------------------------------------
+
+EventDisplayInterface::EventDisplayInterface(LfpDisplay* display_, LfpDisplayCanvas* canvas_, int chNum):
+    isEnabled(true), display(display_), canvas(canvas_)
+{
+
+    channelNumber = chNum;
+
+    chButton = new UtilityButton(String(channelNumber+1), Font("Small Text", 13, Font::plain));
+    chButton->setRadius(5.0f);
+    chButton->setBounds(4,4,14,14);
+    chButton->setEnabledState(true);
+    chButton->setCorners(true, false, true, false);
+    //chButton.color = display->channelColours[channelNumber*2];
+    chButton->addListener(this);
+    addAndMakeVisible(chButton);
+
+
+    checkEnabledState();
+
+}
+
+EventDisplayInterface::~EventDisplayInterface()
+{
+
+}
+
+void EventDisplayInterface::checkEnabledState()
+{
+    isEnabled = display->getEventDisplayState(channelNumber);
+
+    //repaint();
+}
+
+void EventDisplayInterface::buttonClicked(Button* button)
+{
+    checkEnabledState();
+    if (isEnabled)
+    {
+        display->setEventDisplayState(channelNumber, false);
+    }
+    else
+    {
+        display->setEventDisplayState(channelNumber, true);
+    }
+
+    repaint();
+
+}
+
+
+void EventDisplayInterface::paint(Graphics& g)
+{
+
+    checkEnabledState();
+
+    if (isEnabled)
+    {
+        g.setColour(display->channelColours[channelNumber*2]);
+        g.fillRoundedRectangle(2,2,18,18,5.0f);
+    }
+
+
+    //g.drawText(String(channelNumber), 8, 2, 200, 15, Justification::left, false);
+
+}
+
+// Lfp Viewport -------------------------------------------
+
+LfpViewport::LfpViewport(LfpDisplayCanvas *canvas)
+    : Viewport()
+{
+    this->canvas = canvas;
+}
+
+void LfpViewport::visibleAreaChanged(const Rectangle<int>& newVisibleArea)
+{
+    canvas->fullredraw = true;
+    canvas->refresh();
+}
diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h
old mode 100755
new mode 100644
similarity index 95%
rename from Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h
rename to Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h
index cf0d360db20d8f5622780f5bbf497c3274e5401f..0e99bf01dc1058ee1001a2f3a05a262c373e6648
--- a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h
+++ b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h
@@ -1,417 +1,417 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2013 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 __LFPDISPLAYCANVAS_H_B711873A__
-#define __LFPDISPLAYCANVAS_H_B711873A__
-
-#include "../../../JuceLibraryCode/JuceHeader.h"
-#include "LfpDisplayNode.h"
-#include "../Visualization/Visualizer.h"
-#define CHANNEL_TYPES 3
-
-class LfpDisplayNode;
-
-class LfpTimescale;
-class LfpDisplay;
-class LfpChannelDisplay;
-class LfpChannelDisplayInfo;
-class EventDisplayInterface;
-class LfpViewport;
-
-/**
-
-  Displays multiple channels of continuous data.
-
-  @see LfpDisplayNode, LfpDisplayEditor
-
-*/
-
-class LfpDisplayCanvas : public Visualizer,
-    public ComboBox::Listener,
-    public Button::Listener,
-    public KeyListener
-
-{
-public:
-    LfpDisplayCanvas(LfpDisplayNode* n);
-    ~LfpDisplayCanvas();
-
-    void beginAnimation();
-    void endAnimation();
-
-    void refreshState();
-    void update();
-
-    void setParameter(int, float);
-    void setParameter(int, int, int, float) {}
-
-    void setRangeSelection(float range, bool canvasMustUpdate = false); // set range selection combo box to correct value if it has been changed by scolling etc.
-    void setSpreadSelection(int spread, bool canvasMustUpdate = false); // set spread selection combo box to correct value if it has been changed by scolling etc.
-
-    void paint(Graphics& g);
-
-    void refresh();
-
-    void resized();
-
-    int getChannelHeight();
-
-    int getNumChannels();
-    bool getInputInvertedState();
-    bool getDrawMethodState();
-
-    const float getXCoord(int chan, int samp);
-    const float getYCoord(int chan, int samp);
-
-    const float getYCoordMin(int chan, int samp);
-    const float getYCoordMean(int chan, int samp);
-    const float getYCoordMax(int chan, int samp);
-
-    Array<int> screenBufferIndex;
-    Array<int> lastScreenBufferIndex;
-
-    void comboBoxChanged(ComboBox* cb);
-    void buttonClicked(Button* button);
-
-    void saveVisualizerParameters(XmlElement* xml);
-    void loadVisualizerParameters(XmlElement* xml);
-
-    bool keyPressed(const KeyPress& key);
-    bool keyPressed(const KeyPress& key, Component* orig);
-
-    ChannelType getChannelType(int n);
-    ChannelType getSelectedType();
-    String getTypeName(ChannelType type);
-    int getRangeStep(ChannelType type);
-
-    void setSelectedType(ChannelType type, bool toggleButton = true);
-
-    //void scrollBarMoved(ScrollBar *scrollBarThatHasMoved, double newRangeStart);
-
-    bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw, there is a similar switch for ach ch display;
-    static const int leftmargin=50; // left margin for lfp plots (so the ch number text doesnt overlap)
-
-    Array<bool> isChannelEnabled;
-
-    int nChans;
-
-private:
-
-    Array<float> sampleRate;
-    float timebase;
-    float displayGain;
-    float timeOffset;
-    //int spread ; // vertical spacing between channels
-
-
-    static const int MAX_N_CHAN = 2048;  // maximum number of channels
-    static const int MAX_N_SAMP = 5000; // maximum display size in pixels
-    //float waves[MAX_N_CHAN][MAX_N_SAMP*2]; // we need an x and y point for each sample
-
-    LfpDisplayNode* processor;
-    AudioSampleBuffer* displayBuffer; // sample wise data buffer for display
-    AudioSampleBuffer* screenBuffer; // subsampled buffer- one int per pixel
-
-    //'define 3 buffers for min mean and max for better plotting of spikes
-    // not pretty, but 'AudioSampleBuffer works only for channels X samples
-    AudioSampleBuffer* screenBufferMin; // like screenBuffer but holds min/mean/max values per pixel
-    AudioSampleBuffer* screenBufferMean; // like screenBuffer but holds min/mean/max values per pixel
-    AudioSampleBuffer* screenBufferMax; // like screenBuffer but holds min/mean/max values per pixel
-
-    MidiBuffer* eventBuffer;
-
-    ScopedPointer<LfpTimescale> timescale;
-    ScopedPointer<LfpDisplay> lfpDisplay;
-    ScopedPointer<LfpViewport> viewport;
-
-    ScopedPointer<ComboBox> timebaseSelection;
-    ScopedPointer<ComboBox> rangeSelection;
-    ScopedPointer<ComboBox> spreadSelection;
-    ScopedPointer<ComboBox> colorGroupingSelection;
-    ScopedPointer<UtilityButton> invertInputButton;
-    ScopedPointer<UtilityButton> drawMethodButton;
-    ScopedPointer<UtilityButton> pauseButton;
-    OwnedArray<UtilityButton> typeButtons;
-
-    StringArray voltageRanges[CHANNEL_TYPES];
-    StringArray timebases;
-    StringArray spreads; // option for vertical spacing between channels
-    StringArray colorGroupings; // option for coloring every N channels the same
-
-    ChannelType selectedChannelType;
-    int selectedVoltageRange[CHANNEL_TYPES];
-    String selectedVoltageRangeValues[CHANNEL_TYPES];
-    float rangeGain[CHANNEL_TYPES];
-    StringArray rangeUnits;
-    StringArray typeNames;
-    int rangeSteps[CHANNEL_TYPES];
-
-    int selectedSpread;
-    String selectedSpreadValue;
-
-    int selectedTimebase;
-    String selectedTimebaseValue;
-
-    OwnedArray<EventDisplayInterface> eventDisplayInterfaces;
-
-    void refreshScreenBuffer();
-    void updateScreenBuffer();
-
-    Array<int> displayBufferIndex;
-    int displayBufferSize;
-
-    int scrollBarThickness;
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayCanvas);
-
-};
-
-class LfpTimescale : public Component
-{
-public:
-    LfpTimescale(LfpDisplayCanvas*);
-    ~LfpTimescale();
-
-    void paint(Graphics& g);
-
-    void setTimebase(float t);
-
-private:
-
-    LfpDisplayCanvas* canvas;
-
-    float timebase;
-
-    Font font;
-
-    StringArray labels;
-
-};
-
-class LfpDisplay : public Component
-{
-public:
-    LfpDisplay(LfpDisplayCanvas*, Viewport*);
-    ~LfpDisplay();
-
-    void setNumChannels(int numChannels);
-    int getNumChannels();
-
-    int getTotalHeight();
-
-    void paint(Graphics& g);
-
-    void refresh();
-
-    void resized();
-
-    void mouseDown(const MouseEvent& event);
-    void mouseWheelMove(const MouseEvent&  event, const MouseWheelDetails&   wheel) ;
-
-
-    void setRange(float range, ChannelType type);
-    
-    //Withouth parameters returns selected type
-    int getRange();
-    int getRange(ChannelType type);
-
-    void setChannelHeight(int r, bool resetSingle = true);
-    int getChannelHeight();
-    void setInputInverted(bool);
-    void setDrawMethod(bool);
-
-    void setColors();
-
-    bool setEventDisplayState(int ch, bool state);
-    bool getEventDisplayState(int ch);
-
-    int getColorGrouping();
-    void setColorGrouping(int i);
-
-    void setEnabledState(bool, int);
-    bool getEnabledState(int);
-    void enableChannel(bool, int);
-
-    bool getSingleChannelState();
-
-    Array<Colour> channelColours;
-
-    Array<LfpChannelDisplay*> channels;
-    Array<LfpChannelDisplayInfo*> channelInfo;
-
-    bool eventDisplayEnabled[8];
-    bool isPaused; // simple pause function, skips screen bufer updates
-
-private:
-    void toggleSingleChannel(int chan);
-    int singleChan;
-	Array<bool> savedChannelState;
-
-    int numChans;
-
-    int totalHeight;
-
-    int colorGrouping;
-
-    LfpDisplayCanvas* canvas;
-    Viewport* viewport;
-
-    float range[3];
-
-
-};
-
-class LfpChannelDisplay : public Component
-{
-public:
-    LfpChannelDisplay(LfpDisplayCanvas*, LfpDisplay*, int channelNumber);
-    ~LfpChannelDisplay();
-
-    void paint(Graphics& g);
-
-    void select();
-    void deselect();
-
-    bool getSelected();
-
-    void setName(String);
-
-    void setColour(Colour c);
-
-    void setChannelHeight(int);
-    int getChannelHeight();
-
-    void setChannelOverlap(int);
-    int getChannelOverlap();
-
-    void setRange(float range);
-    int getRange();
-
-    void setInputInverted(bool);
-    void setCanBeInverted(bool);
-
-    void setDrawMethod(bool);
-
-    PopupMenu getOptions();
-    void changeParameter(const int id);
-
-    void setEnabledState(bool);
-    bool getEnabledState()
-    {
-        return isEnabled;
-    }
-
-    ChannelType getType();
-    void updateType();
-
-    bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw
-
-protected:
-
-    LfpDisplayCanvas* canvas;
-    LfpDisplay* display;
-
-    bool isSelected;
-
-    int chan;
-
-    String name;
-
-    Font channelFont;
-
-    Colour lineColour;
-
-    int channelOverlap;
-    int channelHeight;
-    float channelHeightFloat;
-
-    float range;
-
-    bool isEnabled;
-    bool inputInverted;
-    bool canBeInverted;
-    bool drawMethod;
-
-    ChannelType type;
-    String typeStr;
-
-};
-
-class LfpChannelDisplayInfo : public LfpChannelDisplay,
-    public Button::Listener
-{
-public:
-    LfpChannelDisplayInfo(LfpDisplayCanvas*, LfpDisplay*, int channelNumber);
-
-    void paint(Graphics& g);
-
-    void buttonClicked(Button* button);
-
-    void resized();
-
-    void setEnabledState(bool);
-    void updateType();
-
-private:
-
-    ScopedPointer<UtilityButton> enableButton;
-
-};
-
-class EventDisplayInterface : public Component,
-    public Button::Listener
-{
-public:
-    EventDisplayInterface(LfpDisplay*, LfpDisplayCanvas*, int chNum);
-    ~EventDisplayInterface();
-
-    void paint(Graphics& g);
-
-    void buttonClicked(Button* button);
-
-    void checkEnabledState();
-
-    bool isEnabled;
-
-private:
-
-    int channelNumber;
-
-    LfpDisplay* display;
-    LfpDisplayCanvas* canvas;
-
-    ScopedPointer<UtilityButton> chButton;
-
-};
-
-class LfpViewport : public Viewport
-{
-public:
-    LfpViewport(LfpDisplayCanvas* canvas);
-    void visibleAreaChanged(const Rectangle<int>& newVisibleArea);
-
-private:
-    LfpDisplayCanvas* canvas;
-};
-
-
-#endif  // __LFPDISPLAYCANVAS_H_B711873A__
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2013 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 __LFPDISPLAYCANVAS_H_B711873A__
+#define __LFPDISPLAYCANVAS_H_B711873A__
+
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "LfpDisplayNode.h"
+#include "../../Processors/Visualization/Visualizer.h"
+#define CHANNEL_TYPES 3
+
+class LfpDisplayNode;
+
+class LfpTimescale;
+class LfpDisplay;
+class LfpChannelDisplay;
+class LfpChannelDisplayInfo;
+class EventDisplayInterface;
+class LfpViewport;
+
+/**
+
+  Displays multiple channels of continuous data.
+
+  @see LfpDisplayNode, LfpDisplayEditor
+
+*/
+
+class LfpDisplayCanvas : public Visualizer,
+    public ComboBox::Listener,
+    public Button::Listener,
+    public KeyListener
+
+{
+public:
+    LfpDisplayCanvas(LfpDisplayNode* n);
+    ~LfpDisplayCanvas();
+
+    void beginAnimation();
+    void endAnimation();
+
+    void refreshState();
+    void update();
+
+    void setParameter(int, float);
+    void setParameter(int, int, int, float) {}
+
+    void setRangeSelection(float range, bool canvasMustUpdate = false); // set range selection combo box to correct value if it has been changed by scolling etc.
+    void setSpreadSelection(int spread, bool canvasMustUpdate = false); // set spread selection combo box to correct value if it has been changed by scolling etc.
+
+    void paint(Graphics& g);
+
+    void refresh();
+
+    void resized();
+
+    int getChannelHeight();
+
+    int getNumChannels();
+    bool getInputInvertedState();
+    bool getDrawMethodState();
+
+    const float getXCoord(int chan, int samp);
+    const float getYCoord(int chan, int samp);
+
+    const float getYCoordMin(int chan, int samp);
+    const float getYCoordMean(int chan, int samp);
+    const float getYCoordMax(int chan, int samp);
+
+    Array<int> screenBufferIndex;
+    Array<int> lastScreenBufferIndex;
+
+    void comboBoxChanged(ComboBox* cb);
+    void buttonClicked(Button* button);
+
+    void saveVisualizerParameters(XmlElement* xml);
+    void loadVisualizerParameters(XmlElement* xml);
+
+    bool keyPressed(const KeyPress& key);
+    bool keyPressed(const KeyPress& key, Component* orig);
+
+    ChannelType getChannelType(int n);
+    ChannelType getSelectedType();
+    String getTypeName(ChannelType type);
+    int getRangeStep(ChannelType type);
+
+    void setSelectedType(ChannelType type, bool toggleButton = true);
+
+    //void scrollBarMoved(ScrollBar *scrollBarThatHasMoved, double newRangeStart);
+
+    bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw, there is a similar switch for ach ch display;
+    static const int leftmargin=50; // left margin for lfp plots (so the ch number text doesnt overlap)
+
+    Array<bool> isChannelEnabled;
+
+    int nChans;
+
+private:
+
+    Array<float> sampleRate;
+    float timebase;
+    float displayGain;
+    float timeOffset;
+    //int spread ; // vertical spacing between channels
+
+
+    static const int MAX_N_CHAN = 2048;  // maximum number of channels
+    static const int MAX_N_SAMP = 5000; // maximum display size in pixels
+    //float waves[MAX_N_CHAN][MAX_N_SAMP*2]; // we need an x and y point for each sample
+
+    LfpDisplayNode* processor;
+    AudioSampleBuffer* displayBuffer; // sample wise data buffer for display
+    AudioSampleBuffer* screenBuffer; // subsampled buffer- one int per pixel
+
+    //'define 3 buffers for min mean and max for better plotting of spikes
+    // not pretty, but 'AudioSampleBuffer works only for channels X samples
+    AudioSampleBuffer* screenBufferMin; // like screenBuffer but holds min/mean/max values per pixel
+    AudioSampleBuffer* screenBufferMean; // like screenBuffer but holds min/mean/max values per pixel
+    AudioSampleBuffer* screenBufferMax; // like screenBuffer but holds min/mean/max values per pixel
+
+    MidiBuffer* eventBuffer;
+
+    ScopedPointer<LfpTimescale> timescale;
+    ScopedPointer<LfpDisplay> lfpDisplay;
+    ScopedPointer<LfpViewport> viewport;
+
+    ScopedPointer<ComboBox> timebaseSelection;
+    ScopedPointer<ComboBox> rangeSelection;
+    ScopedPointer<ComboBox> spreadSelection;
+    ScopedPointer<ComboBox> colorGroupingSelection;
+    ScopedPointer<UtilityButton> invertInputButton;
+    ScopedPointer<UtilityButton> drawMethodButton;
+    ScopedPointer<UtilityButton> pauseButton;
+    OwnedArray<UtilityButton> typeButtons;
+
+    StringArray voltageRanges[CHANNEL_TYPES];
+    StringArray timebases;
+    StringArray spreads; // option for vertical spacing between channels
+    StringArray colorGroupings; // option for coloring every N channels the same
+
+    ChannelType selectedChannelType;
+    int selectedVoltageRange[CHANNEL_TYPES];
+    String selectedVoltageRangeValues[CHANNEL_TYPES];
+    float rangeGain[CHANNEL_TYPES];
+    StringArray rangeUnits;
+    StringArray typeNames;
+    int rangeSteps[CHANNEL_TYPES];
+
+    int selectedSpread;
+    String selectedSpreadValue;
+
+    int selectedTimebase;
+    String selectedTimebaseValue;
+
+    OwnedArray<EventDisplayInterface> eventDisplayInterfaces;
+
+    void refreshScreenBuffer();
+    void updateScreenBuffer();
+
+    Array<int> displayBufferIndex;
+    int displayBufferSize;
+
+    int scrollBarThickness;
+
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayCanvas);
+
+};
+
+class LfpTimescale : public Component
+{
+public:
+    LfpTimescale(LfpDisplayCanvas*);
+    ~LfpTimescale();
+
+    void paint(Graphics& g);
+
+    void setTimebase(float t);
+
+private:
+
+    LfpDisplayCanvas* canvas;
+
+    float timebase;
+
+    Font font;
+
+    StringArray labels;
+
+};
+
+class LfpDisplay : public Component
+{
+public:
+    LfpDisplay(LfpDisplayCanvas*, Viewport*);
+    ~LfpDisplay();
+
+    void setNumChannels(int numChannels);
+    int getNumChannels();
+
+    int getTotalHeight();
+
+    void paint(Graphics& g);
+
+    void refresh();
+
+    void resized();
+
+    void mouseDown(const MouseEvent& event);
+    void mouseWheelMove(const MouseEvent&  event, const MouseWheelDetails&   wheel) ;
+
+
+    void setRange(float range, ChannelType type);
+    
+    //Withouth parameters returns selected type
+    int getRange();
+    int getRange(ChannelType type);
+
+    void setChannelHeight(int r, bool resetSingle = true);
+    int getChannelHeight();
+    void setInputInverted(bool);
+    void setDrawMethod(bool);
+
+    void setColors();
+
+    bool setEventDisplayState(int ch, bool state);
+    bool getEventDisplayState(int ch);
+
+    int getColorGrouping();
+    void setColorGrouping(int i);
+
+    void setEnabledState(bool, int);
+    bool getEnabledState(int);
+    void enableChannel(bool, int);
+
+    bool getSingleChannelState();
+
+    Array<Colour> channelColours;
+
+    Array<LfpChannelDisplay*> channels;
+    Array<LfpChannelDisplayInfo*> channelInfo;
+
+    bool eventDisplayEnabled[8];
+    bool isPaused; // simple pause function, skips screen bufer updates
+
+private:
+    void toggleSingleChannel(int chan);
+    int singleChan;
+	Array<bool> savedChannelState;
+
+    int numChans;
+
+    int totalHeight;
+
+    int colorGrouping;
+
+    LfpDisplayCanvas* canvas;
+    Viewport* viewport;
+
+    float range[3];
+
+
+};
+
+class LfpChannelDisplay : public Component
+{
+public:
+    LfpChannelDisplay(LfpDisplayCanvas*, LfpDisplay*, int channelNumber);
+    ~LfpChannelDisplay();
+
+    void paint(Graphics& g);
+
+    void select();
+    void deselect();
+
+    bool getSelected();
+
+    void setName(String);
+
+    void setColour(Colour c);
+
+    void setChannelHeight(int);
+    int getChannelHeight();
+
+    void setChannelOverlap(int);
+    int getChannelOverlap();
+
+    void setRange(float range);
+    int getRange();
+
+    void setInputInverted(bool);
+    void setCanBeInverted(bool);
+
+    void setDrawMethod(bool);
+
+    PopupMenu getOptions();
+    void changeParameter(const int id);
+
+    void setEnabledState(bool);
+    bool getEnabledState()
+    {
+        return isEnabled;
+    }
+
+    ChannelType getType();
+    void updateType();
+
+    bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw
+
+protected:
+
+    LfpDisplayCanvas* canvas;
+    LfpDisplay* display;
+
+    bool isSelected;
+
+    int chan;
+
+    String name;
+
+    Font channelFont;
+
+    Colour lineColour;
+
+    int channelOverlap;
+    int channelHeight;
+    float channelHeightFloat;
+
+    float range;
+
+    bool isEnabled;
+    bool inputInverted;
+    bool canBeInverted;
+    bool drawMethod;
+
+    ChannelType type;
+    String typeStr;
+
+};
+
+class LfpChannelDisplayInfo : public LfpChannelDisplay,
+    public Button::Listener
+{
+public:
+    LfpChannelDisplayInfo(LfpDisplayCanvas*, LfpDisplay*, int channelNumber);
+
+    void paint(Graphics& g);
+
+    void buttonClicked(Button* button);
+
+    void resized();
+
+    void setEnabledState(bool);
+    void updateType();
+
+private:
+
+    ScopedPointer<UtilityButton> enableButton;
+
+};
+
+class EventDisplayInterface : public Component,
+    public Button::Listener
+{
+public:
+    EventDisplayInterface(LfpDisplay*, LfpDisplayCanvas*, int chNum);
+    ~EventDisplayInterface();
+
+    void paint(Graphics& g);
+
+    void buttonClicked(Button* button);
+
+    void checkEnabledState();
+
+    bool isEnabled;
+
+private:
+
+    int channelNumber;
+
+    LfpDisplay* display;
+    LfpDisplayCanvas* canvas;
+
+    ScopedPointer<UtilityButton> chButton;
+
+};
+
+class LfpViewport : public Viewport
+{
+public:
+    LfpViewport(LfpDisplayCanvas* canvas);
+    void visibleAreaChanged(const Rectangle<int>& newVisibleArea);
+
+private:
+    LfpDisplayCanvas* canvas;
+};
+
+
+#endif  // __LFPDISPLAYCANVAS_H_B711873A__
diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayEditor.cpp b/Source/Plugins/LfpDisplayNode/LfpDisplayEditor.cpp
old mode 100755
new mode 100644
similarity index 96%
rename from Source/Processors/LfpDisplayNode/LfpDisplayEditor.cpp
rename to Source/Plugins/LfpDisplayNode/LfpDisplayEditor.cpp
index b5564dd525351bf80d48253334697989aa51128b..cf75ba71b2915b523a32de968c977572cb8c947a
--- a/Source/Processors/LfpDisplayNode/LfpDisplayEditor.cpp
+++ b/Source/Plugins/LfpDisplayNode/LfpDisplayEditor.cpp
@@ -1,66 +1,66 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2013 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 "LfpDisplayEditor.h"
-
-
-LfpDisplayEditor::LfpDisplayEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true)
-    : VisualizerEditor(parentNode, useDefaultParameterEditors)
-
-{
-
-    tabText = "LFP";
-
-    desiredWidth = 180;
-
-}
-
-LfpDisplayEditor::~LfpDisplayEditor()
-{
-}
-
-
-Visualizer* LfpDisplayEditor::createNewCanvas()
-{
-
-    LfpDisplayNode* processor = (LfpDisplayNode*) getProcessor();
-    return new LfpDisplayCanvas(processor);
-
-}
-
-void LfpDisplayEditor::buttonCallback(Button* button)
-{
-
-    int gId = button->getRadioGroupId();
-
-    if (gId > 0)
-    {
-        if (canvas != 0)
-        {
-            canvas->setParameter(gId-1, button->getName().getFloatValue());
-        }
-
-    }
-
-}
-
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2013 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 "LfpDisplayEditor.h"
+
+
+LfpDisplayEditor::LfpDisplayEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true)
+    : VisualizerEditor(parentNode, useDefaultParameterEditors)
+
+{
+
+    tabText = "LFP";
+
+    desiredWidth = 180;
+
+}
+
+LfpDisplayEditor::~LfpDisplayEditor()
+{
+}
+
+
+Visualizer* LfpDisplayEditor::createNewCanvas()
+{
+
+    LfpDisplayNode* processor = (LfpDisplayNode*) getProcessor();
+    return new LfpDisplayCanvas(processor);
+
+}
+
+void LfpDisplayEditor::buttonCallback(Button* button)
+{
+
+    int gId = button->getRadioGroupId();
+
+    if (gId > 0)
+    {
+        if (canvas != 0)
+        {
+            canvas->setParameter(gId-1, button->getName().getFloatValue());
+        }
+
+    }
+
+}
+
diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayEditor.h b/Source/Plugins/LfpDisplayNode/LfpDisplayEditor.h
old mode 100755
new mode 100644
similarity index 89%
rename from Source/Processors/LfpDisplayNode/LfpDisplayEditor.h
rename to Source/Plugins/LfpDisplayNode/LfpDisplayEditor.h
index c6fcf331ac2df106b37140c6f9bb2ca34269f3f8..41af1b9d6d150ab99853ec1c9c8c791a603ccf05
--- a/Source/Processors/LfpDisplayNode/LfpDisplayEditor.h
+++ b/Source/Plugins/LfpDisplayNode/LfpDisplayEditor.h
@@ -1,63 +1,63 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2013 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 __LFPDISPLAYEDITOR_H_3438800D__
-#define __LFPDISPLAYEDITOR_H_3438800D__
-
-#include "../../../JuceLibraryCode/JuceHeader.h"
-#include "../Editors/GenericEditor.h"
-#include "../../UI/UIComponent.h"
-#include "../../UI/DataViewport.h"
-#include "../Visualization/DataWindow.h"
-#include "LfpDisplayNode.h"
-#include "LfpDisplayCanvas.h"
-#include "../Editors/VisualizerEditor.h"
-
-class Visualizer;
-
-/**
-
-  User interface for the LfpDisplayNode sink.
-
-  @see LfpDisplayNode, LfpDisplayCanvas
-
-*/
-
-class LfpDisplayEditor : public VisualizerEditor
-{
-public:
-    LfpDisplayEditor(GenericProcessor*, bool useDefaultParameterEditors);
-    ~LfpDisplayEditor();
-
-    void buttonCallback(Button* button);
-
-    Visualizer* createNewCanvas();
-
-private:
-
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayEditor);
-
-};
-
-#endif  // __LFPDISPLAYEDITOR_H_3438800D__
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2013 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 __LFPDISPLAYEDITOR_H_3438800D__
+#define __LFPDISPLAYEDITOR_H_3438800D__
+
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "../../Processors/Editors/GenericEditor.h"
+#include "../../UI/UIComponent.h"
+#include "../../UI/DataViewport.h"
+#include "../../Processors/Visualization/DataWindow.h"
+#include "LfpDisplayNode.h"
+#include "LfpDisplayCanvas.h"
+#include "../../Processors/Editors/VisualizerEditor.h"
+
+class Visualizer;
+
+/**
+
+  User interface for the LfpDisplayNode sink.
+
+  @see LfpDisplayNode, LfpDisplayCanvas
+
+*/
+
+class LfpDisplayEditor : public VisualizerEditor
+{
+public:
+    LfpDisplayEditor(GenericProcessor*, bool useDefaultParameterEditors);
+    ~LfpDisplayEditor();
+
+    void buttonCallback(Button* button);
+
+    Visualizer* createNewCanvas();
+
+private:
+
+
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayEditor);
+
+};
+
+#endif  // __LFPDISPLAYEDITOR_H_3438800D__
diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp b/Source/Plugins/LfpDisplayNode/LfpDisplayNode.cpp
old mode 100755
new mode 100644
similarity index 97%
rename from Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp
rename to Source/Plugins/LfpDisplayNode/LfpDisplayNode.cpp
index 701569a494ada5db42882c6810affa6e16c9d546..dd6f87769292ea4d3d80d0eed29cff3a9ac88b04
--- a/Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp
+++ b/Source/Plugins/LfpDisplayNode/LfpDisplayNode.cpp
@@ -1,347 +1,347 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2013 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 "LfpDisplayNode.h"
-#include "LfpDisplayCanvas.h"
-#include <stdio.h>
-
-LfpDisplayNode::LfpDisplayNode()
-    : GenericProcessor("LFP Viewer"),
-      displayGain(1), bufferLength(5.0f),
-      abstractFifo(100)
-{
-    //std::cout << " LFPDisplayNodeConstructor" << std::endl;
-    displayBuffer = new AudioSampleBuffer(8, 100);
-
-    arrayOfOnes = new float[5000];
-
-    for (int n = 0; n < 5000; n++)
-    {
-        arrayOfOnes[n] = 1;
-    }
-
-}
-
-LfpDisplayNode::~LfpDisplayNode()
-{
-
-}
-
-AudioProcessorEditor* LfpDisplayNode::createEditor()
-{
-
-    editor = new LfpDisplayEditor(this, true);
-    return editor;
-
-}
-
-void LfpDisplayNode::updateSettings()
-{
-    std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl;
-
-    channelForEventSource.clear();
-    eventSourceNodes.clear();
-    ttlState.clear();
-
-    for (int i = 0; i < eventChannels.size(); i++)
-    {
-        if (!eventSourceNodes.contains(eventChannels[i]->sourceNodeId) && eventChannels[i]->type == EVENT_CHANNEL)
-        {
-            eventSourceNodes.add(eventChannels[i]->sourceNodeId);
-
-        }
-    }\
-
-    numEventChannels = eventSourceNodes.size();
-
-    std::cout << "Found " << numEventChannels << " event channels." << std::endl;
-
-    for (int i = 0; i < eventSourceNodes.size(); i++)
-    {
-        std::cout << "Adding channel " << getNumInputs() + i << " for event source node " << eventSourceNodes[i] << std::endl;
-        channelForEventSource[eventSourceNodes[i]] = getNumInputs() + i;
-        ttlState[eventSourceNodes[i]] = 0;
-        Channel* eventChan = new Channel(this, getNumInputs() + i, EVENT_CHANNEL);
-        eventChan->sourceNodeId = eventSourceNodes[i];
-        channels.add(eventChan); // add a channel for event data for each source node
-    }
-
-    displayBufferIndex.clear();
-    displayBufferIndex.insertMultiple(0, 0, getNumInputs() + numEventChannels);
-
-}
-
-bool LfpDisplayNode::resizeBuffer()
-{
-    int nSamples = (int) getSampleRate()*bufferLength;
-    int nInputs = getNumInputs();
-
-    std::cout << "Resizing buffer. Samples: " << nSamples << ", Inputs: " << nInputs << std::endl;
-
-    if (nSamples > 0 && nInputs > 0)
-    {
-        abstractFifo.setTotalSize(nSamples);
-        displayBuffer->setSize(nInputs + numEventChannels, nSamples); // add extra channels for TTLs
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-
-}
-
-bool LfpDisplayNode::enable()
-{
-
-    if (resizeBuffer())
-    {
-        LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
-        editor->enable();
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-
-}
-
-bool LfpDisplayNode::disable()
-{
-    LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
-    editor->disable();
-    return true;
-}
-
-void LfpDisplayNode::setParameter(int parameterIndex, float newValue)
-{
-    editor->updateParameterButtons(parameterIndex);
-    //Sets Parameter in parameters array for processor
-    Parameter* parameterPointer = parameters.getRawDataPointer();
-    parameterPointer = parameterPointer+parameterIndex;
-    parameterPointer->setValue(newValue, currentChannel);
-
-    //std::cout << "Saving Parameter from " << currentChannel << ", channel ";
-
-    LfpDisplayEditor* ed = (LfpDisplayEditor*) getEditor();
-    if (ed->canvas != 0)
-        ed->canvas->setParameter(parameterIndex, newValue);
-}
-
-void LfpDisplayNode::handleEvent(int eventType, MidiMessage& event, int sampleNum)
-{
-    if (eventType == TTL)
-    {
-        const uint8* dataptr = event.getRawData();
-
-        //int eventNodeId = *(dataptr+1);
-        int eventId = *(dataptr+2);
-        int eventChannel = *(dataptr+3);
-        int eventTime = event.getTimeStamp();
-
-        int eventSourceNodeId = *(dataptr+5);
-
-        int nSamples = numSamples.at(eventSourceNodeId);
-
-        int samplesToFill = nSamples - eventTime;
-
-        //	std::cout << "Received event from " << eventSourceNode << ", channel "
-        //	          << eventChannel << ", with ID " << eventId << ", copying to "
-         //            << channelForEventSource[eventSourceNode] << std::endl;
-        ////
-        int bufferIndex = (displayBufferIndex[channelForEventSource[eventSourceNodeId]] + eventTime - nSamples) % displayBuffer->getNumSamples();
-        
-        bufferIndex = bufferIndex >= 0 ? bufferIndex :
-        displayBuffer->getNumSamples() + bufferIndex;
-
-
-        if (eventId == 1)
-        {
-            ttlState[eventSourceNodeId] |= (1L << eventChannel);
-        }
-        else
-        {
-            ttlState[eventSourceNodeId] &= ~(1L << eventChannel);
-        }
-
-        if (samplesToFill + bufferIndex < displayBuffer->getNumSamples())
-        {
-
-            //std::cout << bufferIndex << " " << samplesToFill << " " << ttlState[eventSourceNode] << std::endl;
-
-            displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId],  // destChannel
-                                    bufferIndex,		// destStartSample
-                                    arrayOfOnes, 		// source
-                                    samplesToFill, 		// numSamples
-                                    float(ttlState[eventSourceNodeId]));   // gain
-        }
-        else
-        {
-
-            int block2Size = (samplesToFill + bufferIndex) % displayBuffer->getNumSamples();
-            int block1Size = samplesToFill - block2Size;
-
-            //std::cout << "OVERFLOW." << std::endl;
-
-            //std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl;
-
-            displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId],  // destChannel
-                                    bufferIndex,		// destStartSample
-                                    arrayOfOnes, 		// source
-                                    block1Size, 		// numSamples
-                                    float(ttlState[eventSourceNodeId]));   // gain
-
-            //std::cout << 0 << " " << block2Size << " " << ttlState << std::endl;
-
-            displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId],  // destChannel
-                                    0,		                        // destStartSample
-                                    arrayOfOnes, 		// source
-                                    block2Size, 		// numSamples
-                                    float(ttlState[eventSourceNodeId]));   // gain
-
-
-        }
-
-
-        // 	std::cout << "ttlState: " << ttlState << std::endl;
-
-        // std::cout << "Received event from " << eventNodeId <<
-        //              " on channel " << eventChannel <<
-        //             " with value " << eventId <<
-        //             " at timestamp " << event.getTimeStamp() << std::endl;
-
-
-    }
-
-}
-
-void LfpDisplayNode::initializeEventChannels()
-{
-
-    for (int i = 0; i < eventSourceNodes.size(); i++)
-    {
-
-        int chan = channelForEventSource[eventSourceNodes[i]];
-        int index = displayBufferIndex[chan];
-
-        //std::cout << "Event source node " << i << ", channel " << chan << std::endl;
-
-        int samplesLeft = displayBuffer->getNumSamples() - index;
-
-        int nSamples = numSamples.at(eventSourceNodes[i]);
-
-
-
-        if (nSamples < samplesLeft)
-        {
-
-            //	std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl;
-            //
-            displayBuffer->copyFrom(chan,  // destChannel
-                                    index,		// destStartSample
-                                    arrayOfOnes, 		// source
-                                    nSamples, 		// numSamples
-                                    float(ttlState[eventSourceNodes[i]]));   // gain
-
-            displayBufferIndex.set(chan, index + nSamples);
-        }
-        else
-        {
-
-            int extraSamples = nSamples - samplesLeft;
-
-            // std::cout << "OVERFLOW." << std::endl;
-            // std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl;
-
-            displayBuffer->copyFrom(chan,    // destChannel
-                                    index,		// destStartSample
-                                    arrayOfOnes, 		// source
-                                    samplesLeft, 		// numSamples
-                                    float(ttlState[eventSourceNodes[i]]));   // gain
-            // std::cout << 0 << " " << block2Size << " " << ttlState << std::endl;
-
-            displayBuffer->copyFrom(chan,  // destChannel
-                                    0,		// destStartSample
-                                    arrayOfOnes, 		// source
-                                    extraSamples, 		// numSamples
-                                    float(ttlState[eventSourceNodes[i]]));   // gain
-
-            displayBufferIndex.set(chan, extraSamples);
-        }
-    }   
-}
-
-void LfpDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events)
-{
-    // 1. place any new samples into the displayBuffer
-    //std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;
-
-    initializeEventChannels();
-
-    checkForEvents(events); // see if we got any TTL events
-
-	ScopedLock displayLock(displayMutex);
-
-    for (int chan = 0; chan < buffer.getNumChannels(); chan++)
-    {
-         int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex[chan];
-         int nSamples = getNumSamples(chan);
-
-        if (nSamples < samplesLeft)
-        {
-
-            displayBuffer->copyFrom(chan,  			// destChannel
-                                    displayBufferIndex[chan], // destStartSample
-                                    buffer, 			// source
-                                    chan, 				// source channel
-                                    0,					// source start sample
-                                    nSamples); 			// numSamples
-        
-            displayBufferIndex.set(chan, displayBufferIndex[chan] + nSamples);
-        }
-        else
-        {
-
-            int extraSamples = nSamples - samplesLeft;
-
-            displayBuffer->copyFrom(chan,  				// destChannel
-                                    displayBufferIndex[chan], // destStartSample
-                                        buffer, 			// source
-                                        chan, 				// source channel
-                                        0,					// source start sample
-                                        samplesLeft); 		// numSamples
-
-                displayBuffer->copyFrom(chan,
-                                        0,
-                                        buffer,
-                                        chan,
-                                        samplesLeft,
-                                        extraSamples);
-
-            displayBufferIndex.set(chan, extraSamples);
-        }
-    }
-
-}
-
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2013 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 "LfpDisplayNode.h"
+#include "LfpDisplayCanvas.h"
+#include <stdio.h>
+
+LfpDisplayNode::LfpDisplayNode()
+    : GenericProcessor("LFP Viewer"),
+      displayGain(1), bufferLength(5.0f),
+      abstractFifo(100)
+{
+    //std::cout << " LFPDisplayNodeConstructor" << std::endl;
+    displayBuffer = new AudioSampleBuffer(8, 100);
+
+    arrayOfOnes = new float[5000];
+
+    for (int n = 0; n < 5000; n++)
+    {
+        arrayOfOnes[n] = 1;
+    }
+
+}
+
+LfpDisplayNode::~LfpDisplayNode()
+{
+
+}
+
+AudioProcessorEditor* LfpDisplayNode::createEditor()
+{
+
+    editor = new LfpDisplayEditor(this, true);
+    return editor;
+
+}
+
+void LfpDisplayNode::updateSettings()
+{
+    std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl;
+
+    channelForEventSource.clear();
+    eventSourceNodes.clear();
+    ttlState.clear();
+
+    for (int i = 0; i < eventChannels.size(); i++)
+    {
+        if (!eventSourceNodes.contains(eventChannels[i]->sourceNodeId) && eventChannels[i]->type == EVENT_CHANNEL)
+        {
+            eventSourceNodes.add(eventChannels[i]->sourceNodeId);
+
+        }
+    }\
+
+    numEventChannels = eventSourceNodes.size();
+
+    std::cout << "Found " << numEventChannels << " event channels." << std::endl;
+
+    for (int i = 0; i < eventSourceNodes.size(); i++)
+    {
+        std::cout << "Adding channel " << getNumInputs() + i << " for event source node " << eventSourceNodes[i] << std::endl;
+        channelForEventSource[eventSourceNodes[i]] = getNumInputs() + i;
+        ttlState[eventSourceNodes[i]] = 0;
+        Channel* eventChan = new Channel(this, getNumInputs() + i, EVENT_CHANNEL);
+        eventChan->sourceNodeId = eventSourceNodes[i];
+        channels.add(eventChan); // add a channel for event data for each source node
+    }
+
+    displayBufferIndex.clear();
+    displayBufferIndex.insertMultiple(0, 0, getNumInputs() + numEventChannels);
+
+}
+
+bool LfpDisplayNode::resizeBuffer()
+{
+    int nSamples = (int) getSampleRate()*bufferLength;
+    int nInputs = getNumInputs();
+
+    std::cout << "Resizing buffer. Samples: " << nSamples << ", Inputs: " << nInputs << std::endl;
+
+    if (nSamples > 0 && nInputs > 0)
+    {
+        abstractFifo.setTotalSize(nSamples);
+        displayBuffer->setSize(nInputs + numEventChannels, nSamples); // add extra channels for TTLs
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+
+}
+
+bool LfpDisplayNode::enable()
+{
+
+    if (resizeBuffer())
+    {
+        LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
+        editor->enable();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+
+}
+
+bool LfpDisplayNode::disable()
+{
+    LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
+    editor->disable();
+    return true;
+}
+
+void LfpDisplayNode::setParameter(int parameterIndex, float newValue)
+{
+    editor->updateParameterButtons(parameterIndex);
+    //Sets Parameter in parameters array for processor
+    Parameter* parameterPointer = parameters.getRawDataPointer();
+    parameterPointer = parameterPointer+parameterIndex;
+    parameterPointer->setValue(newValue, currentChannel);
+
+    //std::cout << "Saving Parameter from " << currentChannel << ", channel ";
+
+    LfpDisplayEditor* ed = (LfpDisplayEditor*) getEditor();
+    if (ed->canvas != 0)
+        ed->canvas->setParameter(parameterIndex, newValue);
+}
+
+void LfpDisplayNode::handleEvent(int eventType, MidiMessage& event, int sampleNum)
+{
+    if (eventType == TTL)
+    {
+        const uint8* dataptr = event.getRawData();
+
+        //int eventNodeId = *(dataptr+1);
+        int eventId = *(dataptr+2);
+        int eventChannel = *(dataptr+3);
+        int eventTime = event.getTimeStamp();
+
+        int eventSourceNodeId = *(dataptr+5);
+
+        int nSamples = numSamples.at(eventSourceNodeId);
+
+        int samplesToFill = nSamples - eventTime;
+
+        //	std::cout << "Received event from " << eventSourceNode << ", channel "
+        //	          << eventChannel << ", with ID " << eventId << ", copying to "
+         //            << channelForEventSource[eventSourceNode] << std::endl;
+        ////
+        int bufferIndex = (displayBufferIndex[channelForEventSource[eventSourceNodeId]] + eventTime - nSamples) % displayBuffer->getNumSamples();
+        
+        bufferIndex = bufferIndex >= 0 ? bufferIndex :
+        displayBuffer->getNumSamples() + bufferIndex;
+
+
+        if (eventId == 1)
+        {
+            ttlState[eventSourceNodeId] |= (1L << eventChannel);
+        }
+        else
+        {
+            ttlState[eventSourceNodeId] &= ~(1L << eventChannel);
+        }
+
+        if (samplesToFill + bufferIndex < displayBuffer->getNumSamples())
+        {
+
+            //std::cout << bufferIndex << " " << samplesToFill << " " << ttlState[eventSourceNode] << std::endl;
+
+            displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId],  // destChannel
+                                    bufferIndex,		// destStartSample
+                                    arrayOfOnes, 		// source
+                                    samplesToFill, 		// numSamples
+                                    float(ttlState[eventSourceNodeId]));   // gain
+        }
+        else
+        {
+
+            int block2Size = (samplesToFill + bufferIndex) % displayBuffer->getNumSamples();
+            int block1Size = samplesToFill - block2Size;
+
+            //std::cout << "OVERFLOW." << std::endl;
+
+            //std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl;
+
+            displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId],  // destChannel
+                                    bufferIndex,		// destStartSample
+                                    arrayOfOnes, 		// source
+                                    block1Size, 		// numSamples
+                                    float(ttlState[eventSourceNodeId]));   // gain
+
+            //std::cout << 0 << " " << block2Size << " " << ttlState << std::endl;
+
+            displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId],  // destChannel
+                                    0,		                        // destStartSample
+                                    arrayOfOnes, 		// source
+                                    block2Size, 		// numSamples
+                                    float(ttlState[eventSourceNodeId]));   // gain
+
+
+        }
+
+
+        // 	std::cout << "ttlState: " << ttlState << std::endl;
+
+        // std::cout << "Received event from " << eventNodeId <<
+        //              " on channel " << eventChannel <<
+        //             " with value " << eventId <<
+        //             " at timestamp " << event.getTimeStamp() << std::endl;
+
+
+    }
+
+}
+
+void LfpDisplayNode::initializeEventChannels()
+{
+
+    for (int i = 0; i < eventSourceNodes.size(); i++)
+    {
+
+        int chan = channelForEventSource[eventSourceNodes[i]];
+        int index = displayBufferIndex[chan];
+
+        //std::cout << "Event source node " << i << ", channel " << chan << std::endl;
+
+        int samplesLeft = displayBuffer->getNumSamples() - index;
+
+        int nSamples = numSamples.at(eventSourceNodes[i]);
+
+
+
+        if (nSamples < samplesLeft)
+        {
+
+            //	std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl;
+            //
+            displayBuffer->copyFrom(chan,  // destChannel
+                                    index,		// destStartSample
+                                    arrayOfOnes, 		// source
+                                    nSamples, 		// numSamples
+                                    float(ttlState[eventSourceNodes[i]]));   // gain
+
+            displayBufferIndex.set(chan, index + nSamples);
+        }
+        else
+        {
+
+            int extraSamples = nSamples - samplesLeft;
+
+            // std::cout << "OVERFLOW." << std::endl;
+            // std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl;
+
+            displayBuffer->copyFrom(chan,    // destChannel
+                                    index,		// destStartSample
+                                    arrayOfOnes, 		// source
+                                    samplesLeft, 		// numSamples
+                                    float(ttlState[eventSourceNodes[i]]));   // gain
+            // std::cout << 0 << " " << block2Size << " " << ttlState << std::endl;
+
+            displayBuffer->copyFrom(chan,  // destChannel
+                                    0,		// destStartSample
+                                    arrayOfOnes, 		// source
+                                    extraSamples, 		// numSamples
+                                    float(ttlState[eventSourceNodes[i]]));   // gain
+
+            displayBufferIndex.set(chan, extraSamples);
+        }
+    }   
+}
+
+void LfpDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events)
+{
+    // 1. place any new samples into the displayBuffer
+    //std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;
+
+    initializeEventChannels();
+
+    checkForEvents(events); // see if we got any TTL events
+
+	ScopedLock displayLock(displayMutex);
+
+    for (int chan = 0; chan < buffer.getNumChannels(); chan++)
+    {
+         int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex[chan];
+         int nSamples = getNumSamples(chan);
+
+        if (nSamples < samplesLeft)
+        {
+
+            displayBuffer->copyFrom(chan,  			// destChannel
+                                    displayBufferIndex[chan], // destStartSample
+                                    buffer, 			// source
+                                    chan, 				// source channel
+                                    0,					// source start sample
+                                    nSamples); 			// numSamples
+        
+            displayBufferIndex.set(chan, displayBufferIndex[chan] + nSamples);
+        }
+        else
+        {
+
+            int extraSamples = nSamples - samplesLeft;
+
+            displayBuffer->copyFrom(chan,  				// destChannel
+                                    displayBufferIndex[chan], // destStartSample
+                                        buffer, 			// source
+                                        chan, 				// source channel
+                                        0,					// source start sample
+                                        samplesLeft); 		// numSamples
+
+                displayBuffer->copyFrom(chan,
+                                        0,
+                                        buffer,
+                                        chan,
+                                        samplesLeft,
+                                        extraSamples);
+
+            displayBufferIndex.set(chan, extraSamples);
+        }
+    }
+
+}
+
diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayNode.h b/Source/Plugins/LfpDisplayNode/LfpDisplayNode.h
old mode 100755
new mode 100644
similarity index 92%
rename from Source/Processors/LfpDisplayNode/LfpDisplayNode.h
rename to Source/Plugins/LfpDisplayNode/LfpDisplayNode.h
index 18426bb7f2e38ece3905652fdd619898ee5504a5..16e7148064d75a229d290d6caf07b7103794ff16
--- a/Source/Processors/LfpDisplayNode/LfpDisplayNode.h
+++ b/Source/Plugins/LfpDisplayNode/LfpDisplayNode.h
@@ -1,116 +1,116 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2013 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 __LFPDISPLAYNODE_H_D969A379__
-#define __LFPDISPLAYNODE_H_D969A379__
-
-#include "../../../JuceLibraryCode/JuceHeader.h"
-#include "LfpDisplayEditor.h"
-#include "../Editors/VisualizerEditor.h"
-#include "../GenericProcessor/GenericProcessor.h"
-
-class DataViewport;
-
-/**
-
-  Holds data in a displayBuffer to be used by the LfpDisplayCanvas
-  for rendering continuous data streams.
-
-  @see GenericProcessor, LfpDisplayEditor, LfpDisplayCanvas
-
-*/
-
-class LfpDisplayNode :  public GenericProcessor
-
-{
-public:
-
-    LfpDisplayNode();
-    ~LfpDisplayNode();
-
-    AudioProcessorEditor* createEditor();
-
-    bool isSink()
-    {
-        return true;
-    }
-
-    void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
-
-    void setParameter(int, float);
-
-    void updateSettings();
-
-    bool enable();
-    bool disable();
-
-    void handleEvent(int, MidiMessage&, int);
-
-    AudioSampleBuffer* getDisplayBufferAddress()
-    {
-        return displayBuffer;
-    }
-    int getDisplayBufferIndex(int chan)
-    {
-        return displayBufferIndex[chan];
-    }
-
-	CriticalSection* getMutex()
-	{
-		return &displayMutex;
-	}
-
-private:
-
-    void initializeEventChannels();
-
-    ScopedPointer<AudioSampleBuffer> displayBuffer;
-
-    Array<int> displayBufferIndex;
-    Array<int> eventSourceNodes;
-    std::map<int, int> channelForEventSource;
-
-    int numEventChannels;
-
-    float displayGain; //
-    float bufferLength; // s
-
-    AbstractFifo abstractFifo;
-
-    int64 bufferTimestamp;
-    std::map<int, int> ttlState;
-    float* arrayOfOnes;
-    int totalSamples;
-
-    bool resizeBuffer();
-
-	CriticalSection displayMutex;
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayNode);
-
-};
-
-
-
-
-#endif  // __LFPDISPLAYNODE_H_D969A379__
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2013 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 __LFPDISPLAYNODE_H_D969A379__
+#define __LFPDISPLAYNODE_H_D969A379__
+
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "LfpDisplayEditor.h"
+#include "../../Processors/Editors/VisualizerEditor.h"
+#include "../../Processors/GenericProcessor/GenericProcessor.h"
+
+class DataViewport;
+
+/**
+
+  Holds data in a displayBuffer to be used by the LfpDisplayCanvas
+  for rendering continuous data streams.
+
+  @see GenericProcessor, LfpDisplayEditor, LfpDisplayCanvas
+
+*/
+
+class LfpDisplayNode :  public GenericProcessor
+
+{
+public:
+
+    LfpDisplayNode();
+    ~LfpDisplayNode();
+
+    AudioProcessorEditor* createEditor();
+
+    bool isSink()
+    {
+        return true;
+    }
+
+    void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
+
+    void setParameter(int, float);
+
+    void updateSettings();
+
+    bool enable();
+    bool disable();
+
+    void handleEvent(int, MidiMessage&, int);
+
+    AudioSampleBuffer* getDisplayBufferAddress()
+    {
+        return displayBuffer;
+    }
+    int getDisplayBufferIndex(int chan)
+    {
+        return displayBufferIndex[chan];
+    }
+
+	CriticalSection* getMutex()
+	{
+		return &displayMutex;
+	}
+
+private:
+
+    void initializeEventChannels();
+
+    ScopedPointer<AudioSampleBuffer> displayBuffer;
+
+    Array<int> displayBufferIndex;
+    Array<int> eventSourceNodes;
+    std::map<int, int> channelForEventSource;
+
+    int numEventChannels;
+
+    float displayGain; //
+    float bufferLength; // s
+
+    AbstractFifo abstractFifo;
+
+    int64 bufferTimestamp;
+    std::map<int, int> ttlState;
+    float* arrayOfOnes;
+    int totalSamples;
+
+    bool resizeBuffer();
+
+	CriticalSection displayMutex;
+
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayNode);
+
+};
+
+
+
+
+#endif  // __LFPDISPLAYNODE_H_D969A379__
diff --git a/Source/Processors/LfpDisplayNode/Makefile b/Source/Plugins/LfpDisplayNode/Makefile
old mode 100755
new mode 100644
similarity index 96%
rename from Source/Processors/LfpDisplayNode/Makefile
rename to Source/Plugins/LfpDisplayNode/Makefile
index 92d2433d4c85b020bb0d1b985f08c74a54ca9c09..451d473441bc516654177433d0b3d419d07af868
--- a/Source/Processors/LfpDisplayNode/Makefile
+++ b/Source/Plugins/LfpDisplayNode/Makefile
@@ -1,73 +1,73 @@
-TYPE = sinks
-
-ifeq ($(TARGET_ARCH),)
-  TARGET_ARCH := -march=native
-endif
-
-# (this disables dependency generation if multiple architectures are set)
-DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD)
-
-PLUGINDIR := /usr/local/lib/GUI
-BINDIR := build
-LIBDIR := build
-OBJDIR := build/intermediate/Debug
-OUTDIR := build
-CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I /usr/include -I /usr/include/freetype2 -I ../../../JuceLibraryCode
-CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -fPIC -O0
-CXXFLAGS += $(CFLAGS) 
-LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -shared -L/usr/X11R6/lib/ -lGL -lX11 -lXext -lXinerama -lasound -ldl -lfreetype -lpthread -lrt -lephys
-LDDEPS :=
-RESFLAGS :=  -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I /usr/include -I /usr/include/freetype2 -I ../../../JuceLibraryCode
-TARGET := LfpDisplayNode.so
-BLDCMD = $(CXX) -shared -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH)
-
-OBJECTS := \
-  $(OBJDIR)/LfpDisplayEditor.o \
-  $(OBJDIR)/LfpDisplayNode.o \
-  $(OBJDIR)/LfpDisplayCanvas.o \
-
-.PHONY: clean install
-
-$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES)
-	-@mkdir -p $(BINDIR)
-	-@mkdir -p $(LIBDIR)
-	-@mkdir -p $(OUTDIR)
-	@$(BLDCMD)
-
-install:
-	@echo ${TARGET} installed.
-	-@sudo mv $(BINDIR)/$(TARGET) $(PLUGINDIR)/$(TYPE)/$(TARGET)
-
-clean:
-	@echo Plugin cleaned.
-	-@rm -f $(OUTDIR)/$(TARGET)
-	-@rm -rf $(OBJDIR)/*
-	-@rm -rf $(OBJDIR)
-	-@rm -rf $(BINDIR)
-	-@sudo rm -rf $(PLUGINDIR)/$(TYPE)/$(TARGET)
-
-strip:
-	@echo Plugin stripped.
-	-@strip --strip-unneeded $(OUTDIR)/$(TARGET)
-
-$(OBJDIR)/LfpDisplayEditor.o: LfpDisplayEditor.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling LfpDisplayEditor.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/LfpDisplayCanvas.o: LfpDisplayCanvas.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling LfpDisplayCanvas.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/LfpDisplayNode.o: LfpDisplayNode.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling LfpDisplayNode.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
-$(OBJDIR)/VisualizerEditor.o: ../Editors/VisualizerEditor.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling VisualizerEditor.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
--include $(OBJECTS:%.o=%.d)
+TYPE = sinks
+
+ifeq ($(TARGET_ARCH),)
+  TARGET_ARCH := -march=native
+endif
+
+# (this disables dependency generation if multiple architectures are set)
+DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD)
+
+PLUGINDIR := /usr/local/lib/GUI
+BINDIR := build
+LIBDIR := build
+OBJDIR := build/intermediate/Debug
+OUTDIR := build
+CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I /usr/include -I /usr/include/freetype2 -I ../../../JuceLibraryCode
+CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -fPIC -O0
+CXXFLAGS += $(CFLAGS) 
+LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -shared -L/usr/X11R6/lib/ -lGL -lX11 -lXext -lXinerama -lasound -ldl -lfreetype -lpthread -lrt -lephys
+LDDEPS :=
+RESFLAGS :=  -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I /usr/include -I /usr/include/freetype2 -I ../../../JuceLibraryCode
+TARGET := LfpDisplayNode.so
+BLDCMD = $(CXX) -shared -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH)
+
+OBJECTS := \
+  $(OBJDIR)/LfpDisplayEditor.o \
+  $(OBJDIR)/LfpDisplayNode.o \
+  $(OBJDIR)/LfpDisplayCanvas.o \
+
+.PHONY: clean install
+
+$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES)
+	-@mkdir -p $(BINDIR)
+	-@mkdir -p $(LIBDIR)
+	-@mkdir -p $(OUTDIR)
+	@$(BLDCMD)
+
+install:
+	@echo ${TARGET} installed.
+	-@sudo mv $(BINDIR)/$(TARGET) $(PLUGINDIR)/$(TYPE)/$(TARGET)
+
+clean:
+	@echo Plugin cleaned.
+	-@rm -f $(OUTDIR)/$(TARGET)
+	-@rm -rf $(OBJDIR)/*
+	-@rm -rf $(OBJDIR)
+	-@rm -rf $(BINDIR)
+	-@sudo rm -rf $(PLUGINDIR)/$(TYPE)/$(TARGET)
+
+strip:
+	@echo Plugin stripped.
+	-@strip --strip-unneeded $(OUTDIR)/$(TARGET)
+
+$(OBJDIR)/LfpDisplayEditor.o: LfpDisplayEditor.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling LfpDisplayEditor.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/LfpDisplayCanvas.o: LfpDisplayCanvas.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling LfpDisplayCanvas.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/LfpDisplayNode.o: LfpDisplayNode.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling LfpDisplayNode.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/VisualizerEditor.o: ../Editors/VisualizerEditor.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling VisualizerEditor.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+-include $(OBJECTS:%.o=%.d)
diff --git a/Source/Processors/LfpDisplayNode/OpenEphysLib.cpp b/Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp
similarity index 80%
rename from Source/Processors/LfpDisplayNode/OpenEphysLib.cpp
rename to Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp
index 26fa29a8b3725f983ca42da420b64da20274d7bc..6c3e4460063afbe2a56389ffbf37c4d211aad261 100644
--- a/Source/Processors/LfpDisplayNode/OpenEphysLib.cpp
+++ b/Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp
@@ -21,7 +21,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 
-#include "../PluginManager/OpenEphysPlugin.h"
+#include "../../Processors/PluginManager/OpenEphysPlugin.h"
 #include "LfpDisplayNode.h"
 #include <string>
 #ifdef WIN32
@@ -43,11 +43,18 @@ extern "C" EXPORT void getLibInfo(Plugin::LibraryInfo* info)
 
 extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info)
 {
-	if (index < 0 || index >= NUM_PLUGINS) return -1;
-	info->type = Plugin::ProcessorPlugin;
-	strcpy(info->processor.name, "LFP viewer");
-	info->processor.type = Plugin::SinkProcessor;
-	info->processor.creator = &(Plugin::createProcessor<LfpDisplayNode>);
+	switch (index)
+	{
+	case 0:
+		info->type = Plugin::ProcessorPlugin;
+		strcpy(info->processor.name, "LFP viewer");
+		info->processor.type = Plugin::SinkProcessor;
+		info->processor.creator = &(Plugin::createProcessor<LfpDisplayNode>);
+		break;
+	default:
+		return -1;
+		break;
+	}
 	return 0;
 }
 
diff --git a/Source/Processors/DataThreads/Rhythm/OpenEphysLib.cpp b/Source/Plugins/RhythmNode/OpenEphysLib.cpp
similarity index 82%
rename from Source/Processors/DataThreads/Rhythm/OpenEphysLib.cpp
rename to Source/Plugins/RhythmNode/OpenEphysLib.cpp
index c5a44767e3e3454166dfc0732fc7bf8c02b76de3..1343247b7ead8f82c17c862d66aa9217df47098d 100644
--- a/Source/Processors/DataThreads/Rhythm/OpenEphysLib.cpp
+++ b/Source/Plugins/RhythmNode/OpenEphysLib.cpp
@@ -21,7 +21,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 
-#include "../../PluginManager/OpenEphysPlugin.h"
+#include "../../Processors/PluginManager/OpenEphysPlugin.h"
 #include "RHD2000Thread.h"
 #include <string>
 #ifdef WIN32
@@ -44,10 +44,17 @@ extern "C" EXPORT void getLibInfo(Plugin::LibraryInfo* info)
 
 extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info)
 {
-	if (index < 0 || index >= NUM_PLUGINS) return -1;
-	info->type = Plugin::DatathreadPlugin;
-	strcpy(info->dataThread.name, "Rhythm FPGA");
-	info->dataThread.creator = &(Plugin::createDataThread<RHD2000Thread>);
+	switch (index)
+	{
+	case 0:
+		info->type = Plugin::DatathreadPlugin;
+		strcpy(info->dataThread.name, "Rhythm FPGA");
+		info->dataThread.creator = &(Plugin::createDataThread<RHD2000Thread>);
+		break;
+	default:
+		return -1;
+		break;
+	}
 	return 0;
 }
 
diff --git a/Source/Processors/DataThreads/Rhythm/RHD2000Editor.cpp b/Source/Plugins/RhythmNode/RHD2000Editor.cpp
similarity index 99%
rename from Source/Processors/DataThreads/Rhythm/RHD2000Editor.cpp
rename to Source/Plugins/RhythmNode/RHD2000Editor.cpp
index 863bfeee0f76f3ac4fc73f8486a383b3a8f28ca7..df792ae0d982f17085bea6bd27996e4b01def36b 100644
--- a/Source/Processors/DataThreads/Rhythm/RHD2000Editor.cpp
+++ b/Source/Plugins/RhythmNode/RHD2000Editor.cpp
@@ -24,8 +24,8 @@
 #include "RHD2000Editor.h"
 #include <cmath>
 
-#include "../../Editors/ChannelSelector.h"
-#include "../../SourceNode/SourceNode.h"
+#include "../../Processors/Editors/ChannelSelector.h"
+#include "../../Processors/SourceNode/SourceNode.h"
 #include "RHD2000Thread.h"
 
 #ifdef WIN32
diff --git a/Source/Processors/DataThreads/Rhythm/RHD2000Editor.h b/Source/Plugins/RhythmNode/RHD2000Editor.h
similarity index 97%
rename from Source/Processors/DataThreads/Rhythm/RHD2000Editor.h
rename to Source/Plugins/RhythmNode/RHD2000Editor.h
index 2bab9802b735eb6e47d94a243a5e5700ab4dfb45..e860e23d259627798ebc703871c5685de31e2bff 100644
--- a/Source/Processors/DataThreads/Rhythm/RHD2000Editor.h
+++ b/Source/Plugins/RhythmNode/RHD2000Editor.h
@@ -24,11 +24,11 @@
 #ifndef __RHD2000EDITOR_H_2AD3C591__
 #define __RHD2000EDITOR_H_2AD3C591__
 
-#include "../../../../JuceLibraryCode/JuceHeader.h"
-#include "../../Editors/GenericEditor.h"
-#include "../../Editors/VisualizerEditor.h"
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "../../Processors/Editors/GenericEditor.h"
+#include "../../Processors/Editors/VisualizerEditor.h"
 
-#include "../../Editors/ElectrodeButtons.h" // for ElectrodeButton
+#include "../../Processors/Editors/ElectrodeButtons.h" // for ElectrodeButton
 
 class HeadstageOptionsInterface;
 class SampleRateInterface;
diff --git a/Source/Processors/DataThreads/Rhythm/RHD2000Thread.cpp b/Source/Plugins/RhythmNode/RHD2000Thread.cpp
similarity index 99%
rename from Source/Processors/DataThreads/Rhythm/RHD2000Thread.cpp
rename to Source/Plugins/RhythmNode/RHD2000Thread.cpp
index 426914867a2200b366c902790d2e0d55c374afe4..ba36113e8dace280ecd2693fc0767ebe53720938 100644
--- a/Source/Processors/DataThreads/Rhythm/RHD2000Thread.cpp
+++ b/Source/Plugins/RhythmNode/RHD2000Thread.cpp
@@ -23,7 +23,7 @@
 
 #include "RHD2000Thread.h"
 #include "RHD2000Editor.h"
-#include "../../SourceNode/SourceNode.h"
+#include "../../Processors/SourceNode/SourceNode.h"
 
 #if defined(_WIN32)
 #define okLIB_NAME "okFrontPanel.dll"
diff --git a/Source/Processors/DataThreads/Rhythm/RHD2000Thread.h b/Source/Plugins/RhythmNode/RHD2000Thread.h
similarity index 98%
rename from Source/Processors/DataThreads/Rhythm/RHD2000Thread.h
rename to Source/Plugins/RhythmNode/RHD2000Thread.h
index 4a9edfce0362e896693860f8d43dd65eff9d210f..9bab798ae05f369c4c264d681ed63f523ce09658 100644
--- a/Source/Processors/DataThreads/Rhythm/RHD2000Thread.h
+++ b/Source/Plugins/RhythmNode/RHD2000Thread.h
@@ -26,7 +26,7 @@
 #define __RHD2000THREAD_H_2C4CBD67__
 
 
-#include "../../../../JuceLibraryCode/JuceHeader.h"
+#include "../../../JuceLibraryCode/JuceHeader.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -36,8 +36,8 @@
 #include "rhythm-api/rhd2000datablock.h"
 #include "rhythm-api/okFrontPanelDLL.h"
 
-#include "../DataThread.h"
-#include "../../GenericProcessor/GenericProcessor.h"
+#include "../../Processors/DataThreads/DataThread.h"
+#include "../../Processors/GenericProcessor/GenericProcessor.h"
 
 #define MAX_NUM_DATA_STREAMS_USB2 8
 #define MAX_NUM_DATA_STREAMS_USB3 16
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/okFrontPanelDLL.cpp b/Source/Plugins/RhythmNode/rhythm-api/okFrontPanelDLL.cpp
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/okFrontPanelDLL.cpp
rename to Source/Plugins/RhythmNode/rhythm-api/okFrontPanelDLL.cpp
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/okFrontPanelDLL.h b/Source/Plugins/RhythmNode/rhythm-api/okFrontPanelDLL.h
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/okFrontPanelDLL.h
rename to Source/Plugins/RhythmNode/rhythm-api/okFrontPanelDLL.h
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000datablock.cpp b/Source/Plugins/RhythmNode/rhythm-api/rhd2000datablock.cpp
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000datablock.cpp
rename to Source/Plugins/RhythmNode/rhythm-api/rhd2000datablock.cpp
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000datablock.h b/Source/Plugins/RhythmNode/rhythm-api/rhd2000datablock.h
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000datablock.h
rename to Source/Plugins/RhythmNode/rhythm-api/rhd2000datablock.h
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000evalboard.cpp b/Source/Plugins/RhythmNode/rhythm-api/rhd2000evalboard.cpp
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000evalboard.cpp
rename to Source/Plugins/RhythmNode/rhythm-api/rhd2000evalboard.cpp
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000evalboard.h b/Source/Plugins/RhythmNode/rhythm-api/rhd2000evalboard.h
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000evalboard.h
rename to Source/Plugins/RhythmNode/rhythm-api/rhd2000evalboard.h
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000registers.cpp b/Source/Plugins/RhythmNode/rhythm-api/rhd2000registers.cpp
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000registers.cpp
rename to Source/Plugins/RhythmNode/rhythm-api/rhd2000registers.cpp
diff --git a/Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000registers.h b/Source/Plugins/RhythmNode/rhythm-api/rhd2000registers.h
similarity index 100%
rename from Source/Processors/DataThreads/Rhythm/rhythm-api/rhd2000registers.h
rename to Source/Plugins/RhythmNode/rhythm-api/rhd2000registers.h
diff --git a/Source/Processors/FileReader/FileReader.cpp b/Source/Processors/FileReader/FileReader.cpp
index 42a6052aff10d17b183cc892bd875b3b08465048..6bab0a934b6aa9eb90117dd8f2c1fb264214a63c 100644
--- a/Source/Processors/FileReader/FileReader.cpp
+++ b/Source/Processors/FileReader/FileReader.cpp
@@ -45,7 +45,7 @@ FileReader::FileReader()
 		extensions.addTokens(info.extensions, ";", "\"");
 		for (int j = 0; j < extensions.size(); j++)
 		{
-			supportedExtensions.set(extensions[j], i + 1);
+			supportedExtensions.set(extensions[j].toLowerCase(), i + 1);
 		}
 	}
 }
@@ -117,7 +117,7 @@ bool FileReader::setFile(String fullpath)
 {
     File file(fullpath);
 
-    String ext = file.getFileExtension();
+	String ext = file.getFileExtension().toLowerCase().substring(1);
 
 	int index = supportedExtensions[ext] - 1;
 
diff --git a/Source/Processors/PluginManager/PluginManager.cpp b/Source/Processors/PluginManager/PluginManager.cpp
index 6c68ad074fcfe96c2d9d5162a74be7e1a21e2126..f2b950f86ad9b9136d5cbd8f883a6088e13a939c 100644
--- a/Source/Processors/PluginManager/PluginManager.cpp
+++ b/Source/Processors/PluginManager/PluginManager.cpp
@@ -184,13 +184,13 @@ int PluginManager::loadPlugin(const String& pluginLoc) {
 		}
 		case Plugin::FileSourcePlugin:
 		{
-			break;
 			LoadedPluginInfo<Plugin::FileSourceInfo> info;
 			info.creator = pInfo.fileSource.creator;
 			strcpy(info.name, pInfo.fileSource.name);
 			strcpy(info.extensions, pInfo.fileSource.extensions);
 			info.libIndex = libArray.size();
 			fileSourcePlugins.add(info);
+			break;
 		}
 		}
 	}
diff --git a/open-ephys.jucer b/open-ephys.jucer
index 3232ba0e071b9b2d5a23ba9f61ed8dc2ab235411..ea198db0aa68dcf1aa9806e3913ed581baa3e969 100644
--- a/open-ephys.jucer
+++ b/open-ephys.jucer
@@ -68,30 +68,22 @@
         <MODULEPATH id="juce_audio_basics" path="JuceLibraryCode/modules"/>
       </MODULEPATHS>
     </LINUX_MAKE>
-    <VS2012 targetFolder="Builds/VisualStudio2012" libraryType="1" extraDefs="NOMINMAX&#10;ZEROMQ"
-            externalLibraries="setupapi.lib&#10;opengl32.lib&#10;glu32.lib&#10;hdf5.lib&#10;hdf5_cpp.lib&#10;libzmq-v120-mt-4_0_4.lib"
+    <VS2012 targetFolder="Builds/VisualStudio2012" libraryType="1" extraDefs="NOMINMAX&#10;"
+            externalLibraries="setupapi.lib&#10;opengl32.lib&#10;glu32.lib&#10;"
             toolset="v110">
       <CONFIGURATIONS>
         <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
                        isDebug="1" optimisation="1" targetName="open-ephys" binaryPath="Builds\VisualStudio2012\Debug\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x86&#10;../../Resources/windows-libs/ZeroMQ/lib_x86"
-                       postbuildCommand="copy &quot;..\..\Resources\DLLs\*.dll&quot; &quot;$(OutDir)&quot;"/>
+                       headerPath="" libraryPath="" postbuildCommand="copy &quot;..\..\Resources\DLLs\*.dll&quot; &quot;$(OutDir)&quot;"/>
         <CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
                        isDebug="0" optimisation="3" targetName="open-ephys" binaryPath="Builds\VisualStudio2012\Release\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x86&#10;../../Resources/windows-libs/ZeroMQ/lib_x86"
-                       postbuildCommand="copy &quot;..\..\Resources\DLLs\*.dll&quot; &quot;$(OutDir)&quot;"/>
+                       headerPath="" libraryPath="" postbuildCommand="copy &quot;..\..\Resources\DLLs\*.dll&quot; &quot;$(OutDir)&quot;"/>
         <CONFIGURATION name="Debug64" winWarningLevel="2" generateManifest="1" winArchitecture="x64"
                        isDebug="1" optimisation="1" targetName="open-ephys" binaryPath="Builds\VisualStudio2012\Debug64\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x64&#10;../../Resources/windows-libs/ZeroMQ/lib_x64"
-                       postbuildCommand="copy &quot;..\..\Resources\DLLs\Win64\*.dll&quot; &quot;$(OutDir)&quot;"/>
+                       headerPath="" libraryPath="" postbuildCommand="copy &quot;..\..\Resources\DLLs\Win64\*.dll&quot; &quot;$(OutDir)&quot;"/>
         <CONFIGURATION name="Release64" winWarningLevel="2" generateManifest="1" winArchitecture="x64"
                        isDebug="0" optimisation="3" targetName="open-ephys" binaryPath="Builds\VisualStudio2012\Release64\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x64&#10;../../Resources/windows-libs/ZeroMQ/lib_x64"
-                       postbuildCommand="copy &quot;..\..\Resources\DLLs\Win64\*.dll&quot; &quot;$(OutDir)&quot;"/>
+                       headerPath="" libraryPath="" postbuildCommand="copy &quot;..\..\Resources\DLLs\Win64\*.dll&quot; &quot;$(OutDir)&quot;"/>
       </CONFIGURATIONS>
       <MODULEPATHS>
         <MODULEPATH id="juce_video" path="JuceLibraryCode/modules"/>
@@ -111,32 +103,24 @@
         <MODULEPATH id="juce_audio_basics" path="JuceLibraryCode/modules"/>
       </MODULEPATHS>
     </VS2012>
-    <VS2013 targetFolder="Builds/VisualStudio2013" externalLibraries="setupapi.lib&#10;opengl32.lib&#10;glu32.lib&#10;hdf5.lib&#10;hdf5_cpp.lib&#10;libzmq-v120-mt-4_0_4.lib"
-            extraDefs="NOMINMAX&#10;ZEROMQ&#10;JUCE_API=__declspec(dllexport)">
+    <VS2013 targetFolder="Builds/VisualStudio2013" externalLibraries="setupapi.lib&#10;opengl32.lib&#10;glu32.lib&#10;"
+            extraDefs="NOMINMAX&#10;JUCE_API=__declspec(dllexport)">
       <CONFIGURATIONS>
         <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
                        isDebug="1" optimisation="1" targetName="open-ephys" binaryPath="Builds\VisualStudio2013\Debug\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x86&#10;../../Resources/windows-libs/ZeroMQ/lib_x86"
-                       wholeProgramOptimisation="1" postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013\*.dll&quot; &quot;$(OutDir)&quot;"
+                       headerPath="" libraryPath="" wholeProgramOptimisation="1" postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013\*.dll&quot; &quot;$(OutDir)&quot;"
                        fastMath="1" useRuntimeLibDLL="1"/>
         <CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
                        isDebug="0" optimisation="3" targetName="open-ephys" binaryPath="Builds\VisualStudio2013\Release\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x86&#10;../../Resources/windows-libs/ZeroMQ/lib_x86"
-                       postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013\*.dll&quot; &quot;$(OutDir)&quot;"
+                       headerPath="" libraryPath="" postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013\*.dll&quot; &quot;$(OutDir)&quot;"
                        fastMath="1" useRuntimeLibDLL="1"/>
         <CONFIGURATION name="Debug64" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
                        isDebug="1" optimisation="1" targetName="open-ephys" binaryPath="Builds\VisualStudio2013\x64\Debug64\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x64&#10;../../Resources/windows-libs/ZeroMQ/lib_x64"
-                       wholeProgramOptimisation="1" postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013-x64\*.dll&quot; &quot;$(OutDir)&quot;"
+                       headerPath="" libraryPath="" wholeProgramOptimisation="1" postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013-x64\*.dll&quot; &quot;$(OutDir)&quot;"
                        fastMath="1" useRuntimeLibDLL="1"/>
         <CONFIGURATION name="Release64" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
                        isDebug="0" optimisation="3" targetName="open-ephys" binaryPath="Builds\VisualStudio2013\x64\Release64\bin"
-                       headerPath="../../Resources/windows-libs/HDF5/include&#10;../../Resources/windows-libs/ZeroMQ/include"
-                       libraryPath="../../Resources/windows-libs/HDF5/lib/x64&#10;../../Resources/windows-libs/ZeroMQ/lib_x64"
-                       postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013-x64\*.dll&quot; &quot;$(OutDir)&quot;"
+                       headerPath="" libraryPath="" postbuildCommand="copy /Y &quot;..\..\Resources\DLLs\VS2013-x64\*.dll&quot; &quot;$(OutDir)&quot;"
                        fastMath="1" useRuntimeLibDLL="1"/>
       </CONFIGURATIONS>
       <MODULEPATHS>
@@ -295,15 +279,6 @@
               file="Source/Audio/AudioComponent.h"/>
       </GROUP>
       <GROUP id="yQmqZWk" name="Processors">
-        <GROUP id="{6FA57F74-56F2-BB55-177E-B0E8FA54217F}" name="NetworkEvents">
-          <FILE id="C2QHS4" name="NetworkEventsEditor.cpp" compile="1" resource="0"
-                file="Source/Processors/NetworkEvents/NetworkEventsEditor.cpp"/>
-          <FILE id="qM68wu" name="NetworkEventsEditor.h" compile="0" resource="0"
-                file="Source/Processors/NetworkEvents/NetworkEventsEditor.h"/>
-          <FILE id="cKkI7r" name="NetworkEvents.cpp" compile="1" resource="0"
-                file="Source/Processors/NetworkEvents/NetworkEvents.cpp"/>
-          <FILE id="xYFMhh" name="NetworkEvents.h" compile="0" resource="0" file="Source/Processors/NetworkEvents/NetworkEvents.h"/>
-        </GROUP>
         <GROUP id="{AA47A836-2CD5-F803-C043-23BBBCFDA0CF}" name="ProcessorManager">
           <FILE id="KVCpqW" name="ProcessorManager.cpp" compile="1" resource="0"
                 file="Source/Processors/ProcessorManager/ProcessorManager.cpp"/>
@@ -398,10 +373,6 @@
                 file="Source/Processors/Editors/VisualizerEditor.h"/>
         </GROUP>
         <GROUP id="{27CF9A8D-7C31-9AA9-6DCA-6C719E127923}" name="FileReader">
-          <FILE id="i8d55i" name="KwikFileSource.cpp" compile="1" resource="0"
-                file="Source/Processors/FileReader/KwikFileSource.cpp"/>
-          <FILE id="MXFbiF" name="KwikFileSource.h" compile="1" resource="0"
-                file="Source/Processors/FileReader/KwikFileSource.h"/>
           <FILE id="O6lxmJ" name="FileSource.cpp" compile="1" resource="0" file="Source/Processors/FileReader/FileSource.cpp"/>
           <FILE id="CHKZ6y" name="FileSource.h" compile="1" resource="0" file="Source/Processors/FileReader/FileSource.h"/>
           <FILE id="Pg9JfX" name="FileReader.cpp" compile="1" resource="0" file="Source/Processors/FileReader/FileReader.cpp"/>
@@ -462,22 +433,6 @@
           <FILE id="ccpPpJ" name="RecordNode.cpp" compile="1" resource="0" file="Source/Processors/RecordNode/RecordNode.cpp"/>
           <FILE id="R9n30e" name="RecordNode.h" compile="1" resource="0" file="Source/Processors/RecordNode/RecordNode.h"/>
         </GROUP>
-        <GROUP id="{273A4CD9-60CE-A6A3-13E9-8BCAF573E024}" name="PSTH">
-          <FILE id="Y6TRvD" name="PeriStimulusTimeHistogramEditor.cpp" compile="1"
-                resource="0" file="Source/Processors/PSTH/PeriStimulusTimeHistogramEditor.cpp"/>
-          <FILE id="Z4mUYg" name="PeriStimulusTimeHistogramEditor.h" compile="1"
-                resource="0" file="Source/Processors/PSTH/PeriStimulusTimeHistogramEditor.h"/>
-          <FILE id="QpvGnH" name="PeriStimulusTimeHistogramNode.cpp" compile="1"
-                resource="0" file="Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp"/>
-          <FILE id="zptezx" name="PeriStimulusTimeHistogramNode.h" compile="1"
-                resource="0" file="Source/Processors/PSTH/PeriStimulusTimeHistogramNode.h"/>
-          <FILE id="t5D2ke" name="tictoc.cpp" compile="1" resource="0" file="Source/Processors/PSTH/tictoc.cpp"/>
-          <FILE id="Jshr7Y" name="tictoc.h" compile="1" resource="0" file="Source/Processors/PSTH/tictoc.h"/>
-          <FILE id="hcemDS" name="TrialCircularBuffer.cpp" compile="1" resource="0"
-                file="Source/Processors/PSTH/TrialCircularBuffer.cpp"/>
-          <FILE id="fDpocU" name="TrialCircularBuffer.h" compile="1" resource="0"
-                file="Source/Processors/PSTH/TrialCircularBuffer.h"/>
-        </GROUP>
         <GROUP id="{58E5BDC1-3523-0E4D-2402-72726098BA07}" name="SourceNode">
           <FILE id="bcB5hN" name="SourceNode.cpp" compile="1" resource="0" file="Source/Processors/SourceNode/SourceNode.cpp"/>
           <FILE id="Dyas33" name="SourceNode.h" compile="1" resource="0" file="Source/Processors/SourceNode/SourceNode.h"/>
@@ -486,36 +441,6 @@
           <FILE id="EWFh9x" name="SourceNodeEditor.h" compile="1" resource="0"
                 file="Source/Processors/SourceNode/SourceNodeEditor.h"/>
         </GROUP>
-        <GROUP id="{3C98FCA3-673A-3E34-ABC6-D506EF05DDD4}" name="SpikeDisplayNode">
-          <FILE id="Ak6yJU" name="SpikeDisplayCanvas.cpp" compile="1" resource="0"
-                file="Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp"/>
-          <FILE id="Ivm1WE" name="SpikeDisplayCanvas.h" compile="1" resource="0"
-                file="Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.h"/>
-          <FILE id="tzcDUJ" name="SpikeDisplayEditor.cpp" compile="1" resource="0"
-                file="Source/Processors/SpikeDisplayNode/SpikeDisplayEditor.cpp"/>
-          <FILE id="qpnGQ2" name="SpikeDisplayEditor.h" compile="1" resource="0"
-                file="Source/Processors/SpikeDisplayNode/SpikeDisplayEditor.h"/>
-          <FILE id="Osx5Vs" name="SpikeDisplayNode.cpp" compile="1" resource="0"
-                file="Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp"/>
-          <FILE id="EYFdq6" name="SpikeDisplayNode.h" compile="1" resource="0"
-                file="Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h"/>
-        </GROUP>
-        <GROUP id="{B65E315B-E451-52BB-C46B-DFC8CFE52512}" name="SpikeSorter">
-          <FILE id="IDfGJU" name="SpikeSortBoxes.cpp" compile="1" resource="0"
-                file="Source/Processors/SpikeSorter/SpikeSortBoxes.cpp"/>
-          <FILE id="oKqHU5" name="SpikeSortBoxes.h" compile="1" resource="0"
-                file="Source/Processors/SpikeSorter/SpikeSortBoxes.h"/>
-          <FILE id="ZvsSnb" name="SpikeSorter.cpp" compile="1" resource="0" file="Source/Processors/SpikeSorter/SpikeSorter.cpp"/>
-          <FILE id="iWFZ8N" name="SpikeSorter.h" compile="1" resource="0" file="Source/Processors/SpikeSorter/SpikeSorter.h"/>
-          <FILE id="AAjUyt" name="SpikeSorterCanvas.cpp" compile="1" resource="0"
-                file="Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp"/>
-          <FILE id="vSwtHQ" name="SpikeSorterCanvas.h" compile="1" resource="0"
-                file="Source/Processors/SpikeSorter/SpikeSorterCanvas.h"/>
-          <FILE id="eRXHEt" name="SpikeSorterEditor.cpp" compile="1" resource="0"
-                file="Source/Processors/SpikeSorter/SpikeSorterEditor.cpp"/>
-          <FILE id="seDqmg" name="SpikeSorterEditor.h" compile="1" resource="0"
-                file="Source/Processors/SpikeSorter/SpikeSorterEditor.h"/>
-        </GROUP>
         <GROUP id="{393F8FA9-FA27-4F2D-8252-9AB2CAA871DA}" name="Splitter">
           <FILE id="xbkXa2" name="Splitter.cpp" compile="1" resource="0" file="Source/Processors/Splitter/Splitter.cpp"/>
           <FILE id="kFiAO3" name="Splitter.h" compile="1" resource="0" file="Source/Processors/Splitter/Splitter.h"/>