Index: CLAM/src/Processing/Controls/ControlTrace.cxx
===================================================================
--- CLAM/src/Processing/Controls/ControlTrace.cxx	(revision 0)
+++ CLAM/src/Processing/Controls/ControlTrace.cxx	(revision 0)
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
+ *                         UNIVERSITAT POMPEU FABRA
+ * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch
+ *
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "ControlTrace.hxx"
+#include "Factory.hxx"
+#include "XMLAdapter.hxx"
+#include "XMLStorage.hxx"
+#include "XMLIterableAdapter.hxx"
+#include "XMLAdapter.hxx"
+#include "XmlStorageErr.hxx"
+#include <sstream>
+
+namespace CLAM
+{
+
+ControlTraceEvent::ControlTraceEvent(const ControlTraceEvent &obj)
+	: mValues(obj.mValues)
+{
+}
+ControlTraceEvent::ControlTraceEvent(const InControlArray &inputs)
+{
+	mValues.resize(inputs.Size());
+	for (int i = 0; i < inputs.Size(); i++)
+		mValues[i] = inputs[i].GetLastValue();
+}
+
+void ControlTraceEvent::UpdateControls(OutControlArray &outputs) const
+{
+	for (int i = 0; i < outputs.Size(); i++)
+		outputs[i].SendControl(mValues[i]);
+}
+
+void ControlTraceEvent::LoadFrom( Storage& storage )
+{
+	XMLIterableAdapter<ValueArray> adapter(mValues, "value", "values", true);
+	storage.Load(adapter);
+}
+
+void ControlTraceEvent::StoreOn( Storage& storage ) const
+{
+	XMLIterableAdapter<ValueArray> adapter(mValues, "value", "values", true);
+	storage.Store(adapter);
+}
+
+const ControlTraceEvent& ControlTraceEvent::operator=(const ControlTraceEvent& obj)
+{
+	mValues = obj.mValues;
+	return *this;
+}
+
+/* ================================================================== */
+
+ControlTraceData::ControlTraceData(const ControlTraceData &obj)
+	: mEvents(obj.mEvents)
+{
+}
+
+void ControlTraceData::LoadFrom( Storage& storage )
+{
+	XMLIterableAdapter<EventList> adapter(mEvents, "event", "events", true);
+	storage.Load(adapter);
+}
+
+void ControlTraceData::StoreOn( Storage& storage ) const
+{
+	XMLIterableAdapter<EventList> adapter(mEvents, "event", "events", true);
+	storage.Store(adapter);
+}
+
+/* ================================================================== */
+
+ControlTraceFile::ControlTraceFile( const ControlTraceFile& obj )
+	: ConfigurableFile(obj)
+{
+}
+
+const ControlTraceFile& ControlTraceFile::operator=( const ControlTraceFile& obj )
+{
+	this->ConfigurableFile::operator=(obj);
+	return *this;
+}
+
+ControlTraceFile::~ControlTraceFile()
+{
+}
+
+const FileFormatFilterList &ControlTraceFile::GetFormatFilterList() const
+{
+	static FileFormatFilterList traceFormatFilterList;
+	if (traceFormatFilterList.size())
+		return traceFormatFilterList;
+	FileFormatFilter filter("CLAM Control Traces (v0)", "*.clamtrace");
+	traceFormatFilterList.push_back(filter);
+	return traceFormatFilterList;
+}
+
+
+void ControlTraceFileSource::LocationUpdated()
+{
+	// TODO: implement me
+}
+void ControlTraceFileSource::LoadTrace(ControlTraceData &data) const
+{
+	XMLStorage::Restore(data, GetLocation().c_str());
+}
+
+
+void ControlTraceFileTarget::LocationUpdated()
+{
+	// TODO: implement me
+}
+void ControlTraceFileTarget::SaveTrace(const ControlTraceData &data) const
+{
+	XMLStorage::Dump(data, "trace", GetLocation().c_str());
+}
+
+/* ================================================================= */
+
+void ControlTraceWriterConfig::DefaultInit()
+{
+	AddAll();
+	UpdateData();
+	SetNumberOfInputs(1.);
+}
+
+ControlTraceWriter::ControlTraceWriter()
+{
+	Configure(mConfig);
+}
+
+ControlTraceWriter::ControlTraceWriter( const ProcessingConfig& cfg )
+{
+	Configure( cfg );
+}
+
+ControlTraceWriter::~ControlTraceWriter()
+{
+	RemoveOldControls();
+}
+
+bool ControlTraceWriter::ConcreteConfigure( const ProcessingConfig& cfgObj )
+{
+	RemoveOldControls();
+	CopyAsConcreteConfig( mConfig, cfgObj );
+	if ( !mConfig.HasTraceFile() )
+	{
+		AddConfigErrorMessage("No 'trace file' was specified in the configuration!");
+		return false;
+	}
+
+	ControlTraceFileTarget &file = mConfig.GetTraceFile();
+	if ( file.GetLocation() == "" )
+	{
+		AddConfigErrorMessage("No trace file selected");
+		return false;
+	}
+
+	if (!mConfig.HasNumberOfInputs() || mConfig.GetNumberOfInputs() < 1.)
+	{
+		AddConfigErrorMessage("The number of inputs has not been configured.");
+		return false;
+	}
+
+	mInputs.Resize(int(mConfig.GetNumberOfInputs()), "Inputs", this);
+	return true;
+}
+
+bool ControlTraceWriter::ConcreteStop()
+{
+	mConfig.GetTraceFile().SaveTrace(mTrace);
+	mTrace.Clear();
+	return true;
+}
+
+bool ControlTraceWriter::Do()
+{
+	mTrace.Append(ControlTraceEvent(mInputs));
+	return true;
+}
+
+
+void ControlTraceWriter::RemoveOldControls()
+{
+	mInputs.Clear();
+	GetInControls().Clear();
+}
+
+/* ================================================================= */
+
+void ControlTraceReaderConfig::DefaultInit()
+{
+	AddAll();
+	UpdateData();
+}
+
+ControlTraceReader::ControlTraceReader()
+{
+	Configure(mConfig);
+}
+
+ControlTraceReader::ControlTraceReader( const ProcessingConfig& cfg )
+{
+	Configure( cfg );
+}
+
+ControlTraceReader::~ControlTraceReader()
+{
+	RemoveOldControls();
+}
+
+bool ControlTraceReader::ConcreteConfigure( const ProcessingConfig& cfgObj )
+{
+	RemoveOldControls();
+	CopyAsConcreteConfig( mConfig, cfgObj );
+	if ( !mConfig.HasTraceFile() )
+	{
+		AddConfigErrorMessage("No 'trace file' was specified in the configuration!");
+		return false;
+	}
+
+	ControlTraceFileSource &file = mConfig.GetTraceFile();
+	if ( file.GetLocation() == "" )
+	{
+		AddConfigErrorMessage("No trace file selected");
+		return false;
+	}
+
+	try {
+		mConfig.GetTraceFile().LoadTrace(mTrace);
+	}
+	catch (XmlStorageErr &e)
+	{
+		AddConfigErrorMessage(e.what());
+		return false;
+	}
+
+	if (mTrace.GetNumberOfControls() < 1)
+	{
+		AddConfigErrorMessage("The specified file does not contain any control events.");
+		return false;
+	}
+
+	mOutputs.Resize(mTrace.GetNumberOfControls(), "Outputs", this);
+	return true;
+}
+
+bool ControlTraceReader::ConcreteStart()
+{
+	mIterator = mTrace.Begin();
+	return true;
+}
+
+bool ControlTraceReader::Do()
+{
+	if (mIterator == mTrace.End())
+		return false;
+
+	const ControlTraceEvent &event = *mIterator++;
+	event.UpdateControls(mOutputs);
+	return true;
+}
+
+void ControlTraceReader::RemoveOldControls()
+{
+	mOutputs.Clear();
+	GetOutControls().Clear();
+}
+
+/* ================================================================== */
+
+namespace detail
+{
+typedef CLAM::Factory<CLAM::Processing> ProcessingFactory;
+static ProcessingFactory::Registrator<CLAM::ControlTraceReader>
+		regtControlTraceReader("ControlTraceReader");
+static ProcessingFactory::Registrator<CLAM::ControlTraceWriter>
+		regtControlTraceWriter("ControlTraceWriter");
+}
+
+
+} // CLAM namespace
+
Index: CLAM/src/Processing/Controls/ControlTrace.hxx
===================================================================
--- CLAM/src/Processing/Controls/ControlTrace.hxx	(revision 0)
+++ CLAM/src/Processing/Controls/ControlTrace.hxx	(revision 0)
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
+ *                         UNIVERSITAT POMPEU FABRA
+ * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch
+ *
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef CONTROL_TRACE_HXX
+#define CONTROL_TRACE_HXX
+
+#include <CLAM/Processing.hxx>
+#include <CLAM/ProcessingConfig.hxx>
+#include <CLAM/InControlArray.hxx>
+#include <CLAM/OutControlArray.hxx>
+#include <CLAM/ConfigurableFile.hxx>
+#include <vector>
+
+class Network;
+
+struct fann;
+
+namespace CLAM
+{
+
+class ControlTraceEvent : public Component {
+public:
+	typedef std::vector<TControlData> ValueArray;
+
+	ControlTraceEvent() { }
+	ControlTraceEvent(const InControlArray &inputs);
+	ControlTraceEvent(const ControlTraceEvent &event);
+	const ControlTraceEvent& operator=( const ControlTraceEvent& );
+	virtual ~ControlTraceEvent() { }
+
+	const char *GetClassName() const { return "ControlTraceEvent"; }
+
+	void LoadFrom( Storage& storage);
+	void StoreOn( Storage& storage ) const;
+
+	size_t Size() const { return mValues.size(); }
+
+	void UpdateControls(OutControlArray &array) const;
+
+private:
+	ValueArray mValues;
+};
+
+
+class ControlTraceData : public Component {
+public:
+	typedef std::list<ControlTraceEvent> EventList;
+	virtual ~ControlTraceData() { }
+
+	ControlTraceData() { }
+	ControlTraceData(const ControlTraceData &obj);
+
+	const char *GetClassName() const { return "ControlTraceData"; }
+
+	void LoadFrom( Storage& storage);
+	void StoreOn( Storage& storage ) const;
+
+	size_t GetNumberOfControls() const { return mEvents.front().Size(); }
+
+	void Append(const ControlTraceEvent &data) { mEvents.push_back(data); }
+
+	EventList::iterator Begin() { return mEvents.begin(); }
+	EventList::iterator End() { return mEvents.end(); }
+
+	void Clear() { mEvents.clear(); }
+
+protected:
+	EventList mEvents;
+};
+
+
+class ControlTraceFile : public ConfigurableFile
+{
+public:
+	ControlTraceFile() { }
+	ControlTraceFile( const ControlTraceFile& );
+	const ControlTraceFile& operator=( const ControlTraceFile& );
+	virtual ~ControlTraceFile();
+
+	const char* GetClassName() const { return "ControlTraceFile"; }
+	const char* GetGroupName() const { return "control trace"; }
+	const FileFormatFilterList &GetFormatFilterList() const;
+};
+
+class ControlTraceFileSource : public ControlTraceFile
+{
+public:
+	ControlTraceFileSource() { }
+	void LoadTrace(ControlTraceData &trace) const;
+	bool GetWriteMode() { return false; }
+	const char* GetClassName() const { return "ControlTraceFileSource"; }
+protected:
+	void LocationUpdated();
+};
+
+class ControlTraceFileTarget : public ControlTraceFile
+{
+public:
+	ControlTraceFileTarget() { }
+	void SaveTrace(const ControlTraceData &trace) const;
+	bool GetWriteMode() { return true; }
+	const char* GetClassName() const { return "ControlTraceFileTarget"; }
+protected:
+	void LocationUpdated();
+};
+
+
+class ControlTraceReaderConfig  : public ProcessingConfig {
+	DYNAMIC_TYPE_USING_INTERFACE
+	( ControlTraceReaderConfig, 1, ProcessingConfig );
+
+	DYN_ATTRIBUTE( 0, public, ControlTraceFileSource, TraceFile );
+
+protected:
+	void DefaultInit();
+};
+
+class ControlTraceReader : public Processing
+{
+public:
+	ControlTraceReader();
+	ControlTraceReader( const ProcessingConfig& cfg );
+	virtual ~ControlTraceReader();
+
+	const char* GetClassName() const { return "ControlTraceReader"; }
+	const ProcessingConfig& GetConfig() const { return mConfig; }
+
+	bool Do();
+
+protected: // methods
+	bool ConcreteConfigure( const ProcessingConfig& cfgObject );
+	bool ConcreteStart();
+	void RemoveOldControls();
+	
+protected: // attributes
+	ControlTraceReaderConfig mConfig;
+	ControlTraceData mTrace;
+	ControlTraceData::EventList::iterator mIterator;
+	OutControlArray mOutputs;
+};
+
+class ControlTraceWriterConfig  : public ProcessingConfig {
+	DYNAMIC_TYPE_USING_INTERFACE
+	( ControlTraceWriterConfig, 2, ProcessingConfig );
+
+	DYN_ATTRIBUTE( 0, public, ControlTraceFileTarget, TraceFile );
+	DYN_ATTRIBUTE( 1, public, TData, NumberOfInputs );
+
+protected:
+	void DefaultInit();
+};
+
+class ControlTraceWriter : public Processing
+{
+public:
+	ControlTraceWriter();
+	ControlTraceWriter( const ProcessingConfig& cfg );
+	virtual ~ControlTraceWriter();
+
+	const char* GetClassName() const { return "ControlTraceWriter"; }
+	const ProcessingConfig& GetConfig() const { return mConfig; }
+
+	bool Do();
+
+protected: // methods
+	bool ConcreteConfigure( const ProcessingConfig& cfgObject );
+	bool ConcreteStop();
+	void RemoveOldControls();
+	
+protected: // attributes
+	ControlTraceWriterConfig mConfig;
+	ControlTraceData mTrace;
+	InControlArray mInputs;
+};
+
+
+
+} // CLAM namespace
+
+#endif
Index: NetworkEditor/src/ProcessingTree.cxx
===================================================================
--- NetworkEditor/src/ProcessingTree.cxx	(revision 9990)
+++ NetworkEditor/src/ProcessingTree.cxx	(working copy)
@@ -67,6 +67,8 @@
 	"ControlSource",
 	"ControlSink",
 	"ControlPrinter",
+	"ControlTraceReader",
+	"ControlTraceWriter",
 	"ControlScaler", 
 	"AutoPanner",
 	"FlagControl",
Index: NetworkEditor/src/ProcessingBox.cxx
===================================================================
--- NetworkEditor/src/ProcessingBox.cxx	(revision 9990)
+++ NetworkEditor/src/ProcessingBox.cxx	(working copy)
@@ -85,7 +85,7 @@
 	if (className=="ControlSurface")
 		return new ControlSurfaceWidget(processing);
 
-	if (className=="ControlPrinter")
+	if (className=="ControlPrinter" || className=="ControlTraceWriter")
 		return new ControlPrinterWidget(processing);
 
 	if (className=="Vumeter")
Index: NetworkEditor/src/RegisterConfiguratorLaunchers.cxx
===================================================================
--- NetworkEditor/src/RegisterConfiguratorLaunchers.cxx	(revision 9990)
+++ NetworkEditor/src/RegisterConfiguratorLaunchers.cxx	(working copy)
@@ -66,6 +66,7 @@
 #include <CLAM/ControlScaler.hxx>
 #include "ControlSurface.hxx"
 #include <CLAM/ControlSource.hxx>
+#include <CLAM/ControlTrace.hxx>
 #include <CLAM/OutControlSender.hxx>
 
 //MIDI
@@ -129,6 +130,8 @@
 STANDARD_PROCESSING_CONFIG_REGISTER(ControlScalerConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(ControlSourceConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(ControlSurfaceConfig);
+STANDARD_PROCESSING_CONFIG_REGISTER(ControlTraceReaderConfig);
+STANDARD_PROCESSING_CONFIG_REGISTER(ControlTraceWriterConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(FlagControlConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(Fundamental2ControlConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(OneOverFConfig);
Index: CLAM/test/FunctionalTests/ProcessingTests/TestControlTraces.cxx
===================================================================
--- CLAM/test/FunctionalTests/ProcessingTests/TestControlTraces.cxx	(revision 0)
+++ CLAM/test/FunctionalTests/ProcessingTests/TestControlTraces.cxx	(revision 0)
@@ -0,0 +1,279 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include "cppUnitHelper.hxx"
+#include <CLAM/ControlTrace.hxx>
+#include "similarityHelper.hxx"
+#include <algorithm>
+#include <cstdio>
+
+namespace CLAMTest
+{
+
+class ControlTraceReaderFunctionalTest;
+CPPUNIT_TEST_SUITE_REGISTRATION( ControlTraceReaderFunctionalTest );
+
+class ControlTraceReaderFunctionalTest
+	: public CppUnit::TestFixture
+{
+	CPPUNIT_TEST_SUITE( ControlTraceReaderFunctionalTest );
+
+	// Configuration values checking tests
+	CPPUNIT_TEST( testConfigure_ReturnsTrueWithJustFilename );
+	CPPUNIT_TEST( testConfigure_ReturnsFalseWithoutTraceFileInConfig );
+	CPPUNIT_TEST( testConfigure_ReturnsTrueWhenFileExists );
+	CPPUNIT_TEST( testConfigure_ReturnsFalseWhenFileDoesNotExist );
+	CPPUNIT_TEST( testConfigure_ReturnsTrueWhenTraceEventsExist );
+	CPPUNIT_TEST( testConfigure_ReturnsFalseWhenTraceFileIsEmpty );
+
+#if 0
+	// File reading checking
+	CPPUNIT_TEST( testDo_PCM_JustOneFrameFromMonoFile );
+	CPPUNIT_TEST( testDo_PCM_JustTwoFramesFromMonoFile );
+	CPPUNIT_TEST( testDo_PCM_JustOneFrameFromStereoFile );
+	CPPUNIT_TEST( testDo_PCM_JustTwoFramesFromStereoFile );
+
+	CPPUNIT_TEST( testDo_OggVorbis_JustOneFrameFromStereoFile );
+	CPPUNIT_TEST( testDo_OggVorbis_JustTwoFramesFromStereoFile );
+
+	CPPUNIT_TEST( test_MpegAudioFiles_AreDecoded_OK );
+
+	CPPUNIT_TEST( testDo_JustTwoFramesBeginTimesAreRight );
+	CPPUNIT_TEST( testDo_JustOneFrame_SampleRateIsOK );
+
+	CPPUNIT_TEST( test_WindowsMedia_WAVE_File );
+#endif
+
+	CPPUNIT_TEST_SUITE_END();
+
+protected: // Attributes
+
+	std::string mPathToTestData;
+	std::string mInputFileName;
+	std::string mEmptyFileName;
+
+protected: // Auxiliary methods
+
+public: // TestFixture interface
+
+	void setUp()
+	{
+		mPathToTestData = GetTestDataDirectory() + "ControlTraceReader";
+		mInputFileName = mPathToTestData + "Input.clamtrace";
+		mEmptyFileName = mPathToTestData + "Empty.clamtrace";
+	}
+
+	void tearDown()
+	{
+	}
+
+private: // tests cases
+
+	void testConfigure_ReturnsTrueWithJustFilename()
+	{
+		CLAM::ControlTraceFileSource file;
+		file.SetLocation(mInputFileName);
+
+		CLAM::ControlTraceReaderConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceReader proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( true, configResult );
+	}
+
+	void testConfigure_ReturnsFalseWithoutTraceFileInConfig()
+	{
+		CLAM::ControlTraceReaderConfig cfg;
+		cfg.RemoveTraceFile();
+		cfg.UpdateData();
+		
+		CLAM::ControlTraceReader proc;
+		
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( false, configResult );
+	}
+	
+	void testConfigure_ReturnsTrueWhenFileExists()
+	{
+		CLAM::ControlTraceFileSource file;
+		file.SetLocation(mInputFileName);
+		CLAM::ControlTraceReaderConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceReader proc;
+		
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( true, configResult );
+	}
+
+	void testConfigure_ReturnsFalseWhenFileDoesNotExist()
+	{
+		CLAM::ControlTraceFileSource file;
+		file.SetLocation(mPathToTestData + 
+				std::string( "missing-file.clamtrace" ) );
+
+		CLAM::ControlTraceReaderConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceReader proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( false, configResult );
+	}
+	
+	void testConfigure_ReturnsTrueWhenTraceEventsExist()
+	{
+		CLAM::ControlTraceFileSource file;
+		file.SetLocation(mInputFileName);
+		
+		CLAM::ControlTraceReaderConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceReader proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( true, configResult );
+	}
+
+	void testConfigure_ReturnsFalseWhenTraceFileIsEmpty()
+	{
+		CLAM::ControlTraceFileSource file;
+		file.SetLocation( mEmptyFileName );
+		
+		CLAM::ControlTraceReaderConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceReader proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( false, configResult );
+		
+	}
+
+};
+
+class ControlTraceWriterFunctionalTest;
+CPPUNIT_TEST_SUITE_REGISTRATION( ControlTraceWriterFunctionalTest );
+
+class ControlTraceWriterFunctionalTest
+	: public CppUnit::TestFixture
+{
+	CPPUNIT_TEST_SUITE( ControlTraceWriterFunctionalTest );
+
+	// Configuration values checking tests
+	CPPUNIT_TEST( testConfigure_ReturnsTrueWithJustFilename );
+	CPPUNIT_TEST( testConfigure_ReturnsFalseWithoutTraceFileInConfig );
+	CPPUNIT_TEST( testConfigure_ReturnsTrueWhenFileExists );
+	CPPUNIT_TEST( testConfigure_ReturnsFalseWithoutInputsInConfig );
+	CPPUNIT_TEST( testConfigure_ReturnsFalseWhenConfiguredWithNoInputs );
+
+	CPPUNIT_TEST_SUITE_END();
+
+protected: // Attributes
+
+	std::string mPathToTestData;
+	std::string mOutputFileName;
+
+protected: // Auxiliary methods
+
+public: // TestFixture interface
+
+	void setUp()
+	{
+		mPathToTestData = GetTestDataDirectory() + "ControlTraceWriter";
+		mOutputFileName = mPathToTestData + "Output.clamtrace";
+	}
+
+	void tearDown()
+	{
+	}
+
+private: // tests cases
+
+	void testConfigure_ReturnsTrueWithJustFilename()
+	{
+		CLAM::ControlTraceFileTarget file;
+		file.SetLocation(mOutputFileName);
+
+		CLAM::ControlTraceWriterConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceWriter proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( true, configResult );
+	}
+
+	void testConfigure_ReturnsFalseWithoutTraceFileInConfig()
+	{
+		CLAM::ControlTraceWriterConfig cfg;
+		cfg.RemoveTraceFile();
+		cfg.UpdateData();
+		
+		CLAM::ControlTraceWriter proc;
+		
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( false, configResult );
+	}
+	
+	void testConfigure_ReturnsTrueWhenFileExists()
+	{
+		CLAM::ControlTraceFileTarget file;
+		file.SetLocation(mOutputFileName);
+
+		CLAM::ControlTraceWriterConfig cfg;
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceWriter proc;
+		
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( true, configResult );
+	}
+
+	void testConfigure_ReturnsFalseWithoutInputsInConfig()
+	{
+		CLAM::ControlTraceFileTarget file;
+		file.SetLocation( mOutputFileName );
+		
+		CLAM::ControlTraceWriterConfig cfg;
+		cfg.RemoveNumberOfInputs();
+		cfg.UpdateData();
+		cfg.SetTraceFile( file );
+
+		CLAM::ControlTraceWriter proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( false, configResult );
+		
+	}
+
+	void testConfigure_ReturnsFalseWhenConfiguredWithNoInputs()
+	{
+		CLAM::ControlTraceFileTarget file;
+		file.SetLocation( mOutputFileName );
+		
+		CLAM::ControlTraceWriterConfig cfg;
+		cfg.SetTraceFile( file );
+		cfg.SetNumberOfInputs( 0 );
+
+		CLAM::ControlTraceWriter proc;
+
+		bool configResult = proc.Configure( cfg );
+
+		CPPUNIT_ASSERT_EQUAL( false, configResult );
+		
+	}
+};
+
+}
+
