diff --git a/Code/Mantid/Framework/DataObjects/CMakeLists.txt b/Code/Mantid/Framework/DataObjects/CMakeLists.txt
index eb6c7317f71c3a165cb9d9c8d038d709acc2bdbe..2013657a5611131dd8c8b62845845bc68072804d 100644
--- a/Code/Mantid/Framework/DataObjects/CMakeLists.txt
+++ b/Code/Mantid/Framework/DataObjects/CMakeLists.txt
@@ -19,6 +19,9 @@ set ( SRC_FILES
 	src/TableColumn.cpp
 	src/TableWorkspace.cpp
 	src/Workspace2D.cpp
+	src/WorkspaceMemento.cpp
+	src/WorkspaceMementoCollection.cpp
+	src/WorkspaceMementoItem.cpp
 	src/WorkspaceSingleValue.cpp
 )
 
@@ -51,6 +54,9 @@ set ( INC_FILES
 	inc/MantidDataObjects/TablePointerColumn.h
 	inc/MantidDataObjects/TableWorkspace.h
 	inc/MantidDataObjects/Workspace2D.h
+	inc/MantidDataObjects/WorkspaceMemento.h
+	inc/MantidDataObjects/WorkspaceMementoCollection.h
+	inc/MantidDataObjects/WorkspaceMementoItem.h
 	inc/MantidDataObjects/WorkspaceSingleValue.h
 )
 
@@ -77,6 +83,9 @@ set ( TEST_FILES
 	test/WeightedEventNoTimeTest.h
 	test/WeightedEventTest.h
 	test/Workspace2DTest.h
+	test/WorkspaceMementoTest.h
+	test/WorkspaceMementoCollectionTest.h
+	test/WorkspaceMementoItemTest.h
 	test/WorkspaceIteratorTest.h
 	test/WorkspaceSingleValueTest.h
 	test/WorkspaceValidatorsTest.h
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h
index a21239882baca70ecd46d025addc3d754584ce71..e2d6bea481cb2501620621b1f1573cd7abd426ff 100644
--- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h
@@ -51,6 +51,9 @@ namespace DataObjects
     /// Must return overall memory size taken by the column.
     virtual long int sizeOfData()const;
 
+    /// Clone.
+    virtual PeakColumn* clone() const;
+
   protected:
     /// Sets the new column size.
     virtual void resize(int count);
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h
index d68e30b64a4f7e1940f6971cabff5c4a6fc21eff..a5555aa9fa701fc4f37446507680e31418957baf 100644
--- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h
@@ -85,6 +85,14 @@ public:
     bool isBool()const{return typeid(Type) == typeid(API::Boolean);}
     /// Memory used by the column
     long int sizeOfData()const{return static_cast<long int>(m_data.size()*sizeof(Type));}
+    /// Clone
+    virtual TableColumn* clone() const
+    {
+      TableColumn* temp = new TableColumn();
+      temp->m_data = this->m_data;
+      temp->setName(this->m_name);
+      return temp;
+    }
 
     /// Reference to the data.
     std::vector<Type>& data(){return m_data;}
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TablePointerColumn.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TablePointerColumn.h
index 08544d31088c399dc6f939fe407c40771c5115fc..8e6856d01266e8780918e21825d7ea8f95a97709 100644
--- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TablePointerColumn.h
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TablePointerColumn.h
@@ -75,6 +75,13 @@ public:
     bool isBool()const{return typeid(Type) == typeid(API::Boolean);}
     /// Memory used by the column
     long int sizeOfData()const{return static_cast<long int>(m_data.size()*sizeof(Type));}
+    /// Clone 
+    virtual TablePointerColumn* clone() const
+    {
+      TablePointerColumn* temp = new TablePointerColumn();
+      temp->m_data = this->m_data;
+      return temp;
+    }
 protected:
     /// Resize.
     void resize(int count)
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
index 38c9c6dd465fa33feace2e6b76c3d3f3b46ff1e2..12a6175e36022199b13b62fd6eda37fe525ba223 100644
--- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
@@ -95,7 +95,6 @@ namespace DataObjects
     virtual const std::string id() const{return "TableWorkspace";}
     /// Get the footprint in memory in KB.
     virtual size_t getMemorySize() const;
-
     /// Creates a new column.
     bool addColumn(const std::string& type, const std::string& name);
     /// Removes a column.
@@ -118,6 +117,8 @@ namespace DataObjects
     int insertRow(int index);
     /// Delets a row if it exists.
     void removeRow(int index);
+    /// Clone table workspace instance.
+    TableWorkspace* clone() const;
 
     /** This method finds the row and column index of an integer cell value in a table workspace
      * @param value :: -value to search
@@ -209,7 +210,9 @@ private:
 			throw;
 		}
 	}
-	
+
+    bool addColumn(boost::shared_ptr<API::Column> column);
+
     /** This method finds the row and column index of an integer cell value in a table workspace
     * @param value :: -value to search
     * @param  row  row number of the value  searched
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMemento.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMemento.h
new file mode 100644
index 0000000000000000000000000000000000000000..2730c8b1b46d7142fb5dadcbf8d11e3bc4420064
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMemento.h
@@ -0,0 +1,112 @@
+#ifndef MANTID_DATAOBJECTS_MEMENTO_H_
+#define MANTID_DATAOBJECTS_MEMENTO_H_
+
+#include "MantidKernel/System.h"
+#include "MantidDataObjects/WorkspaceMementoItem.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <boost/scoped_ptr.hpp>
+
+namespace Mantid
+{
+  namespace DataObjects
+  {
+    /**
+    Abstract Functor for locking usage. 
+    */
+    class DLLExport WorkspaceMementoLock
+    {
+    public:
+      virtual void lock() = 0;
+      virtual bool unlock() = 0;
+      virtual bool locked() const = 0;
+      virtual ~WorkspaceMementoLock(){}
+    };
+
+    /**
+    Concrete locking functor implementing single-owner-usage for locking.
+    */
+    class DLLExport SingleOwnerLock : public WorkspaceMementoLock
+    {
+    private:
+      typedef std::map<size_t, bool> LockMap;
+      static LockMap locks;
+      size_t m_runNumber;
+    public:
+      SingleOwnerLock(size_t runNumber);
+      virtual void lock();
+      virtual bool unlock();
+      virtual bool locked() const;
+      virtual ~SingleOwnerLock();
+    };
+
+    /** @class WorkspaceMemento
+
+    Stores local changes to Workspace metadata. Can commit or rollback these changes to an underlying table workspace,
+    which encapsulates all changes to a set of related workspaces (see WorkspaceMementoCollection).
+
+    @author Owen Arnold
+    @date 30/08/2011
+
+    Copyright &copy; 2007-8 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+
+    This file is part of Mantid.
+
+    Mantid 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.
+
+    Mantid 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/>.
+
+    File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
+    Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+    class DLLExport WorkspaceMemento
+    {
+    public:
+
+      typedef std::vector<AbstractMementoItem_sptr> VecMementoItems;
+      WorkspaceMemento(TableWorkspace& ws, size_t runNumber);
+      WorkspaceMemento(TableWorkspace& ws, size_t runNumber, WorkspaceMementoLock* lock);
+      ~WorkspaceMemento(); 
+      void addItem(AbstractMementoItem* item);
+      AbstractMementoItem_sptr getItem(const size_t col) const;
+      void commit();
+      void rollback();
+      bool hasChanged() const;
+      void validate() const;
+      bool equals(const WorkspaceMemento& workspace) const;
+      bool operator==(const WorkspaceMemento& workspace) const;
+      bool operator!=(const WorkspaceMemento& workspace) const;
+      bool locked() const;
+      bool unlock();
+      void lock();
+    private:
+      /// Reference to underlying data.
+      const TableWorkspace& m_data;
+      /// Memento items to store local/un-saved changes.
+      VecMementoItems m_items;
+      /// Flag indicating memento is valid.
+      bool m_validMemento;
+      /// Run number associated with this memento.
+      size_t m_runNumber;
+      /// Disabled copy constructor.
+      WorkspaceMemento(const WorkspaceMemento&);
+      /// Disabled assignement operator.
+      WorkspaceMemento& operator=(const WorkspaceMemento&);
+      /// Locking object.
+      boost::scoped_ptr<WorkspaceMementoLock> m_lock;
+
+    };
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMementoCollection.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMementoCollection.h
new file mode 100644
index 0000000000000000000000000000000000000000..e86336d1387f233fdd852ff7ecab55322f58330e
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMementoCollection.h
@@ -0,0 +1,88 @@
+#ifndef MANTID_DATAOBJECTS_MEMENTO_COLLECTION_H_
+#define MANTID_DATAOBJECTS_MEMENTO_COLLECTION_H_
+
+#include "MantidDataObjects/WorkspaceMemento.h"
+#include <boost/scoped_ptr.hpp>
+
+namespace Mantid
+{
+  namespace API
+  {
+    class Workspace;
+  }
+  namespace DataObjects
+  {
+    /// Locking proxy smart pointer. Ensures that Workspace Mementos are always locked and unlocked.
+    class DLLExport LockingMemento {
+    public:
+      LockingMemento (WorkspaceMemento *memento) : m_memento (memento) 
+      {
+        m_memento->lock();
+      }
+      WorkspaceMemento * operator -> () 
+      {
+        return m_memento;
+      }
+      ~LockingMemento () 
+      {
+        m_memento->unlock();
+        delete m_memento;
+      }
+    private:
+      WorkspaceMemento* m_memento;
+    };
+
+
+    /** @class WorkspaceMementoCollection
+
+    Stores all changes to registerd workspace in-terms of a diff-table (TableWorkspace). The final diff table can be exported and used
+    to generate a series of workspaces encapsulating all the changes described within the table.
+
+    Main workflow
+
+    -Register workspaces via method call ::registerWorkspace
+    -Fetch workspace mementos via method call ::at
+    -Serialize changes via method call ::serialize
+
+    Mementos are returned in a Locked format, meaning that no other memento may change that table row (corresponding to an individual run/workspace).
+    Once the fields are changed on the memento, changes may be committed or rolled-back. These operations occur directly on the diff table contained within the MementoCollection.
+    The Memento collection does NOT own memento objects, it is a factory for them.
+
+    @author Owen Arnold
+    @date 26/08/2011
+
+    Copyright &copy; 2011-12 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+
+    This file is part of Mantid.
+
+    Mantid 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.
+
+    Mantid 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/>.
+
+    File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
+    Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+    class DLLExport WorkspaceMementoCollection
+    {
+    public:
+      WorkspaceMementoCollection();
+      ~WorkspaceMementoCollection();
+      void registerWorkspace(const Mantid::API::Workspace& ws);
+      LockingMemento at(size_t runNumber);
+      TableWorkspace* serialize() const;
+    private:
+      TableWorkspace m_data;
+    };
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMementoItem.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMementoItem.h
new file mode 100644
index 0000000000000000000000000000000000000000..c574ea8c61b10e6175c19261d0b5c3eb15313d6c
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceMementoItem.h
@@ -0,0 +1,207 @@
+#ifndef MANTID_DATAOBJECTS_MEMENTO_ITEM_H_
+#define MANTID_DATAOBJECTS_MEMENTO_ITEM_H_
+#include "MantidKernel/System.h"
+#include "MantidDataObjects/TableWorkspace.h"
+#include "boost/shared_ptr.hpp"
+
+namespace Mantid
+{
+  namespace DataObjects
+  {
+
+
+    /**  @class Boolean
+    As TableColumn stores its data in a std::vector bool type cannot be used 
+    in the same way as the other types. Class Boolean is used instead.
+*/
+    class DLLExport AbstractMementoItem
+    {
+    public:
+      virtual bool hasChanged() const = 0;
+      virtual void commit() = 0;
+      virtual void rollback() = 0;
+      virtual bool equals(AbstractMementoItem& other) const = 0;
+      virtual ~AbstractMementoItem() {}
+    };
+
+
+    typedef boost::shared_ptr<AbstractMementoItem> AbstractMementoItem_sptr;
+    
+    /** @class WorkspaceMementoItem. Unique type for column data, through which changes to cell data can be applied, stored and reverted.
+    Type system ensures that no two columns are comparible, even if they store the same data.
+
+
+    @author Owen Arnold
+    @date 25/08/2011
+
+    Copyright &copy; 2011-12 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+
+    This file is part of Mantid.
+
+    Mantid 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.
+
+    Mantid 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/>.
+
+    File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
+    Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+    template<int ColNumber, typename ColType>
+    class DLLExport WorkspaceMementoItem : public AbstractMementoItem
+    {
+    private:
+      /// Actual/outstanding value stored in cell.
+      ColType m_value;
+      /// Reference to mutable table workspace.
+      TableWorkspace& m_data;
+      /// Row onto which this column object projects.
+      size_t m_rowIndex;
+
+    public:
+      /// Unique column index.
+      enum { ColIndex = ColNumber };
+      /// Type of item being stored.
+      typedef ColType ItemType;
+      
+      /**
+      Constructor
+      @param data : ref to table workspace storing the data.
+      @param rowIndex : index of the row in the table workspace that this column/memento item. is to apply.
+      */
+      WorkspaceMementoItem(TableWorkspace& data, size_t rowIndex) : m_data(data), m_rowIndex(rowIndex)
+      {
+        m_value = m_data.getColumn(ColIndex)->cell<ColType>(m_rowIndex);
+      }
+
+      /**
+      Copy constructor
+      @param other : memento item to copy from.
+      */
+      WorkspaceMementoItem(const WorkspaceMementoItem& other) : m_value(other.m_value), m_data(other.m_data), m_rowIndex(other.m_rowIndex)
+      {
+      }
+      
+      /**
+      Overrriden assignement operator.
+      @param other : memento item to assign from.
+      */
+      WorkspaceMementoItem& operator=(const WorkspaceMementoItem& other)
+      {
+        if(&other != this)
+        {
+          m_value = other.m_value;
+          m_rowIndex = other.m_rowIndex;
+        }
+        return *this;
+      }
+
+      /// Destructor
+      virtual ~WorkspaceMementoItem()
+      {
+      }
+
+      /*
+      Getter for changed status.
+      @return true if different.
+      */
+      virtual bool hasChanged() const 
+      {
+        return m_data.getColumn(ColIndex)->cell<ColType>(m_rowIndex) != m_value;
+      }
+
+      /*
+      Abstract equals operator. Templated type indepenedent in interface.
+      @param other : Abstract memento item to compare against.
+      @return true if equal.
+      @throw runtime error if type mismatch.
+      */
+      bool equals(AbstractMementoItem& other) const
+      {
+        WorkspaceMementoItem* pOther = dynamic_cast<WorkspaceMementoItem<ColNumber, ColType>* >(&other);
+        if(pOther == NULL)
+        {
+          throw std::runtime_error("Cannot call AbstractMementoItem::equals() on incompatible types.");
+        }
+        else
+        {
+          return equals(*pOther);
+        }
+      }
+
+      /**
+      Strongly typed equals operator.
+      @param other : ref to other (same exact type) workspace memento item to compare against.
+      @return true if same.
+      */
+      bool equals(const WorkspaceMementoItem& other) const
+      {
+        return m_value == other.m_value;
+      }
+
+      /**
+      Equals operator.
+      @param other : ref to other (same exact type) workspace memento item to compare against.
+      @return true if same.
+      */
+      bool operator==(const WorkspaceMementoItem& other) const
+      {
+        return equals(other);
+      }
+
+      /**
+      Not equals operator.
+      @param other : ref to other (same exact type) workspace memento item to compare against.
+      @return true if not same.
+      */
+      bool operator!=(const WorkspaceMementoItem& other) const
+      {
+        return !equals(other);
+      }
+
+      /**
+      Set the internal value. This is a reversable operation.
+      @value : value to set on memento item.
+      */
+      void setValue(ColType value)
+      {
+        m_value = value;
+      }
+
+     
+      /// Synchronise the changes (via setvalue) with the underlying table workspace. This is a non reversible operation. 
+      void commit()
+      {
+        m_data.getColumn(ColIndex)->cell<ColType>(m_rowIndex) = m_value;
+      }
+
+      /// Undo changes via setValue. 
+      void rollback()
+      {
+        m_value = m_data.getColumn(ColIndex)->cell<ColType>(m_rowIndex);
+      }
+
+      /**
+      Get the value.
+      @return value.
+      */
+      ColType getValue() const
+      {
+        return m_value; //TODO, should we be returning the set value or the commited value.
+      }
+
+    };
+
+  }
+}
+
+
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp b/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp
index 6f051e3bff874cbd5145f439f3bb8d839b5fd207..c941ff76762171baf76a935d394f59fa178b9586 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp
@@ -166,6 +166,12 @@ namespace DataObjects
     throw std::runtime_error("const version of void_pointer() not implemented. Looks to be unused?");
   }
 
+  PeakColumn* PeakColumn::clone() const
+  {
+    PeakColumn* temp = new PeakColumn(this->peaks, this->m_name);
+    return temp;
+  }
+
 } // namespace Mantid
 } // namespace DataObjects
 
diff --git a/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp
index 2241cfa1464697e0dadc5ff351144366ce8cfc44..10f1b3b7dd0460ad033d0308d34398caf16760d5 100644
--- a/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp
@@ -173,6 +173,32 @@ namespace Mantid
         return nameList;
     }
 
+    bool TableWorkspace::addColumn(boost::shared_ptr<API::Column> column)
+    {
+      column_it ci = std::find_if(m_columns.begin(),m_columns.end(),FindName(column->name()));
+      if (ci != m_columns.end())
+      {
+        g_log.error()<<"Column with name "<<column->name()<<" already exists.\n";
+        return false;
+      }
+      else
+      {
+        m_columns.push_back(column);
+      }
+    }
+
+    TableWorkspace* TableWorkspace::clone() const
+    {
+      TableWorkspace* copy = new TableWorkspace(this->m_rowCount);
+      column_const_it it=m_columns.begin();
+      while(it != m_columns.end())
+      {
+        copy->addColumn(boost::shared_ptr<API::Column>((*it)->clone()));
+        it++;
+      }
+      return copy;
+    };
+
 //    template<>
 //    boost::tuples::null_type TableWorkspace::make_TupleRef< boost::tuples::null_type >(int j,const std::vector<std::string>& names,int i)
 //    {return boost::tuples::null_type();}
diff --git a/Code/Mantid/Framework/DataObjects/src/WorkspaceMemento.cpp b/Code/Mantid/Framework/DataObjects/src/WorkspaceMemento.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4caa19d45c10253efade628c4bd1c8936be20d40
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/src/WorkspaceMemento.cpp
@@ -0,0 +1,226 @@
+#include "MantidDataObjects/WorkspaceMemento.h"
+
+namespace Mantid
+{
+  namespace DataObjects
+  {
+
+    /**
+    Constructor
+    @param ws : ref to underlying table workspace where persisted data is stored.
+    @param runNumber : the run number corresponding to this memento.
+    */
+    WorkspaceMemento::WorkspaceMemento(TableWorkspace& ws, size_t runNumber) :
+      m_data(ws), 
+      m_validMemento(false), 
+      m_runNumber(runNumber), 
+      m_lock(new SingleOwnerLock(runNumber))
+    {
+    }
+
+    /**
+    Constructor with option to specify locking object.
+    @param ws : ref to underlying table workspace where persisted data is stored.
+    @param runNumber : the run number corresponding to this memento.
+    @param lock : locking object to use internally.
+    */
+     WorkspaceMemento::WorkspaceMemento(TableWorkspace& ws, size_t runNumber, WorkspaceMementoLock* lock) : 
+      m_data(ws), 
+      m_validMemento(false), 
+      m_runNumber(runNumber), 
+      m_lock(lock)
+    {
+    }
+
+    /// Destructor
+    WorkspaceMemento::~WorkspaceMemento()
+    {
+    }
+
+    /* Add a metadata item. This corresponds to a cell in the underlying table workspace.
+    @param item : Abstract memento item shared pointer.
+    */
+    void WorkspaceMemento::addItem(AbstractMementoItem* item)
+    {
+      //TODO check types here. Type of item should be the same as the corresponding colum in the table.
+      AbstractMementoItem_sptr temp(item);
+      m_items.push_back(temp);
+      m_items.size() == m_data.columnCount() ? m_validMemento = true : m_validMemento = false;
+    }
+
+    /* Getter for the item at a column
+       @return Abstract memento item shared pointer.
+    */
+    AbstractMementoItem_sptr WorkspaceMemento::getItem(const size_t col) const
+    {
+      return m_items[col];
+    }
+
+    /**
+    Getter for the locked status.
+    @return locked status.
+    */
+    bool WorkspaceMemento::locked() const
+    {
+      return m_lock->locked();
+    }
+
+    /// Request the memento and underlying data are locked.
+    void WorkspaceMemento::lock()
+    {
+     return m_lock->lock();
+    }
+
+    /**
+    Unlock the memento. 
+    @return true if sucessfully unlocked, false if already unlocked.
+    */
+    bool WorkspaceMemento::unlock()
+    {
+      return m_lock->unlock();
+    }
+
+    /// Validate the workspace. Ensure that it is well-setup before using as a memento.
+    void WorkspaceMemento::validate() const
+    {
+      if(!m_validMemento)
+      {
+        throw std::runtime_error("Cannot use this type without first having set it up using ::addItem");
+      }
+    }
+
+    /**
+    Getter indicating if there are changes not yet persisted to the underlying table workspace.
+    @return true if outstanding changes exist.
+    */
+    bool WorkspaceMemento::hasChanged() const
+    {
+      validate();
+      //Run through each memento item for its changed status.
+      VecMementoItems::const_iterator it = m_items.begin();
+      while(it != m_items.end())
+      {
+        if((*it)->hasChanged()){ return true; }
+        it++;
+      }
+      return false;
+    }
+
+    /**
+    Equals comparitor for this instance with another memento.
+    @param other : another workspace memento to compare to.
+    @return true if equal.
+    */
+    bool WorkspaceMemento::equals(const WorkspaceMemento& other) const
+    {
+      validate();
+      bool bResult = false;
+      if(this->m_items.size() != other.m_items.size())
+      {
+        return bResult;
+      }
+      for(size_t i = 0; i < m_items.size(); i++)
+      {
+        //Defer to each memento item.
+        bResult = m_items[i]->equals(*other.m_items[i]);
+        if(!bResult)
+          break;
+      }
+      return bResult;
+    }
+
+    /**
+    Equals operator overload.
+    @param other : another workspace memento to compare to.
+    @return true if equal.
+    */
+    bool WorkspaceMemento::operator==(const WorkspaceMemento& other) const
+    {
+      return this->equals(other);
+    }
+
+    /**
+    Not equals operator overload.
+    @param other : another workspace memento to compare to.
+    @return false if equal.
+    */
+    bool WorkspaceMemento::operator!=(const WorkspaceMemento& other) const
+    {
+      return !this->equals(other);
+    }
+
+    /// Commit changes 
+    void WorkspaceMemento::commit()
+    {
+      validate();
+      VecMementoItems::const_iterator it = m_items.begin();
+      while(it != m_items.end())
+      {
+        (*it)->commit();
+        it++;
+      }
+    }
+
+    /// Roll back changes
+    void WorkspaceMemento::rollback()
+    {
+      validate();
+      VecMementoItems::const_iterator it = m_items.begin();
+      while(it != m_items.end())
+      {
+        (*it)->rollback();
+        it++;
+      }
+    }
+
+    // ------------------ TODO split following off into separate cpp ----------------
+
+    SingleOwnerLock::LockMap SingleOwnerLock::locks;
+
+    SingleOwnerLock::SingleOwnerLock(size_t runNumber) : m_runNumber(runNumber) {}
+
+      /// Apply the lock.
+      void SingleOwnerLock::lock()
+      {
+        //You could get a race condition in the following, but this code is not intended for parallel usage.
+        if(locked())
+        {
+          throw std::runtime_error("This memento is already in use!");
+        }
+        SingleOwnerLock::locks[m_runNumber] = true;
+      }
+
+      /**
+      Remove the lock.
+      @return true if locked when unlocked. Returns false if already unlocked.
+      */
+      bool SingleOwnerLock::unlock()
+      {
+        bool existingState = SingleOwnerLock::locks[m_runNumber];
+        SingleOwnerLock::locks[m_runNumber] = false;
+        return existingState;
+      }
+
+      /**
+      Getter for the locked status.
+      @return true if locked.
+      */
+      bool SingleOwnerLock::locked() const
+      {
+        LockMap::iterator it = SingleOwnerLock::locks.find(m_runNumber);
+        if(SingleOwnerLock::locks.end() != it)
+        {
+          return it->second;
+        }
+        return false;
+      }
+
+      /// Destructor
+      SingleOwnerLock::~SingleOwnerLock()
+      {
+        //Remove the lock if not done so already.
+        if(locked())
+          unlock();
+      }
+  }
+}
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/src/WorkspaceMementoCollection.cpp b/Code/Mantid/Framework/DataObjects/src/WorkspaceMementoCollection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..af068ed39fc3635878ad3aef19298e942d1bbdff
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/src/WorkspaceMementoCollection.cpp
@@ -0,0 +1,66 @@
+#include "MantidDataObjects/WorkspaceMementoCollection.h"
+#include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/TableRow.h" 
+#include "MantidDataObjects/WorkspaceMemento.h"
+
+namespace Mantid
+{
+  namespace DataObjects
+  {
+    /// Constructor
+    WorkspaceMementoCollection::WorkspaceMementoCollection()
+    {
+      //Define the table schema here
+      m_data.addColumn("str", "WorkspaceName");
+      //TODO, lots more columns will be required here.
+    }
+
+    /**
+    Register a workspace so that mementos may be generated from it.
+    @param ws : ref to workspace to generate mementos for.
+    */
+    void WorkspaceMementoCollection::registerWorkspace(const Mantid::API::Workspace& ws)
+    {
+      using namespace API;
+      //Add row to table.
+      m_data.insertRow(m_data.rowCount() + 1);
+      TableRow row = m_data.getRow(m_data.rowCount()-1);
+      row << ws.getName();
+    }
+
+    /**
+    Gets the workspace memento at a designated runnumber.
+    Workspace mementos are returned in locking smart pointers to ensure that there is no accidental duplicate access.
+    @param runNumber : The run number.
+    @return locking smart pointer wrapping workspace memento.
+    */
+    LockingMemento WorkspaceMementoCollection::at(size_t runNumber)
+    {
+      WorkspaceMemento* memento = new WorkspaceMemento(m_data, runNumber);
+      
+      //Table schema should be identical to that described in constructor.
+      
+      memento->addItem(new WorkspaceMementoItem<0, std::string>(m_data, runNumber));
+      //TODO lots more column items to add.
+      
+      //Wrap product and return.
+      return LockingMemento(memento);
+    }
+
+    /**
+    Serializes workspace changes to xml.
+    @return serialized table workspace containing all diffs.
+    */
+    TableWorkspace* WorkspaceMementoCollection::serialize() const
+    {
+      //TODO, should hasChanges be checked first? Presumbably we need to ensure that all mementos are in an unmodified state before this is allowed.
+      return m_data.clone();
+    }
+
+    /// Destructor
+    WorkspaceMementoCollection::~WorkspaceMementoCollection()
+    {
+    }
+
+  }
+}
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/src/WorkspaceMementoItem.cpp b/Code/Mantid/Framework/DataObjects/src/WorkspaceMementoItem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..54dc1dba817da77c1e334753c94c8d95e03aa6c1
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/src/WorkspaceMementoItem.cpp
@@ -0,0 +1,9 @@
+#include "MantidDataObjects/WorkspaceMementoItem.h"
+
+namespace Mantid
+{
+  namespace DataObjects
+  {
+
+  }
+}
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/test/PeakColumnTest.h b/Code/Mantid/Framework/DataObjects/test/PeakColumnTest.h
index 20ec171fda183ded0d0ba35b46fc012fc456153e..71fba7a671c80d3ce65d455b100a41343ba1b9d8 100644
--- a/Code/Mantid/Framework/DataObjects/test/PeakColumnTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/PeakColumnTest.h
@@ -24,6 +24,25 @@ public:
     TS_ASSERT_EQUALS( pc.size(), 0);
   }
 
+  void test_clone()
+  {
+    Peak a;
+    Peak b;
+
+    std::vector<Peak> peaks;
+    peaks.push_back(a);
+    peaks.push_back(b);
+
+    PeakColumn pc(peaks, "h");
+
+    PeakColumn* cloned = pc.clone();
+
+    TS_ASSERT_EQUALS(pc.name(), cloned->name());
+    TS_ASSERT_EQUALS(2, cloned->size());
+
+    delete cloned;
+  }
+
 
 
 };
diff --git a/Code/Mantid/Framework/DataObjects/test/TableWorkspaceTest.h b/Code/Mantid/Framework/DataObjects/test/TableWorkspaceTest.h
index dd91cbf39c575599f1ea3a5bcf4dd630fe704756..841cfb9ddf234d6a21bec2e81263e0f21b817df3 100644
--- a/Code/Mantid/Framework/DataObjects/test/TableWorkspaceTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/TableWorkspaceTest.h
@@ -4,6 +4,7 @@
 #include <vector> 
 #include <algorithm> 
 #include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataObjects/TableWorkspace.h" 
@@ -249,8 +250,27 @@ public:
 	  tw.find(searchstr,row,formatcol);
 	  TS_ASSERT_EQUALS(row,7);
 
+  }
 
-
+  void testClone()
+  {
+    TableWorkspace tw(1);
+	  tw.addColumn("str","X");
+	  tw.addColumn("str","Y");
+	  tw.addColumn("str","Z");
+   
+    tw.getColumn(0)->cell<std::string>(0) = "a";
+    tw.getColumn(1)->cell<std::string>(0) = "b";
+    tw.getColumn(2)->cell<std::string>(0) = "c";
+
+    boost::scoped_ptr<TableWorkspace> cloned(tw.clone());
+
+    //Check clone is same as original.
+    TS_ASSERT_EQUALS(tw.columnCount(), cloned->columnCount());
+    TS_ASSERT_EQUALS(tw.rowCount(), cloned->rowCount());
+    TS_ASSERT_EQUALS("a", cloned->getColumn(0)->cell<std::string>(0));
+    TS_ASSERT_EQUALS("b", cloned->getColumn(1)->cell<std::string>(0));
+    TS_ASSERT_EQUALS("c", cloned->getColumn(2)->cell<std::string>(0));
 
   }
 
diff --git a/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoCollectionTest.h b/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoCollectionTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6a4b1366475a5abba1cf9f56877fb2a714d7deb
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoCollectionTest.h
@@ -0,0 +1,58 @@
+#ifndef MANTID_WORKSPACE_MEMENTO_COLLECTION_TEST_H_
+#define MANTID_WORKSPACE_MEMENTO_COLLECTION_TEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidDataObjects/WorkspaceMementoCollection.h"
+#include "MantidDataObjects/TableWorkspace.h"
+
+using namespace Mantid::DataObjects;
+
+class WorkspaceMementoCollectionTest : public CxxTest::TestSuite
+{
+public:
+
+  void testSerialize()
+  {
+    WorkspaceMementoCollection collection;
+    TableWorkspace* productA = collection.serialize();
+    TableWorkspace* productB = collection.serialize();
+
+    TSM_ASSERT_EQUALS("Characterisation test. Current table schema has 1 column", 1, productA->columnCount());
+    TSM_ASSERT_EQUALS("No workspaces registered, so should have no rows.", 0, productA->rowCount());
+    TSM_ASSERT("Check are different locations on heap", productA != productB);
+    delete productA;
+    delete productB;
+  }
+
+void testRegisterWorkspace()
+{
+  TableWorkspace ws;
+  ws.setName("WSName");
+
+  WorkspaceMementoCollection collection;
+  collection.registerWorkspace(ws); //Could be any other kind of workspace.
+  TableWorkspace* product = collection.serialize();
+  
+  TSM_ASSERT_EQUALS("Registered workspace property not serialized.", "WSName", product->cell<std::string>(0, 0));
+  delete product;
+}
+
+void testGetMemento()
+{
+  TableWorkspace ws;
+  ws.setName("WSName");
+
+  WorkspaceMementoCollection collection;
+  collection.registerWorkspace(ws); //Could be any other kind of workspace registered.
+  LockingMemento smrtPtr = collection.at(0);
+  boost::shared_ptr<WorkspaceMementoItem<0, std::string> > pExact = boost::dynamic_pointer_cast<WorkspaceMementoItem<0, std::string> >(smrtPtr->getItem(0));
+
+  TS_ASSERT(pExact != NULL);
+  TS_ASSERT_EQUALS("WSName", pExact->getValue());
+
+}
+
+
+};
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoItemTest.h b/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoItemTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0fa3b940ce99623271447ff171638b017f4742d
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoItemTest.h
@@ -0,0 +1,140 @@
+#ifndef MANTID_WORKSPACE_MEMENTO_ITEM_TEST_H_
+#define MANTID_WORKSPACE_MEMENTO_ITEM_TEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidDataObjects/WorkspaceMementoItem.h"
+#include <string>
+
+using Mantid::DataObjects::WorkspaceMementoItem;
+using Mantid::DataObjects::TableWorkspace;
+
+class WorkspaceMementoItemTest : public CxxTest::TestSuite
+{
+
+private:
+
+  TableWorkspace ws;
+
+public:
+
+WorkspaceMementoItemTest() : ws(2)
+{
+  //Set up a table workspace with one column and one row. then put a single 
+  //value integer in that workspace with value 1.
+  ws.addColumn("int", "test_col1");
+  ws.addColumn("int", "test_col2");
+  ws.getColumn(0)->cell<int>(0) = 1;
+  ws.getColumn(1)->cell<int>(0) = 1;
+}
+
+void testConstructor()
+{
+  //Integer Item
+  WorkspaceMementoItem<0, int> a(ws, 0);
+  TS_ASSERT_EQUALS(0, a.ColIndex);
+  TS_ASSERT_EQUALS(1, a.getValue());
+}
+
+void testEqualsThrows()
+{
+  typedef WorkspaceMementoItem<0, int> TypeA;
+  typedef WorkspaceMementoItem<1, int> TypeB; //Different column number constitutes a different type.
+  TypeA A(ws, 0);
+  TypeB B(ws, 0);
+
+  TSM_ASSERT_THROWS("Should throw if types on which equals are called are not compatible.", A.equals(B), std::runtime_error);
+}
+
+void testEquals()
+{
+  WorkspaceMementoItem<0, int> a(ws, 0);
+  a.setValue(2);
+  WorkspaceMementoItem<0, int> b(ws, 0);
+  b.setValue(2);
+
+  TS_ASSERT(a.equals(b));
+  TS_ASSERT(b.equals(a));
+  TS_ASSERT_EQUALS(a, b);
+}
+
+void testNotEquals()
+{
+  WorkspaceMementoItem<0, int> a(ws, 0);
+  a.setValue(2);
+  WorkspaceMementoItem<0, int> b(ws, 0);
+  b.setValue(3);
+
+  TS_ASSERT(!a.equals(b));
+  TS_ASSERT(!b.equals(a));
+  TS_ASSERT_DIFFERS(a, b);
+  TS_ASSERT(a.operator!=(b));
+}
+
+void testCopy()
+{
+  WorkspaceMementoItem<0, int> item(ws, 0);
+  item.setValue(3);
+  WorkspaceMementoItem<0, int> copy(item);
+
+  TS_ASSERT_EQUALS(item, copy);
+}
+
+void testAssign()
+{
+  WorkspaceMementoItem<0, int> a(ws, 0);
+  a.setValue(3);
+  WorkspaceMementoItem<0, int> b(ws, 0);
+  b.setValue(4);
+  b = a;
+  TS_ASSERT_EQUALS(a, b);
+  TS_ASSERT_EQUALS(3, b.getValue());
+}
+
+void testSetValue()
+{
+  WorkspaceMementoItem<0, int> item(ws, 0);
+  item.setValue(2);
+  TS_ASSERT_EQUALS(2, item.getValue());
+}
+
+void testHasChanged()
+{
+  //create  a mementoitem pointing at the same cell in the table workspace.
+  WorkspaceMementoItem<0, int> item(ws, 0);
+  TS_ASSERT(!item.hasChanged());
+  item.setValue(2000);
+  TS_ASSERT(item.hasChanged());
+}
+
+void testApplyChanges()
+{
+
+  //create  a mementoitem pointing at the same cell in the table workspace.
+  WorkspaceMementoItem<0, int> item(ws, 0);
+  item.setValue(2);
+
+  //Apply changes in memento over to the table workspace.
+  TS_ASSERT_THROWS_NOTHING(item.commit());
+
+  //Check that the chanes arrive.
+  TS_ASSERT_EQUALS(2, ws.getColumn(0)->cell<int>(0));
+  TSM_ASSERT("Changes have been applied. Should not indicate outstanding!", !item.hasChanged())
+}
+
+void testRevertChanges()
+{
+
+  //create  a mementoitem pointing at the same cell in the table workspace.
+  WorkspaceMementoItem<0, int> item(ws, 0);
+  item.setValue(2);
+
+  //Apply changes in memento over to the table workspace.
+  TS_ASSERT_THROWS_NOTHING(item.rollback());
+  TSM_ASSERT("Changes have been reverted. Should not indicate outstanding!", !item.hasChanged())
+}
+
+
+
+};
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoTest.h b/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc6f6c8b0c5532f4a900466325889c40117c8b63
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/test/WorkspaceMementoTest.h
@@ -0,0 +1,177 @@
+#ifndef MANTID_WORKSPACE_MEMENTO_TEST_H_
+#define MANTID_WORKSPACE_MEMENTO_TEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidDataObjects/WorkspaceMemento.h"
+
+using namespace Mantid::DataObjects;
+
+class WorkspaceMementoTest : public CxxTest::TestSuite
+{
+
+private:
+
+  TableWorkspace ws;
+
+public:
+
+WorkspaceMementoTest() : ws(2)
+{
+  //Set up a table workspace with one column and one row. then put a single 
+  //value integer in that workspace with value 1.
+  ws.addColumn("int", "test_col1");
+  ws.addColumn("int", "test_col2");
+}
+
+void setUp()
+{
+  ws.getColumn(0)->cell<int>(0) = 1;
+  ws.getColumn(1)->cell<int>(0) = 1;
+}
+
+void testInvalidWithoutAddingItems()
+{
+  WorkspaceMemento memento(ws, 0);
+  TSM_ASSERT_THROWS("Should not be valid. No items added!", memento.validate(), std::runtime_error);
+}
+
+void testAddItems()
+{
+  WorkspaceMemento memento(ws, 0);
+  memento.addItem(new WorkspaceMementoItem<0, int>(ws, 0));
+  memento.addItem(new WorkspaceMementoItem<1, int>(ws, 0));
+  TS_ASSERT_THROWS_NOTHING(memento.validate());
+  TS_ASSERT(!memento.hasChanged());
+}
+
+void testItemHasChanged()
+{
+  WorkspaceMemento memento(ws, 0);
+  typedef WorkspaceMementoItem<0, int> ColA;
+  typedef WorkspaceMementoItem<1, int> ColB;
+
+  ColA* colA = new ColA(ws, 0);
+  ColB* colB = new ColB(ws, 0);
+
+  memento.addItem(colA);
+  memento.addItem(colB);
+  TS_ASSERT_THROWS_NOTHING(memento.validate());
+  TS_ASSERT(!memento.hasChanged());
+
+  colA->setValue(9); //Set to something different.
+
+  TSM_ASSERT("Should have registered that one of the items has changed.",memento.hasChanged());
+}
+
+void testItemReverted()
+{
+  WorkspaceMemento memento(ws, 0);
+  typedef WorkspaceMementoItem<0, int> ColA;
+  typedef WorkspaceMementoItem<1, int> ColB;
+
+  ColA* colA = new ColA(ws, 0);
+  ColB* colB = new ColB(ws, 0);
+
+  memento.addItem(colA);
+  memento.addItem(colB);
+
+  colA->setValue(9); //Set to something different.
+  memento.rollback(); //Now rollback changes.
+
+  TSM_ASSERT("Should have rolledback everything.", !memento.hasChanged());
+}
+
+
+void testItemCommitted()
+{
+  WorkspaceMemento memento(ws, 0);
+  typedef WorkspaceMementoItem<0, int> ColA;
+  typedef WorkspaceMementoItem<1, int> ColB;
+
+  ColA* colA = new ColA(ws, 0);
+  ColB* colB = new ColB(ws, 0);
+
+  memento.addItem(colA);
+  memento.addItem(colB);
+
+  colA->setValue(9); //Set to something different.
+  memento.commit(); //Now commit changes.
+
+  TSM_ASSERT("Should have commited everything.", !memento.hasChanged());
+}
+
+void testEquals()
+{
+  WorkspaceMemento a(ws, 0);
+  a.addItem(new WorkspaceMementoItem<0, int>(ws, 0));
+  a.addItem(new WorkspaceMementoItem<1, int>(ws, 0));
+
+  WorkspaceMemento b(ws, 0);
+  b.addItem(new WorkspaceMementoItem<0, int>(ws, 0));
+  b.addItem(new WorkspaceMementoItem<1, int>(ws, 0));
+
+  TS_ASSERT(a.equals(b));
+  TS_ASSERT(b.equals(a));
+  TS_ASSERT(a == b);
+};
+
+void testNotEquals()
+{
+  WorkspaceMemento a(ws, 0);
+  a.addItem(new WorkspaceMementoItem<0, int>(ws, 0));
+  a.addItem(new WorkspaceMementoItem<1, int>(ws, 0));
+
+  WorkspaceMemento b(ws, 0);
+  WorkspaceMementoItem<0, int>* colA = new WorkspaceMementoItem<0, int>(ws, 0);
+  b.addItem(colA);
+  colA->setValue(9);// Set item on b to something different.
+  b.addItem(new WorkspaceMementoItem<1, int>(ws, 0));
+
+  TS_ASSERT(!a.equals(b));
+  TS_ASSERT(!b.equals(a));
+  TS_ASSERT(a != b);
+};
+
+void testCheckLocking()
+{
+  WorkspaceMemento a(ws, 0);
+  TSM_ASSERT_THROWS_NOTHING("Lock it.", a.lock());
+  TSM_ASSERT("Check it's locked", a.locked());
+  TSM_ASSERT_THROWS_NOTHING("Unlock it",  a.unlock());
+  TSM_ASSERT("Check it's unlocked", !a.locked());
+}
+
+void testDuplicateLockThrows()
+{
+  WorkspaceMemento a(ws, 0);
+  TSM_ASSERT_THROWS_NOTHING("Lock it.", a.lock());
+  TSM_ASSERT("Check it's locked", a.locked());
+
+  WorkspaceMemento b(ws, 0);
+  TSM_ASSERT_THROWS("Already locked, should throw.", b.lock(), std::runtime_error);
+
+  //Clean-up
+  a.unlock();
+  TSM_ASSERT("Check it's unlocked", !a.locked());
+}
+
+void testAutoUnlock()
+{
+  {
+  WorkspaceMemento a(ws, 0);
+  TSM_ASSERT_THROWS_NOTHING("Lock it.", a.lock());
+  TSM_ASSERT("Check it's locked", a.locked());
+  }
+  //a is out of scope, should have unlocked itself on destruction.
+
+  WorkspaceMemento b(ws, 0);
+  TSM_ASSERT_THROWS_NOTHING("Should be unlocked, so should have obtained lock without throwing!", b.lock());
+  b.unlock();
+}
+
+
+
+
+};
+
+#endif
\ No newline at end of file