diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/Axis.h b/Code/Mantid/Framework/API/inc/MantidAPI/Axis.h
index b72e9bef5d574e2a30713dbcd25349a43b1ea325..6784b7fd2393120181a07f9b8ad867c19efac4b7 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/Axis.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/Axis.h
@@ -61,7 +61,7 @@ public:
   Kernel::Unit_sptr& unit();
 
   /// Set the unit on the Axis
-  virtual void setUnit(const std::string & unit);
+  virtual const Kernel::Unit_sptr& setUnit(const std::string & unitName);
 
   /// Returns true is the axis is a Spectra axis
   virtual bool isSpectra() const{return false;}
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CoordTransform.h b/Code/Mantid/Framework/API/inc/MantidAPI/CoordTransform.h
index 62fddac4d8bb9abb2ee624431c14b0596867d25c..ea5c2d5b9f204b6cf355467e2e12a3fb2266de00 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/CoordTransform.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/CoordTransform.h
@@ -34,6 +34,7 @@ namespace API
     virtual std::string toXMLString() const = 0;
     virtual void apply(const coord_t * inputVector, coord_t * outVector) const = 0;
     virtual CoordTransform * clone() const = 0;
+    virtual std::string id() const = 0;
 
     /// Wrapper for VMD
     Mantid::Kernel::VMD applyVMD(const Mantid::Kernel::VMD & inputVector) const;
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/NullCoordTransform.h b/Code/Mantid/Framework/API/inc/MantidAPI/NullCoordTransform.h
index a81c51a4fe7e23c432b2dc3784ef59be95f0c7b4..ba556ad977d2b9be743623ad2775d6238e1c6fe8 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/NullCoordTransform.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/NullCoordTransform.h
@@ -20,6 +20,7 @@ namespace Mantid
       NullCoordTransform(size_t ndims=3);
       virtual ~NullCoordTransform();
       std::string toXMLString() const;
+      std::string id() const;
       void apply(const Mantid::coord_t * inputVector, Mantid::coord_t * outVector) const;
       virtual CoordTransform * clone() const;
 
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h b/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h
index 847b2cd83a2b57d3a99b4ea747ef4660d84479c7..968898b08ab952677379491ebb3bba34b5a7dd4f 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h
@@ -471,10 +471,7 @@ They will work as was expected for folders @ref folders-sec.
               it it necessary that it identifies who was responsible for changing 
               the file. 
 
-       @param description is an optional argument, because, as 
-              explained at @ref script-description-sec it may be already inside the 
-              file. But, if the description is given, it will be inserted to the local
-              file (if it is a script) or to the README file inside the folder.
+       @param email An string that identifies the email of the author. 
      
 
       @exception ScriptRepoException may be triggered for an attempt to publish an 
@@ -486,7 +483,7 @@ They will work as was expected for folders @ref folders-sec.
      */
     virtual void upload(const std::string & file_path, const std::string & comment,
                 const std::string & author, 
-                const std::string & description = std::string())  = 0;
+                const std::string & email)  = 0;
 
     /** Define the file patterns that will not be listed in listFiles. 
         This is important to force the ScriptRepository to not list hidden files, 
diff --git a/Code/Mantid/Framework/API/src/Axis.cpp b/Code/Mantid/Framework/API/src/Axis.cpp
index 7af21d6ac6c55953ba106e36dfebe3b13b64b0f1..e359642bb7bea112878766414a9f5525fd842a7f 100644
--- a/Code/Mantid/Framework/API/src/Axis.cpp
+++ b/Code/Mantid/Framework/API/src/Axis.cpp
@@ -59,11 +59,13 @@ Kernel::Unit_sptr& Axis::unit()
 }
 /**
 * Sets the Unit that is in use on this axis.
-* @param unit :: name of the unit as known to the UnitFactory
+* @param unitName :: name of the unit as known to the UnitFactory
+* @returns The new unit instance
 */
-void Axis::setUnit(const std::string & unit)
+const Kernel::Unit_sptr& Axis::setUnit(const std::string & unitName)
 {
-  m_unit = Mantid::Kernel::UnitFactory::Instance().create(unit);
+  m_unit = Mantid::Kernel::UnitFactory::Instance().create(unitName);
+  return unit();
 }
 
 /**
diff --git a/Code/Mantid/Framework/API/src/LogManager.cpp b/Code/Mantid/Framework/API/src/LogManager.cpp
index 5252201a069f1352bf656fdd6d39e6a8656387e7..9bd21775a9762022fd41c82c3c21255857ac6315 100644
--- a/Code/Mantid/Framework/API/src/LogManager.cpp
+++ b/Code/Mantid/Framework/API/src/LogManager.cpp
@@ -458,6 +458,12 @@ Kernel::Logger& LogManager::g_log = Kernel::Logger::get("LogManager");
   INSTANTIATE(uint32_t);
   INSTANTIATE(std::string);
   INSTANTIATE(bool);
+
+  template MANTID_API_DLL uint16_t LogManager::getPropertyValueAsType(const std::string &) const;
+  template MANTID_API_DLL std::vector<double> LogManager::getPropertyValueAsType(const std::string &) const;
+  template MANTID_API_DLL std::vector<size_t> LogManager::getPropertyValueAsType(const std::string &) const;
+  template MANTID_API_DLL std::vector<int> LogManager::getPropertyValueAsType(const std::string &) const;
+  template MANTID_API_DLL std::vector<long> LogManager::getPropertyValueAsType(const std::string &) const;
   /** @endcond */
 
 } //API namespace
diff --git a/Code/Mantid/Framework/API/src/NullCoordTransform.cpp b/Code/Mantid/Framework/API/src/NullCoordTransform.cpp
index fcdea182635ecb9aba25b08abde13e6e495fe08b..415bd5b144c4c83cef53bd152f438534e57c4dde 100644
--- a/Code/Mantid/Framework/API/src/NullCoordTransform.cpp
+++ b/Code/Mantid/Framework/API/src/NullCoordTransform.cpp
@@ -32,6 +32,15 @@ namespace Mantid
       throw std::runtime_error("Not Implemented");
     }
 
+    /**
+     * Coordinate transform id
+     * @return the type of coordinate transform
+     */
+    std::string NullCoordTransform::id() const
+    {
+      return "NullCoordTransform";
+    }
+
     /**
     Apply the transformation.
     @param inputVector : pointer to the input vector
diff --git a/Code/Mantid/Framework/API/test/ExperimentInfoTest.h b/Code/Mantid/Framework/API/test/ExperimentInfoTest.h
index 28aaff9059051ae47d5c88e2180ef149f12bb154..eeab798a5748d6b371e158394b39ca375cfd6333 100644
--- a/Code/Mantid/Framework/API/test/ExperimentInfoTest.h
+++ b/Code/Mantid/Framework/API/test/ExperimentInfoTest.h
@@ -10,6 +10,7 @@
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/NexusTestHelper.h"
 #include "MantidKernel/SingletonHolder.h"
+#include "MantidKernel/Matrix.h"
 
 
 #include "MantidTestHelpers/ComponentCreationHelper.h"
@@ -628,6 +629,43 @@ public:
     TS_ASSERT_EQUALS( parameterStr, "" );
   }
 
+  void testNexus_W_matrix()
+  {
+      NexusTestHelper th(true);
+      th.createFile("ExperimentInfoWMatrixTest.nxs");
+      ExperimentInfo ei;
+
+      DblMatrix WTransf(3,3,true);
+      // let's add some tricky stuff to w-transf
+      WTransf[0][1]=0.5;
+      WTransf[0][2]=2.5;
+      WTransf[1][0]=10.5;
+      WTransf[1][2]=12.5;
+      WTransf[2][0]=20.5;
+      WTransf[2][1]=21.5;
+
+      auto wTrVector = WTransf.getVector();
+
+      // this occurs in ConvertToMD, copy methadata
+      ei.mutableRun().addProperty("W_MATRIX",wTrVector,true);
+
+      TS_ASSERT_THROWS_NOTHING(ei.saveExperimentInfoNexus(th.file));
+
+      th.reopenFile();
+
+      ExperimentInfo other;
+      std::string InstrParameters;
+      TS_ASSERT_THROWS_NOTHING(other.loadExperimentInfoNexus(th.file,InstrParameters));
+
+      std::vector<double> wMatrRestored=other.run().getPropertyValueAsType<std::vector<double> >("W_MATRIX");
+
+      for(int i=0;i<9;i++)
+      {
+          TS_ASSERT_DELTA(wTrVector[i],wMatrRestored[i],1.e-9);
+      }
+
+  }
+
 private:
 
   void addInstrumentWithParameter(ExperimentInfo & expt, const std::string & name, const std::string & value)
diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt
index bcc5c5f73dda2af20632cb80e8d8d05c65f935bb..0eecf79a5accd2754f2368c3d51c28ed3cad7e54 100644
--- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt
+++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt
@@ -478,6 +478,7 @@ set ( TEST_FILES
 	ConvertToMatrixWorkspaceTest.h
 	ConvertToPointDataTest.h
 	ConvertUnitsTest.h
+	CopyInstrumentParametersTest.h
 	CopySampleTest.h
 	CorrectFlightPathsTest.h
 	CorrectKiKfTest.h
diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
index e592d7ad890330592c4d8bdcfa30aa25a5782111..84ec3ba4d14a073123fe9d948350a336f0c5281e 100644
--- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
+++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
@@ -61,7 +61,7 @@ namespace Algorithms
   class DLLExport GenerateEventsFilter : public API::Algorithm
   {
   public:
-    GenerateEventsFilter();
+    explicit GenerateEventsFilter();
     virtual ~GenerateEventsFilter();
     
     /// Algorithm's name for identification overriding a virtual method
@@ -83,34 +83,51 @@ namespace Algorithms
     void setFilterByTimeOnly();
     void setFilterByLogValue(std::string logname);
 
-    void processSingleValueFilter(Kernel::TimeSeriesProperty<double>* mlog, double minvalue, double maxvalue,
+    void processSingleValueFilter(double minvalue, double maxvalue,
         bool filterincrease, bool filterdecrease);
 
-    void processMultipleValueFilters(Kernel::TimeSeriesProperty<double>* mlog, double minvalue, double maxvalue,
+    void processMultipleValueFilters(double minvalue, double maxvalue,
         bool filterincrease, bool filterdecrease);
 
-    void makeFilterByValue(Kernel::TimeSeriesProperty<double>* mlog,
-        Kernel::TimeSplitterType& split, double min, double max, double TimeTolerance, bool centre,
+    void makeFilterByValue(Kernel::TimeSplitterType& split, double min, double max, double TimeTolerance, bool centre,
         bool filterIncrease, bool filterDecrease, Kernel::DateAndTime startTime, Kernel::DateAndTime stopTime,
         int wsindex);
 
-    void makeMultipleFiltersByValues(Kernel::TimeSeriesProperty<double>* mlog,
-        Kernel::TimeSplitterType& split, std::map<size_t, int> indexwsindexmap, std::vector<double> logvalueranges,
+    void makeMultipleFiltersByValues(Kernel::TimeSplitterType& split, std::map<size_t, int> indexwsindexmap, std::vector<double> logvalueranges,
         bool centre, bool filterIncrease, bool filterDecrease, Kernel::DateAndTime startTime, Kernel::DateAndTime stopTime);
 
+    void processIntegerValueFilter(Kernel::TimeSplitterType &splitters, int minvalue, int maxvalue,
+                                   bool filterIncrease, bool filterDecrease, Kernel::DateAndTime runend);
+
     size_t searchValue(std::vector<double> sorteddata, double value);
 
-    DataObjects::EventWorkspace_const_sptr mEventWS;
-    API::ISplittersWorkspace_sptr mSplitters;
-    API::ITableWorkspace_sptr mFilterInfoWS;
+    DataObjects::EventWorkspace_const_sptr m_dataWS;
+    API::ISplittersWorkspace_sptr m_splitWS;
+    API::ITableWorkspace_sptr m_filterInfoWS;
 
     Kernel::DateAndTime mStartTime;
     Kernel::DateAndTime mStopTime;
 
-    double m_convertfactor;
+    double m_timeUnitConvertFactor;
+
+    Kernel::TimeSeriesProperty<double>* m_dblLog;
+    Kernel::TimeSeriesProperty<int>* m_intLog;
+
+    bool m_logAtCentre;
+    double m_logTimeTolerance;
 
   };
 
+  /** Generate a new time splitter and add to a list of splitters
+    */
+  void make_splitter(Kernel::DateAndTime start, Kernel::DateAndTime stop, int group, Kernel::time_duration tolerance,
+                     Kernel::TimeSplitterType& splitters)
+  {
+    Kernel::SplittingInterval newsplit(start - tolerance, stop - tolerance, group);
+    splitters.push_back(newsplit);
+
+    return;
+  }
 
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp b/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
index 5e4d199849b3817babde19b0262ae40f3646173a..e6bcecf5c1e76852df3d9d524f494d177b48ae31 100644
--- a/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
@@ -47,6 +47,8 @@ using namespace Mantid;
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
 
+using namespace std;
+
 namespace Mantid
 {
 namespace Algorithms
@@ -72,13 +74,12 @@ namespace Algorithms
     this->setWikiSummary("Generate one or a set of event filters according to time or specified log's value.");
   }
 
-  /*
-   * Define input
+  //----------------------------------------------------------------------------------------------
+  /** Declare input
    */
   void GenerateEventsFilter::init()
   {
-
-    // 0. Input/Output Workspaces
+    // 1. Input/Output Workspaces
     declareProperty(
       new API::WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace", "Anonymous", Direction::Input),
       "An input event workspace" );
@@ -91,7 +92,7 @@ namespace Algorithms
                                                                      Direction::Output),
                     "Optional output for the information of each splitter workspace index");
 
-    // 1. Time
+    // 2. Time (general)
     declareProperty("StartTime", "0.0",
         "The start time, in (a) seconds, (b) nanoseconds or (c) percentage of total run time\n"
         "since the start of the run. OR (d) absolute time. \n"
@@ -102,6 +103,7 @@ namespace Algorithms
         "since the start of the run. OR (d) absolute time. \n"
         "Events at or after this time are filtered out.");
 
+    // 3. Filter by time (only)
     declareProperty("TimeInterval", -1.0,
         "Length of the time splices if filtered in time only.");
 
@@ -114,7 +116,7 @@ namespace Algorithms
                     "The unit can be second or nanosecond from run start time."
                     "They can also be defined as percentage of total run time.");
 
-    // 2. Log value
+    // 4. Filter by log value (only)
     declareProperty("LogName", "",
         "Name of the sample log to use to filter.\n"
         "For example, the pulse charge is recorded in 'ProtonCharge'.");
@@ -138,24 +140,20 @@ namespace Algorithms
     declareProperty("TimeTolerance", 0.0,
         "Tolerance in time for the event times to keep. It is used in the case to filter by single value.");
 
-    declareProperty("LogBoundary", "centre",
-        "How to treat log values as being measured in the centre of time.");
+    vector<string> logboundoptions;
+    logboundoptions.push_back("Centre");
+    logboundoptions.push_back("other");
+    auto logvalidator = boost::make_shared<StringListValidator>(logboundoptions);
+    declareProperty("LogBoundary", "Centre", logvalidator,
+                    "How to treat log values as being measured in the centre of time.");
 
     declareProperty("LogValueTolerance", EMPTY_DBL(),
         "Tolerance of the log value to be included in filter.  It is used in the case to filter by multiple values.");
 
-    /* removed due to SNS hardware
-    std::vector<std::string> logvalueoptions;
-    logvalueoptions.push_back("StepFunction");
-    logvalueoptions.push_back("LinearInterpolation");
-    declareProperty("LogValueInterpolation", "StepFunction", boost::make_shared<Kernel::StringListValidator>(logvalueoptions),
-        "How to treat the changing log value in multiple-value filtering.");
-    */
-
     declareProperty("LogValueTimeSections", 1,
         "In one log value interval, it can be further divided into sections in even time slice.");
 
-    // Output workspaces' title and name
+    // 5. Output workspaces' title and name
     declareProperty("TitleOfSplitters", "",
                     "Title of output splitters workspace and information workspace.");
 
@@ -169,8 +167,8 @@ namespace Algorithms
   void GenerateEventsFilter::exec()
   {
     // 1. Get general input and output
-    mEventWS = this->getProperty("InputWorkspace");
-    if (!mEventWS)
+    m_dataWS = this->getProperty("InputWorkspace");
+    if (!m_dataWS)
     {
       std::stringstream errss;
       errss << "GenerateEventsFilter does not get input workspace as an EventWorkspace.";
@@ -179,11 +177,12 @@ namespace Algorithms
     }
     else
     {
-      g_log.debug() << "DB9441 GenerateEventsFilter() Input Event WS = " << mEventWS->getName()
-                    << ", Events = " << mEventWS->getNumberEvents() << std::endl;
+      g_log.debug() << "DB9441 GenerateEventsFilter() Input Event WS = " << m_dataWS->getName()
+                    << ", Events = " << m_dataWS->getNumberEvents() << std::endl;
     }
 
-    Kernel::DateAndTime runstart(mEventWS->run().getProperty("run_start")->value());
+    Kernel::DateAndTime runstart = m_dataWS->run().startTime();
+    // (m_dataWS->run().getProperty("run_start")->value());
     g_log.debug() << "DB9441 Run Start = " << runstart << " / " << runstart.totalNanoseconds()
                   << std::endl;
 
@@ -195,15 +194,15 @@ namespace Algorithms
     }
 
     // Output Splitters workspace
-    mSplitters =  boost::shared_ptr<DataObjects::SplittersWorkspace>(new DataObjects::SplittersWorkspace());
-    mSplitters->setTitle(title);
+    m_splitWS =  boost::shared_ptr<DataObjects::SplittersWorkspace>(new DataObjects::SplittersWorkspace());
+    m_splitWS->setTitle(title);
 
     // mFilterInfoWS = boost::shared_ptr<DataObjects::TableWorkspace>(new DataObjects::TableWorkspace);
-    mFilterInfoWS = API::WorkspaceFactory::Instance().createTable("TableWorkspace");
-    mFilterInfoWS->setTitle(title);
+    m_filterInfoWS = API::WorkspaceFactory::Instance().createTable("TableWorkspace");
+    m_filterInfoWS->setTitle(title);
 
-    mFilterInfoWS->addColumn("int", "workspacegroup");
-    mFilterInfoWS->addColumn("str", "title");
+    m_filterInfoWS->addColumn("int", "workspacegroup");
+    m_filterInfoWS->addColumn("str", "title");
 
     // 2. Get Time
     processInputTime(runstart);
@@ -224,14 +223,15 @@ namespace Algorithms
       setFilterByLogValue(logname);
     }
 
-    this->setProperty("OutputWorkspace", mSplitters);
-    this->setProperty("InformationWorkspace", mFilterInfoWS);
+    this->setProperty("OutputWorkspace", m_splitWS);
+    this->setProperty("InformationWorkspace", m_filterInfoWS);
 
     return;
   }
 
-  /*
-   * Process the input for time.  A smart but complicated default rule
+  //----------------------------------------------------------------------------------------------
+  /** Process the input for time.  A smart but complicated default rule
+    * @param runstarttime :: run start time in sample log
    */
   void GenerateEventsFilter::processInputTime(Kernel::DateAndTime runstarttime)
   {
@@ -269,27 +269,27 @@ namespace Algorithms
       // 2. Find maximum time by proton charge
       // FIXME Use this simple method may miss the events in the last pulse
       Kernel::TimeSeriesProperty<double>* protonchargelog =
-          dynamic_cast<Kernel::TimeSeriesProperty<double> *>(mEventWS->run().getProperty("proton_charge"));
+          dynamic_cast<Kernel::TimeSeriesProperty<double> *>(m_dataWS->run().getProperty("proton_charge"));
       Kernel::DateAndTime runend = protonchargelog->lastTime();
 
       // 3. Set up time-convert unit
-      m_convertfactor = 1.0;
+      m_timeUnitConvertFactor = 1.0;
       if (timeunit.compare("Seconds") == 0)
       {
         // a) In unit of seconds
-        m_convertfactor = 1.0E9;
+        m_timeUnitConvertFactor = 1.0E9;
       }
       else if (timeunit.compare("Nanoseconds") == 0)
       {
         // b) In unit of nano-seconds
-        m_convertfactor = 1.0;
+        m_timeUnitConvertFactor = 1.0;
       }
       else if (timeunit.compare("Percent") == 0)
       {
         // c) In unit of percent of total run time
         int64_t runtime_ns = runend.totalNanoseconds()-runstarttime.totalNanoseconds();
         double runtimed_ns = static_cast<double>(runtime_ns);
-        m_convertfactor = 0.01*runtimed_ns;
+        m_timeUnitConvertFactor = 0.01*runtimed_ns;
       }
       else
       {
@@ -299,7 +299,7 @@ namespace Algorithms
       }
 
       // 4. Process second round
-      int64_t t0_ns = runstarttime.totalNanoseconds() + static_cast<int64_t>(inpt0*m_convertfactor);
+      int64_t t0_ns = runstarttime.totalNanoseconds() + static_cast<int64_t>(inpt0*m_timeUnitConvertFactor);
       Kernel::DateAndTime tmpt0(t0_ns);
       mStartTime = tmpt0;
 
@@ -309,19 +309,19 @@ namespace Algorithms
       }
       else
       {
-        int64_t tf_ns = runstarttime.totalNanoseconds()+static_cast<int64_t>(inptf*m_convertfactor);
+        int64_t tf_ns = runstarttime.totalNanoseconds()+static_cast<int64_t>(inptf*m_timeUnitConvertFactor);
         Kernel::DateAndTime tmptf(tf_ns);
         mStopTime = tmptf;
       }
     }
 
-    g_log.debug() << "DB8147 StartTime = " << mStartTime << ", StopTime = " << mStopTime << std::endl;
+    g_log.information() << "Filter: StartTime = " << mStartTime << ", StopTime = " << mStopTime << std::endl;
 
     return;
   }
 
-  /*
-   * Set splitters by time value / interval only
+  //----------------------------------------------------------------------------------------------
+  /** Set splitters by time value / interval only
    */
   void GenerateEventsFilter::setFilterByTimeOnly()
   {
@@ -336,9 +336,9 @@ namespace Algorithms
       int wsindex = 0;
       // 1. Default and thus just one interval
       Kernel::SplittingInterval ti(mStartTime, mStopTime, 0);
-      mSplitters->addSplitter(ti);
+      m_splitWS->addSplitter(ti);
 
-      API::TableRow row = mFilterInfoWS->appendRow();
+      API::TableRow row = m_filterInfoWS->appendRow();
       std::stringstream ss;
       ss << "Time Interval From " << mStartTime << " to " << mStopTime;
       row << wsindex << ss.str();
@@ -346,7 +346,7 @@ namespace Algorithms
     else
     {
       // 2. Use N time interval
-      int64_t deltatime_ns = static_cast<int64_t>(timeinterval*m_convertfactor);
+      int64_t deltatime_ns = static_cast<int64_t>(timeinterval*m_timeUnitConvertFactor);
 
       int64_t curtime_ns = mStartTime.totalNanoseconds();
       int wsindex = 0;
@@ -361,10 +361,10 @@ namespace Algorithms
         Kernel::DateAndTime t0(curtime_ns);
         Kernel::DateAndTime tf(nexttime_ns);
         Kernel::SplittingInterval spiv(t0, tf, wsindex);
-        mSplitters->addSplitter(spiv);
+        m_splitWS->addSplitter(spiv);
 
         // c) Information
-        API::TableRow row = mFilterInfoWS->appendRow();
+        API::TableRow row = m_filterInfoWS->appendRow();
         std::stringstream ss;
         ss << "Time Interval From " << t0 << " to " << tf;
         row << wsindex << ss.str();
@@ -392,42 +392,34 @@ namespace Algorithms
 
   //----------------------------------------------------------------------------------------------
   /** Generate filters by log values.
+    * @param logname :: name of the log to filter with
     */
   void GenerateEventsFilter::setFilterByLogValue(std::string logname)
   {
-    // 1. Process inputs
-    Kernel::TimeSeriesProperty<double>* mLog =
-        dynamic_cast<Kernel::TimeSeriesProperty<double>* >(mEventWS->run().getProperty(logname));
-    if (!mLog)
+    // 1. Get hold on sample log to filter with
+    m_dblLog = dynamic_cast<TimeSeriesProperty<double>* >(m_dataWS->run().getProperty(logname));
+    m_intLog = dynamic_cast<TimeSeriesProperty<int>* > (m_dataWS->run().getProperty(logname));
+    if (!m_dblLog && !m_intLog)
     {
-      g_log.error() << "Log " << logname << " does not exist or is not TimeSeriesProperty in double." << std::endl;
-      throw std::invalid_argument("User specified log is not correct");
+      stringstream errmsg;
+      errmsg << "Log " << logname << " does not exist or is not TimeSeriesProperty in double or integer.";
+      g_log.error(errmsg.str());
+      throw runtime_error(errmsg.str());
     }
 
-    // a) Clear duplicate value
-    mLog->eliminateDuplicates();
+    //  Clear duplicate value
+    if (m_dblLog)
+      m_dblLog->eliminateDuplicates();
+    else
+      m_intLog->eliminateDuplicates();
 
+    // 2. Process input properties related to filter with log value
     double minvalue = this->getProperty("MinimumLogValue");
     double maxvalue = this->getProperty("MaximumLogValue");
     double deltaValue = this->getProperty("LogValueInterval");
 
-    if (minvalue == EMPTY_DBL())
-    {
-      minvalue = mLog->minValue();
-    }
-    if (maxvalue == EMPTY_DBL())
-    {
-      maxvalue = mLog->maxValue();
-    }
-
-    if (minvalue > maxvalue)
-    {
-      g_log.error() << "Error: Input minimum log value " << minvalue <<
-          " is larger than maximum log value " << maxvalue << std::endl;
-      throw std::invalid_argument("Input minimum value is larger than maximum value");
-    }
-
-    std::string filterdirection = this->getProperty("FilterLogValueByChangingDirection");
+    // 3. Log value change direction
+    std::string filterdirection = getProperty("FilterLogValueByChangingDirection");
     bool filterIncrease;
     bool filterDecrease;
     if (filterdirection.compare("Both") == 0)
@@ -452,52 +444,122 @@ namespace Algorithms
       toProcessSingleValueFilter = true;
     }
 
-    // 2. Generate filters
-    if (toProcessSingleValueFilter)
+    // 4. Log boundary
+    string logboundary = getProperty("LogBoundary");
+    if (logboundary.compare("Centre"))
+      m_logAtCentre = true;
+    else
+      m_logAtCentre = false;
+
+    m_logTimeTolerance = getProperty("TimeTolerance");
+
+    // 5. Generate filters
+    if (m_dblLog)
     {
-      // a) Generate a filter for a single log value
-      processSingleValueFilter(mLog, minvalue, maxvalue, filterIncrease, filterDecrease);
+      // Process min/max
+      if (minvalue == EMPTY_DBL())
+      {
+        minvalue = m_dblLog->minValue();
+      }
+      if (maxvalue == EMPTY_DBL())
+      {
+        maxvalue = m_dblLog->maxValue();
+      }
+
+      if (minvalue > maxvalue)
+      {
+        stringstream errmsg;
+        errmsg << "Fatal Error: Input minimum log value " << minvalue
+               << " is larger than maximum log value " << maxvalue;
+        g_log.error(errmsg.str());
+        throw runtime_error(errmsg.str());
+      }
+
+      // Filter double value log
+      if (toProcessSingleValueFilter)
+      {
+        // a) Generate a filter for a single log value
+        processSingleValueFilter(minvalue, maxvalue, filterIncrease, filterDecrease);
+      }
+      else
+      {
+        // b) Generate filters for a series of log value
+        processMultipleValueFilters(minvalue, maxvalue, filterIncrease, filterDecrease);
+      }
     }
     else
     {
-      // b) Generate filters for a series of log value
-      processMultipleValueFilters(mLog, minvalue, maxvalue, filterIncrease, filterDecrease);
+      // Filter integer log
+      int minvaluei, maxvaluei;
+      if (minvalue == EMPTY_DBL())
+        minvaluei = m_intLog->minValue();
+      else
+        minvaluei = static_cast<int>(minvalue+0.5);
+
+      if (maxvalue == EMPTY_DBL())
+        maxvaluei = m_intLog->maxValue();
+      else
+        maxvaluei = static_cast<int>(maxvalue+0.5);
+
+      if (minvalue > maxvalue)
+      {
+        stringstream errmsg;
+        errmsg << "Fatal Error: Input minimum log value " << minvalue
+               << " is larger than maximum log value " << maxvalue;
+        g_log.error(errmsg.str());
+        throw runtime_error(errmsg.str());
+      }
+
+      TimeSplitterType splitters;
+      DateAndTime runendtime = m_dataWS->run().endTime();
+      processIntegerValueFilter(splitters, minvaluei, maxvaluei, filterIncrease, filterDecrease, runendtime);
+
+      size_t numsplits = splitters.size();
+      for (size_t i = 0; i < numsplits; ++i)
+      {
+        SplittingInterval split = splitters[i];
+        m_splitWS->addSplitter(split);
+      }
     }
 
+
     return;
   }
 
   //----------------------------------------------------------------------------------------------
   /** Generate filters by single log value
+    * @param minvalue :: minimum value of the allowed log value;
+    * @param maxvalue :: maximum value of the allowed log value;
+    * @param filterincrease :: if true, log value in the increasing curve should be included;
+    * @param filterdecrease :: if true, log value in the decreasing curve should be included;
     */
-  void GenerateEventsFilter::processSingleValueFilter(Kernel::TimeSeriesProperty<double>* mlog,
-                                                      double minvalue, double maxvalue,
+  void GenerateEventsFilter::processSingleValueFilter(double minvalue, double maxvalue,
                                                       bool filterincrease, bool filterdecrease)
   {
     // 1. Validity & value
     double timetolerance = this->getProperty("TimeTolerance");
-    int64_t timetolerance_ns = static_cast<int64_t>(timetolerance*m_convertfactor);
+    int64_t timetolerance_ns = static_cast<int64_t>(timetolerance*m_timeUnitConvertFactor);
 
     std::string logboundary = this->getProperty("LogBoundary");
-    std::transform(logboundary.begin(), logboundary.end(), logboundary.begin(), tolower);
+    transform(logboundary.begin(), logboundary.end(), logboundary.begin(), ::tolower);
 
     // 2. Generate filter
     std::vector<Kernel::SplittingInterval> splitters;
     int wsindex = 0;
-    makeFilterByValue(mlog, splitters, minvalue, maxvalue, static_cast<double>(timetolerance_ns)*1.0E-9,
+    makeFilterByValue(splitters, minvalue, maxvalue, static_cast<double>(timetolerance_ns)*1.0E-9,
         logboundary.compare("centre")==0,
         filterincrease, filterdecrease, mStartTime, mStopTime, wsindex);
 
     // 3. Add to output
     for (size_t isp = 0; isp < splitters.size(); isp ++)
     {
-      mSplitters->addSplitter(splitters[isp]);
+      m_splitWS->addSplitter(splitters[isp]);
     }
 
     // 4. Add information
-    API::TableRow row = mFilterInfoWS->appendRow();
+    API::TableRow row = m_filterInfoWS->appendRow();
     std::stringstream ss;
-    ss << "Log " << mlog->name() << " From " << minvalue << " To " << maxvalue << "  Value-change-direction ";
+    ss << "Log " << m_dblLog->name() << " From " << minvalue << " To " << maxvalue << "  Value-change-direction ";
     if (filterincrease && filterdecrease)
     {
       ss << " both ";
@@ -517,10 +579,14 @@ namespace Algorithms
 
   //----------------------------------------------------------------------------------------------
   /** Generate filters from multiple values
+    * @param minvalue :: minimum value of the allowed log value;
+    * @param maxvalue :: maximum value of the allowed log value;
+    * @param filterincrease :: if true, log value in the increasing curve should be included;
+    * @param filterdecrease :: if true, log value in the decreasing curve should be included;
    */
-  void GenerateEventsFilter::processMultipleValueFilters(Kernel::TimeSeriesProperty<double>* mlog, double minvalue,
-                                                         double maxvalue,
-                                                         bool filterincrease, bool filterdecrease)
+  void GenerateEventsFilter::processMultipleValueFilters(double minvalue, double maxvalue,
+                                                         bool filterincrease,
+                                                         bool filterdecrease)
   {
     // 1. Read more input
     double valueinterval = this->getProperty("LogValueInterval");
@@ -552,7 +618,7 @@ namespace Algorithms
 
       // Workgroup information
       std::stringstream ss;
-      ss << "Log " << mlog->name() << " From " << lowbound << " To " << upbound << "  Value-change-direction ";
+      ss << "Log " << m_dblLog->name() << " From " << lowbound << " To " << upbound << "  Value-change-direction ";
       if (filterincrease && filterdecrease)
       {
         ss << " both ";
@@ -565,7 +631,7 @@ namespace Algorithms
       {
         ss << " decrease";
       };
-      API::TableRow newrow = mFilterInfoWS->appendRow();
+      API::TableRow newrow = m_filterInfoWS->appendRow();
       newrow << wsindex << ss.str();
 
       curvalue += valueinterval;
@@ -581,28 +647,28 @@ namespace Algorithms
 
     double upperboundinterval0 = logvalueranges[1];
     double lowerboundlastinterval = logvalueranges[logvalueranges.size()-2];
-    double minlogvalue = mlog->minValue();
-    double maxlogvalue = mlog->maxValue();
+    double minlogvalue = m_dblLog->minValue();
+    double maxlogvalue = m_dblLog->maxValue();
     if (minlogvalue > upperboundinterval0 || maxlogvalue < lowerboundlastinterval)
     {
       g_log.warning() << "User specifies log interval from " << minvalue-valuetolerance
                       << " to " << maxvalue-valuetolerance << " with interval size = " << valueinterval
-                      << "; Log " << mlog->name() << " has range " << minlogvalue << " to " << maxlogvalue
+                      << "; Log " << m_dblLog->name() << " has range " << minlogvalue << " to " << maxlogvalue
                       << ".  Therefore some workgroup index may not have any splitter." << std::endl;
     }
 
     // 3. Call
     Kernel::TimeSplitterType splitters;
     std::string logboundary = this->getProperty("LogBoundary");
-    transform(logboundary.begin(), logboundary.end(), logboundary.begin(), tolower);
+    transform(logboundary.begin(), logboundary.end(), logboundary.begin(), ::tolower);
 
-    makeMultipleFiltersByValues(mlog, splitters, indexwsindexmap, logvalueranges,
+    makeMultipleFiltersByValues(splitters, indexwsindexmap, logvalueranges,
                                 logboundary.compare("centre") == 0,
                                 filterincrease, filterdecrease, mStartTime, mStopTime);
 
     // 4. Put to SplittersWorkspace
     for (size_t i = 0; i < splitters.size(); i ++)
-      mSplitters->addSplitter(splitters[i]);
+      m_splitWS->addSplitter(splitters[i]);
 
     return;
   }
@@ -614,7 +680,6 @@ namespace Algorithms
    * SINGLE log values >= min and < max. Creates SplittingInterval's where
    * times match the log values, and going to index==0.
    *
-   * @param mlog :: Log.
    * @param filterIncrease :: As log value increase, and within (min, max), include this range in the filter.
    * @param filterDecrease :: As log value increase, and within (min, max), include this range in the filter.
    * @param startTime :: Start time.
@@ -626,13 +691,12 @@ namespace Algorithms
    * @param TimeTolerance :: Offset added to times in seconds.
    * @param centre :: Whether the log value time is considered centred or at the beginning.
    */
-  void GenerateEventsFilter::makeFilterByValue(Kernel::TimeSeriesProperty<double>* mlog,
-      Kernel::TimeSplitterType& split, double min, double max, double TimeTolerance, bool centre,
-      bool filterIncrease, bool filterDecrease, Kernel::DateAndTime startTime, Kernel::DateAndTime stopTime,
-      int wsindex)
+  void GenerateEventsFilter::makeFilterByValue(TimeSplitterType &split,
+      double min, double max, double TimeTolerance, bool centre, bool filterIncrease,
+      bool filterDecrease, DateAndTime startTime, Kernel::DateAndTime stopTime, int wsindex)
   {
     // 1. Do nothing if the log is empty.
-    if (mlog->size() == 0)
+    if (m_dblLog->size() == 0)
     {
       g_log.warning() << "There is no entry in this property " << this->name() << std::endl;
       return;
@@ -648,12 +712,12 @@ namespace Algorithms
 
     size_t progslot = 0;
 
-    for (int i = 0; i < mlog->size(); i ++)
+    for (int i = 0; i < m_dblLog->size(); i ++)
     {
       lastTime = t;
       //The new entry
-      t = mlog->nthTime(i);
-      double val = mlog->nthValue(i);
+      t = m_dblLog->nthTime(i);
+      double val = m_dblLog->nthValue(i);
 
       // A good value?
       if (filterIncrease && filterDecrease)
@@ -666,14 +730,14 @@ namespace Algorithms
         if (i == 0)
           isGood = false;
         else
-          isGood = ((val >= min) && (val < max)) && t >= startTime && t <= stopTime && val-mlog->nthValue(i-1) > 0;
+          isGood = ((val >= min) && (val < max)) && t >= startTime && t <= stopTime && val-m_dblLog->nthValue(i-1) > 0;
       }
       else if (filterDecrease)
       {
         if (i == 0)
           isGood = false;
         else
-          isGood = ((val >= min) && (val < max)) && t >= startTime && t <= stopTime && val-mlog->nthValue(i-1) < 0;
+          isGood = ((val >= min) && (val < max)) && t >= startTime && t <= stopTime && val-m_dblLog->nthValue(i-1) < 0;
       }
       else
       {
@@ -708,28 +772,6 @@ namespace Algorithms
           }
           split.push_back( SplittingInterval(start, stop, wsindex) );
 
-          /*
-          if (numgood == 1)
-          {
-            //There was only one point with the value. Use the last time, - the tolerance, as the end time
-            if (centre)
-            {
-              stop = t-tol;
-              // stop = lastTime - tol;
-            }
-            else
-            {
-              stop = t;
-            }
-            split.push_back( SplittingInterval(start, stop, wsindex) );
-          }
-          else
-          {
-            //At least 2 good values. Save the end time
-            XXX XXX
-          }
-          */
-
           //Reset the number of good ones, for next time
           numgood = 0;
         }
@@ -737,7 +779,7 @@ namespace Algorithms
       }
 
       // Progress bar..
-      size_t tmpslot = i*90/mlog->size();
+      size_t tmpslot = i*90/m_dblLog->size();
       if (tmpslot > progslot)
       {
         progslot = tmpslot;
@@ -766,7 +808,6 @@ namespace Algorithms
    * SINGLE log values >= min and < max. Creates SplittingInterval's where
    * times match the log values, and going to index==0.
    *
-   * @param mlog :: Log.
    * @param split :: Splitter that will be filled.
    * @param indexwsindexmap :: Index.
    * @param logvalueranges ::  A vector of double. Each 2i and 2i+1 pair is one individual log value range.
@@ -776,9 +817,10 @@ namespace Algorithms
    * @param startTime :: Start time.
    * @param stopTime :: Stop time.
    */
-  void GenerateEventsFilter::makeMultipleFiltersByValues(Kernel::TimeSeriesProperty<double>* mlog,
-      Kernel::TimeSplitterType& split, std::map<size_t, int> indexwsindexmap, std::vector<double> logvalueranges,
-      bool centre, bool filterIncrease, bool filterDecrease, Kernel::DateAndTime startTime, Kernel::DateAndTime stopTime)
+  void GenerateEventsFilter::makeMultipleFiltersByValues(TimeSplitterType& split, map<size_t, int> indexwsindexmap,
+                                                         vector<double> logvalueranges,
+                                                         bool centre, bool filterIncrease, bool filterDecrease,
+                                                         DateAndTime startTime, DateAndTime stopTime)
   {
     // 0. Set up
     double timetolerance = 0.0;
@@ -789,9 +831,9 @@ namespace Algorithms
     time_duration tol = DateAndTime::durationFromSeconds( timetolerance );
 
     // 1. Do nothing if the log is empty.
-    if (mlog->size() == 0)
+    if (m_dblLog->size() == 0)
     {
-      g_log.warning() << "There is no entry in this property " << mlog->name() << std::endl;
+      g_log.warning() << "There is no entry in this property " << m_dblLog->name() << std::endl;
       return;
     }
 
@@ -804,7 +846,7 @@ namespace Algorithms
     double currValue = 0.0;
     size_t progslot = 0;
 
-    int logsize = mlog->size();
+    int logsize = m_dblLog->size();
 
     for (int i = 0; i < logsize; i ++)
     {
@@ -814,8 +856,8 @@ namespace Algorithms
       bool completehalf = false;
       bool newsplitter = false;
 
-      currTime = mlog->nthTime(i);
-      currValue = mlog->nthValue(i);
+      currTime = m_dblLog->nthTime(i);
+      currValue = m_dblLog->nthValue(i);
 
       // b) Filter out by time and direction (optional)
       bool intime = false;
@@ -855,7 +897,7 @@ namespace Algorithms
         {
           // Filter out one direction
           int direction = 0;
-          if ( mlog->nthValue(i)-mlog->nthValue(i-1) > 0)
+          if ( m_dblLog->nthValue(i)-m_dblLog->nthValue(i-1) > 0)
             direction = 1;
           else
             direction = -1;
@@ -1005,7 +1047,7 @@ namespace Algorithms
 
       // f) Progress
       // Progress bar..
-      size_t tmpslot = i*90/mlog->size();
+      size_t tmpslot = i*90/m_dblLog->size();
       if (tmpslot > progslot)
       {
         progslot = tmpslot;
@@ -1020,6 +1062,161 @@ namespace Algorithms
     return;
 
   }
+  //-----------------------------------------------------------------------------------------------
+  /** Generate filters for an integer log
+    * @param minvalue :: minimum allowed log value
+    * @param maxvalue :: maximum allowed log value
+    * @param filterIncrease :: include log value increasing period;
+    * @param filterDecrease :: include log value decreasing period
+    */
+  void GenerateEventsFilter::processIntegerValueFilter(TimeSplitterType& splitters, int minvalue, int maxvalue,
+                                                       bool filterIncrease, bool filterDecrease, DateAndTime runend)
+  {
+    // 1. Determine the filter mode
+    int delta = 0;
+    double singlemode;
+    if (minvalue == maxvalue)
+    {
+      singlemode = true;
+    }
+    else
+    {
+      double deltadbl = getProperty("LogValueInterval");
+      delta = static_cast<int>(deltadbl+0.5);
+      if (delta <= 0)
+        throw runtime_error("LogValueInterval cannot be 0 or negative for integer log.");
+      singlemode = false;
+    }
+
+    // 2. Search along log to generate splitters
+    size_t numlogentries = m_intLog->size();
+    vector<DateAndTime> times = m_intLog->timesAsVector();
+    vector<int> values = m_intLog->valuesAsVector();
+
+    time_duration timetol = DateAndTime::durationFromSeconds( m_logTimeTolerance*m_timeUnitConvertFactor*1.0E-9);
+
+    DateAndTime splitstarttime(0);
+    int pregroup = -1;
+
+    g_log.debug() << "[DB] Number of log entries = " << numlogentries << ".\n";
+
+    for (size_t i = 0; i < numlogentries; ++i)
+    {
+      int currvalue = values[i];
+      int currgroup = -1;
+
+      // a) Determine allowed and group
+      if (currvalue > maxvalue || currvalue < minvalue)
+      {
+        // Log value is out of range
+        g_log.debug() << "[DB] Entry[" << i << "] = " << currvalue << ": out of range. " << ".\n";
+      }
+      else if ((i == 0) || (i >= 1 && ((filterIncrease && values[i] >= values[i-1]) ||
+                                       (filterDecrease && values[i] <= values[i]))))
+      {
+        // First entry (regardless direction) and other entries considering change of value
+        if (singlemode)
+        {
+          currgroup = 0;
+        }
+        else
+        {
+          currgroup = (currvalue-minvalue)/delta;
+        }
+        g_log.debug() << "[DB] Entry[" << i << "] = " << currvalue << ": belong to group "
+                      << currgroup << ".\n";
+      }
+
+      // b) Consider to make a splitter
+      bool statuschanged;
+      if (pregroup >= 0 && currgroup < 0)
+      {
+        // i.  previous log is in allowed region.  but this one is not.  create a splitter
+        if (splitstarttime.totalNanoseconds() == 0)
+          throw runtime_error("Programming logic error.");
+        make_splitter(splitstarttime, times[i], pregroup, timetol, splitters);
+
+        splitstarttime = DateAndTime(0);
+        statuschanged = true;
+      }
+      else if (pregroup < 0 && currgroup >= 0)
+      {
+        // ii.  previous log is not allowed, but this one is.  this is the start of a new splitter
+        splitstarttime = times[i];
+        statuschanged = true;
+      }
+      else if (currgroup >= 0 && pregroup != currgroup)
+      {
+        // iii. migrated to a new region
+        if (splitstarttime.totalNanoseconds() == 0)
+          throw runtime_error("Programming logic error (1).");
+        make_splitter(splitstarttime, times[i], pregroup, timetol, splitters);
+
+        splitstarttime = times[i];
+        statuschanged = true;
+      }
+      else
+      {
+        // iv.  no need to do anything
+        statuschanged = false;
+      }
+
+      // c) Update
+      if (statuschanged)
+        pregroup = currgroup;
+    }
+
+    // 3. Create the last splitter if existing
+    if (pregroup >= 0)
+    {
+      // Last entry is in an allowed region.
+      if (splitstarttime.totalNanoseconds() == 0)
+        throw runtime_error("Programming logic error (1).");
+      make_splitter(splitstarttime, runend, pregroup, timetol, splitters);
+    }
+
+    // 4. Write to the information workspace
+    if (singlemode)
+    {
+      TableRow newrow = m_filterInfoWS->appendRow();
+      stringstream message;
+      message << m_intLog->name() << " = " << minvalue;
+      newrow << 0 << message.str();
+    }
+    else
+    {
+      int logvalue = minvalue;
+      int wsindex = 0;
+      while (logvalue <= maxvalue)
+      {
+        stringstream message;
+        if (logvalue + delta - 1 > logvalue)
+          message << m_intLog->name() << " = [" << logvalue << ", " << logvalue+delta-1 << "]";
+        else
+          message << m_intLog->name() << " = " << logvalue ;
+
+        message << ". Value change direction: ";
+        if (filterIncrease && filterDecrease)
+          message << "Both.";
+        else if (filterIncrease)
+          message << "Increasing. ";
+        else if (filterDecrease)
+          message << "Decreasing. ";
+
+        TableRow newrow = m_filterInfoWS->appendRow();
+        newrow << wsindex << message.str();
+
+        ++ wsindex;
+        logvalue += delta;
+      }
+    }
+
+    g_log.notice() << "[DB] Number of splitters = " << splitters.size()
+                   << ", Number of split info = " << m_filterInfoWS->rowCount() << ".\n";
+
+    return;
+  }
+
 
   //----------------------------------------------------------------------------------------------
   /** Do a binary search in the following list
diff --git a/Code/Mantid/Framework/Algorithms/test/CopyInstrumentParametersTest.h b/Code/Mantid/Framework/Algorithms/test/CopyInstrumentParametersTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..5501d5ddf10df740b699429046c6308500d93412
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/test/CopyInstrumentParametersTest.h
@@ -0,0 +1,131 @@
+#ifndef COPYINSTRUMENTPARAMETERSTEST_H_
+#define COPYINSTRUMENTPARAMETERSTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidDataHandling/LoadInstrument.h"
+#include "MantidAPI/IAlgorithm.h"
+#include "MantidAlgorithms/CopyInstrumentParameters.h"
+#include "MantidAPI/Workspace.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "WorkspaceCreationHelperTest.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/TableRow.h"
+#include "MantidKernel/V3D.h"
+#include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/Component.h"
+#include "MantidDataHandling/LoadEmptyInstrument.h"
+#include "MantidGeometry/Instrument/ComponentHelper.h"
+#include <stdexcept>
+
+using namespace Mantid::Algorithms;
+using namespace Mantid::API;
+using namespace Mantid::Kernel;
+using namespace Mantid::DataObjects;
+using Mantid::Geometry::IDetector_const_sptr;
+using Mantid::Geometry::IComponent_const_sptr;
+using namespace Geometry::ComponentHelper;
+
+class CopyInstrumentParametersTest : public CxxTest::TestSuite
+{
+public:
+
+  void testName()
+  {
+    TS_ASSERT_EQUALS( copyInstParam.name(), "CopyInstrumentParameters" )
+  }
+
+  void testInit()
+  {
+    copyInstParam.initialize();
+    TS_ASSERT( copyInstParam.isInitialized() )
+  }
+
+  void testExec()
+  {
+     // Create input workspace with paremeterised instrument and put into data store
+     MatrixWorkspace_sptr ws1 = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(3, 10, true);
+     const std::string wsName1("CopyInstParamWs1");
+     AnalysisDataServiceImpl & dataStore = AnalysisDataService::Instance();
+     dataStore.add(wsName1, ws1);
+     /// Create output workspace with the same base instrument and put into data store
+     MatrixWorkspace_sptr ws2 = WorkspaceFactory::Instance().create( ws1 );
+     const std::string wsName2("CopyInstParamWs2");
+     dataStore.add(wsName2, ws2);
+
+     // Set properties
+     TS_ASSERT_THROWS_NOTHING(copyInstParam.setPropertyValue("InputWorkspace", wsName1 ));
+     TS_ASSERT_THROWS_NOTHING(copyInstParam.setPropertyValue("OutputWorkspace", wsName2 ));
+     // Get instrument of input workspace and move some detectors
+     Geometry::ParameterMap *pmap;
+     pmap = &(ws1->instrumentParameters());
+     Geometry::Instrument_const_sptr instrument = ws1->getInstrument();
+     IComponent_const_sptr det1 =instrument->getDetector(1);
+     Geometry::ComponentHelper::moveComponent(*det1, *pmap, V3D(6.0,0.0,0.7), Absolute );
+     IComponent_const_sptr det2 =instrument->getDetector(2);
+     Geometry::ComponentHelper::moveComponent(*det2, *pmap, V3D(6.0,0.1,0.7), Absolute );
+
+     // Verify that a detector moved in the input workspace has not yet been moved in the output workspace
+     IDetector_const_sptr deto = ws2->getDetector(0);
+     V3D newPos = deto->getPos();
+     TS_ASSERT_DELTA( newPos.X() , 5.0, 0.0001);
+
+     // Execute Algorithm
+     TS_ASSERT_THROWS_NOTHING(copyInstParam.execute());
+     TS_ASSERT( copyInstParam.isExecuted() );
+
+     // Verify that the detectors in the output workspace have been moved as in the input workspace before execution
+     IDetector_const_sptr deto1 = ws2->getDetector(0);
+     int id1 = deto1->getID();
+     V3D newPos1 = deto1->getPos();
+     TS_ASSERT_EQUALS( id1, 1);
+     TS_ASSERT_DELTA( newPos1.X() , 6.0, 0.0001);
+     TS_ASSERT_DELTA( newPos1.Y() , 0.0, 0.0001);
+     TS_ASSERT_DELTA( newPos1.Z() , 0.7, 0.0001);
+     IDetector_const_sptr deto2 = ws2->getDetector(1);
+     int id2 = deto2->getID();
+     V3D newPos2 = deto2->getPos();
+     TS_ASSERT_EQUALS( id2, 2);
+     TS_ASSERT_DELTA( newPos2.X() , 6.0, 0.0001);
+     TS_ASSERT_DELTA( newPos2.Y() , 0.1, 0.0001);
+     TS_ASSERT_DELTA( newPos2.Z() , 0.7, 0.0001);
+
+     dataStore.remove(wsName1);
+     dataStore.remove(wsName2);
+  }
+
+  void testDifferent_BaseInstrument_Throws()
+  {
+    // Create input workspace with parameterised instrument and put into data store
+     MatrixWorkspace_sptr ws1 = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(3, 10, true);
+     const std::string wsName1("CopyInstParamWs1");
+     AnalysisDataServiceImpl & dataStore = AnalysisDataService::Instance();
+     dataStore.add(wsName1, ws1);
+     // Create output workspace with another parameterised instrument and put into data store
+     MatrixWorkspace_sptr ws2 = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(3, 10, true);
+     const std::string wsName2("CopyInstParamWs2");
+     dataStore.add(wsName2, ws2);
+
+     // Set properties
+     TS_ASSERT_THROWS_NOTHING(copyInstParam.setPropertyValue("InputWorkspace", wsName1 ));
+     TS_ASSERT_THROWS_NOTHING(copyInstParam.setPropertyValue("OutputWorkspace", wsName2 ));
+
+     // Execute Algorithm, should throw invalid argument exception
+     copyInstParam.setRethrows(true);
+     TS_ASSERT_THROWS(copyInstParam.execute(), std::invalid_argument);
+     TS_ASSERT( !copyInstParam.isExecuted() );
+
+     dataStore.remove(wsName1);
+     dataStore.remove(wsName2);
+  }
+
+private:
+  CopyInstrumentParameters copyInstParam;
+
+
+};
+
+#endif /*COPYINSTRUMENTPARAMETERSTEST_H_*/
diff --git a/Code/Mantid/Framework/Algorithms/test/GenerateEventsFilterTest.h b/Code/Mantid/Framework/Algorithms/test/GenerateEventsFilterTest.h
index c053d707eafc2fd831387d8d3d1281480f0afd6a..5e25cce6fc665f07c044c487cdbd109f400beca7 100644
--- a/Code/Mantid/Framework/Algorithms/test/GenerateEventsFilterTest.h
+++ b/Code/Mantid/Framework/Algorithms/test/GenerateEventsFilterTest.h
@@ -31,6 +31,8 @@
 using namespace Mantid;
 using namespace Mantid::Algorithms;
 using namespace Mantid::API;
+using namespace Mantid::DataObjects;
+using namespace Mantid::Kernel;
 
 using namespace std;
 
@@ -52,8 +54,8 @@ public:
     return;
   }
 
-  /*
-   * Test generation of splitters by time
+  //----------------------------------------------------------------------------------------------
+  /** Test generation of splitters by time
    */
   void test_genTime1Interval()
   {
@@ -113,8 +115,8 @@ public:
     return;
   }
 
-  /*
-   * Test generation of splitters by time
+  //----------------------------------------------------------------------------------------------
+  /** Test generation of splitters by time
    * (1) Multiple time interval
    * (2) Default start time and stop time
    */
@@ -180,8 +182,8 @@ public:
     return;
   }
 
-  /*
-   * Generate filter by log value in simple way
+  //----------------------------------------------------------------------------------------------
+  /** Generate filter by log value in simple way
    * (1) No time tolerance
    * (2) Just one
    */
@@ -238,9 +240,8 @@ public:
      return;
   }
 
-
-  /*
-   * Generate filter by log values in increasing
+  //----------------------------------------------------------------------------------------------
+  /** Generate filter by log values in increasing
    * (1) No time tolerance
    * (2) Just one
    */
@@ -297,9 +298,70 @@ public:
 
   }
 
+  //----------------------------------------------------------------------------------------------
+  /** Test to generate a set of filters against an integer log
+    */
+  void test_genFilterByIntegerLog()
+  {
+    // 1. Create input
+    DataObjects::EventWorkspace_sptr eventWS = createEventWorkspace2();
+    AnalysisDataService::Instance().addOrReplace("TestEventData2", eventWS);
+
+    // 2. Init and set property
+    GenerateEventsFilter alg;
+    alg.initialize();
+
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", "TestEventData2"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "IntLogSplitter"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InformationWorkspace", "IntLogInformation"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogName", "DummyIntLog"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("MinimumLogValue", static_cast<double>(1)));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("MaximumLogValue", static_cast<double>(10)));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogValueInterval", static_cast<double>(1)));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UnitOfTime", "Seconds"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("FilterLogValueByChangingDirection", "Both"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("TimeTolerance", 0.05));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogBoundary",  "Centre"));
+
+    // 3. Running and get result
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    // 4. Retrieve output workspaces
+    SplittersWorkspace_sptr splittersws = boost::dynamic_pointer_cast<SplittersWorkspace>(
+          AnalysisDataService::Instance().retrieve("IntLogSplitter"));
+    TS_ASSERT(splittersws);
+
+    TableWorkspace_const_sptr infows = boost::dynamic_pointer_cast<TableWorkspace>(
+          AnalysisDataService::Instance().retrieve("IntLogInformation"));
+    TS_ASSERT(infows);
+
+     // 5. Check output workspace
+     size_t numsplitters = 10;
+     TS_ASSERT_EQUALS(splittersws->getNumberSplitters(), numsplitters);
+     size_t numoutputs = 10;
+     TS_ASSERT_EQUALS(infows->rowCount(), numoutputs);
+
+     int64_t factor = static_cast<int64_t>(1.0E9+0.5);
+
+     Kernel::SplittingInterval s0 = splittersws->getSplitter(0);
+     TS_ASSERT_EQUALS(s0.start().totalNanoseconds(), 11*factor-5*factor/100);
+     TS_ASSERT_EQUALS(s0.index(), 0);
+
+     Kernel::SplittingInterval s9 = splittersws->getSplitter(9);
+     // TS_ASSERT_EQUALS(s14.start(), 3000924990);
+     // TS_ASSERT_EQUALS(s14.stop(),  3000974990);
+     TS_ASSERT_EQUALS(s9.index(), 9);
+
+     // 6. Clean
+     AnalysisDataService::Instance().remove("TestEventData2");
+     AnalysisDataService::Instance().remove("IntLogSplitter");
+     AnalysisDataService::Instance().remove("IntLogInformation");
+  }
+
 
-  /*
-   * Create an EventWorkspace including
+  //----------------------------------------------------------------------------------------------
+  /** Create an EventWorkspace including
    * (1) proton charge log from
    * (2) test log in sin function with time
    */
@@ -362,8 +424,92 @@ public:
     return eventws;
   }
 
+  //----------------------------------------------------------------------------------------------
+  /** Create an EventWorkspace containing an integer log
+    * 1. Run start  = 10  (s)
+    * 2. Run end    = 22  (s)
+    * 3. Pulse      = 0.5 (s)
+    * 4. Log change = 1   (s)
+    */
+  EventWorkspace_sptr createEventWorkspace2()
+  {
+    using namespace WorkspaceCreationHelper;
+
+    // 1. Empty workspace
+    EventWorkspace_sptr eventws =
+        WorkspaceCreationHelper::createEventWorkspaceWithFullInstrument(2, 2, true);
+
+    // 2. Run star time
+    int64_t factor = static_cast<int64_t>(1.0E9+0.5);
+    int64_t runstarttime_ns = 10*factor;
+    int64_t runstoptime_ns  = 22*factor;
+    int64_t pulsetime_ns    = 5*factor/10;
+    int64_t logduration_ns  = 1*factor;
+
+    Kernel::DateAndTime runstarttime(runstarttime_ns);
+    eventws->mutableRun().addProperty("run_start", runstarttime.toISO8601String());
+    Kernel::DateAndTime runendtime(runstoptime_ns);
+    eventws->mutableRun().addProperty("run_end", runendtime.toISO8601String());
+
+    // 3. Proton charge log
+    Kernel::TimeSeriesProperty<double> *protonchargelog =
+        new Kernel::TimeSeriesProperty<double>("proton_charge");
+    int64_t curtime_ns = runstarttime_ns;
+    while (curtime_ns <= runstoptime_ns)
+    {
+      Kernel::DateAndTime curtime(curtime_ns);
+      protonchargelog->addValue(curtime, 1.0);
+      curtime_ns += pulsetime_ns;
+    }
+    eventws->mutableRun().addProperty(protonchargelog, true);
+
+    // 4. Integer log
+    TimeSeriesProperty<int> *dummyintlog = new TimeSeriesProperty<int>("DummyIntLog");
+
+    int logstep = 1;
+    int logvalue = 0;
+    // double period = static_cast<double>(pulsetime_ns);
+    curtime_ns = runstarttime_ns;
+    while (curtime_ns < runstoptime_ns)
+    {
+      Kernel::DateAndTime curtime(curtime_ns);
+      dummyintlog->addValue(curtime, logvalue);
+
+      curtime_ns += logduration_ns;
+      logvalue += logstep;
+    }
+    eventws->mutableRun().addProperty(dummyintlog, true);
+
+    return eventws;
+  }
 
 };
 
 
 #endif /* MANTID_ALGORITHMS_GENERATEEVENTSFILTERTEST_H_ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h
index 223af86e045909c6ff291cb2251efbd2e05c4c6f..19baacd471aa727acf65dfc861c1d4785cbe93e2 100644
--- a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h
+++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h
@@ -53,14 +53,15 @@ public:
   virtual const std::string category() const { return "Crystal"; }
 
 private:
-  DataObjects::EventWorkspace_sptr inputW;  ///< A pointer to the input workspace
+  API::MatrixWorkspace_sptr inputW;  ///< A pointer to the input workspace
   API::MatrixWorkspace_sptr outputW; ///< A pointer to the output workspace
   // Overridden Algorithm methods
   void init();
   void exec();
-  std::size_t getWkspIndex(detid2index_map * pixel_to_wi, Geometry::RectangularDetector_const_sptr det,
+  std::size_t getWkspIndex(detid2index_map * pixel_to_wi, Geometry::IComponent_const_sptr comp,
                            const int x, const int y);
   void getTofRange(double &tofMin, double &tofMax, const double tofPeak, const MantidVec& tof);
+  int findPixelID(std::string bankName, int col, int row);
 
   /// Read in all the input parameters
   void retrieveProperties();
diff --git a/Code/Mantid/Framework/Crystal/src/MaskPeaksWorkspace.cpp b/Code/Mantid/Framework/Crystal/src/MaskPeaksWorkspace.cpp
index 13221346548e939d7488790794dcfea024f39e40..37461da068c1427f8a15448b6252b4cfcbd248b6 100644
--- a/Code/Mantid/Framework/Crystal/src/MaskPeaksWorkspace.cpp
+++ b/Code/Mantid/Framework/Crystal/src/MaskPeaksWorkspace.cpp
@@ -1,7 +1,7 @@
 /*WIKI* 
 
-Mask pixels in an EventWorkspace close to peak positions from a PeaksWorkspace. 
-Peaks could come from ISAW diamond stripping routine for SNAP data. Only works on EventWorkspaces and for instruments with RectangularDetector's. 
+Mask pixels in an Workspace close to peak positions from a PeaksWorkspace. 
+Peaks could come from ISAW diamond stripping routine for SNAP data. Only works on Workspaces and for instruments with RectangularDetector's. 
 
 *WIKI*/
 //----------------------------------------------------------------------
@@ -37,6 +37,7 @@ namespace Mantid
     using namespace Kernel;
     using namespace API;
     using namespace DataObjects;
+    using namespace Geometry;
     using std::string;
 
 
@@ -54,16 +55,16 @@ namespace Mantid
     void MaskPeaksWorkspace::init()
     {
 
-      declareProperty(new WorkspaceProperty<EventWorkspace>("InputWorkspace", "", Direction::Input),
+      declareProperty(new WorkspaceProperty<MatrixWorkspace>("InputWorkspace", "", Direction::Input),
                       "A workspace containing one or more rectangular area detectors. Each spectrum needs to correspond to only one pixelID (e.g. no grouping or previous calls to SumNeighbours).");
       declareProperty(new WorkspaceProperty<PeaksWorkspace>("InPeaksWorkspace", "", Direction::Input),
                       "The name of the workspace that will be created. Can replace the input workspace.");
-      declareProperty("XMin", -2, "Minimum of X (col) Range to mask peak");
-      declareProperty("XMax", 2, "Maximum of X (col) Range to mask peak");
-      declareProperty("YMin", -2, "Minimum of Y (row) Range to mask peak");
-      declareProperty("YMax", 2, "Maximum of Y (row) Range to mask peak");
-      declareProperty("TOFMin", EMPTY_DBL(), "Minimum TOF relative to peak's center TOF.");
-      declareProperty("TOFMax", EMPTY_DBL(), "Maximum TOF relative to peak's center TOF.");
+      declareProperty("XMin", -2, "Minimum of X (col) Range to mask peak relative to peak's center");
+      declareProperty("XMax", 2, "Maximum of X (col) Range to mask peak relative to peak's center");
+      declareProperty("YMin", -2, "Minimum of Y (row) Range to mask peak relative to peak's center");
+      declareProperty("YMax", 2, "Maximum of Y (row) Range to mask peak relative to peak's center");
+      declareProperty("TOFMin", EMPTY_DBL(), "Optional(all TOF if not specified): Minimum TOF relative to peak's center TOF.");
+      declareProperty("TOFMax", EMPTY_DBL(), "Optional(all TOF if not specified): Maximum TOF relative to peak's center TOF.");
     }
 
     /** Executes the algorithm
@@ -79,7 +80,7 @@ namespace Mantid
       peaksW = AnalysisDataService::Instance().retrieveWS<PeaksWorkspace>(getProperty("InPeaksWorkspace"));
 
       //To get the workspace index from the detector ID
-      detid2index_map * pixel_to_wi = inputW->getDetectorIDToWorkspaceIndexMap(true);
+      detid2index_map * pixel_to_wi = inputW->getDetectorIDToWorkspaceIndexMap(false);
       //Get some stuff from the input workspace
       Geometry::Instrument_const_sptr inst = inputW->getInstrument();
       if (!inst)
@@ -94,37 +95,36 @@ namespace Mantid
  
       // Loop over peaks
       const std::vector<Peak> & peaks = peaksW->getPeaks();
-      for ( auto peak = peaks.begin(); peak != peaks.end(); ++peak )
+      PARALLEL_FOR3(inputW,peaksW,tablews)
+      for (int i=0; i < static_cast<int>(peaks.size()); i++)
       {
+    	PARALLEL_START_INTERUPT_REGION
+    	Peak peak = peaks[i];
         // get the peak location on the detector
-        double col = peak->getCol();
-        double row = peak->getRow();
+        double col = peak.getCol();
+        double row = peak.getRow();
         int xPeak = int(col+0.5)-1;
         int yPeak = int(row+0.5)-1;
         g_log.debug() << "Generating information for peak at x=" << xPeak << " y=" << yPeak << "\n";
   
         // the detector component for the peak will have all pixels that we mask
-        const string bankName = peak->getBankName();
+        const string bankName = peak.getBankName();
+        if(bankName.compare("None") == 0) continue;
         Geometry::IComponent_const_sptr comp = inst->getComponentByName(bankName);
         if (!comp)
         {
-          throw std::invalid_argument("Component "+bankName+" does not exist in instrument");
-        }
-        Geometry::RectangularDetector_const_sptr det
-            = boost::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp);
-        if (!det)
-        {
-          throw std::invalid_argument("Component "+bankName+" is not a rectangular detector");
+        	continue;
+        	g_log.debug() << "Component "+bankName+" does not exist in instrument\n";
         }
 
         // determine the range in time-of-flight
         double x0;
         double xf;
         bool tofRangeSet(false);
-        if(xPeak < det->xpixels() && xPeak >= 0 && yPeak < det->ypixels() && yPeak >= 0)
+        size_t wi = this->getWkspIndex(pixel_to_wi, comp, xPeak, yPeak);
+        if (wi != static_cast<size_t>(EMPTY_INT()))
         { // scope limit the workspace index
-          size_t wi = this->getWkspIndex(pixel_to_wi, det, xPeak, yPeak);
-          this->getTofRange(x0, xf, peak->getTOF(), inputW->readX(wi));
+          this->getTofRange(x0, xf, peak.getTOF(), inputW->readX(wi));
           tofRangeSet = true;
         }
 
@@ -134,15 +134,13 @@ namespace Mantid
         {
           for (int iy=m_yMin; iy <= m_yMax; iy++)
           {
-            std::cout << "in inner loop " << xPeak+ix << ", " << yPeak+iy << std::endl;
             //Find the pixel ID at that XY position on the rectangular detector
-            if(xPeak+ix >= det->xpixels() || xPeak+ix < 0)continue;
-            if(yPeak+iy >= det->ypixels() || yPeak+iy < 0)continue;
-            spectra.insert(this->getWkspIndex(pixel_to_wi, det, xPeak+ix, yPeak+iy));
+            size_t wj = this->getWkspIndex(pixel_to_wi, comp, xPeak+ix, yPeak+iy);
+            if (wj == static_cast<size_t>(EMPTY_INT())) continue;
+            spectra.insert(wj);
             if (!tofRangeSet)
             { // scope limit the workspace index
-              size_t wi = this->getWkspIndex(pixel_to_wi, det, xPeak+ix, yPeak+iy);
-              this->getTofRange(x0, xf, peak->getTOF(), inputW->readX(wi));
+              this->getTofRange(x0, xf, peak.getTOF(), inputW->readX(wj));
               tofRangeSet = true;
             }
           }
@@ -152,22 +150,24 @@ namespace Mantid
         if (!tofRangeSet)
         {
           g_log.warning() << "Failed to set time-of-flight range for peak (x=" << xPeak
-                          << ", y=" << yPeak << ", tof=" << peak->getTOF() << ")\n";
+                          << ", y=" << yPeak << ", tof=" << peak.getTOF() << ")\n";
         }
         else if (spectra.empty())
         {
           g_log.warning() << "Failed to find spectra for peak (x=" << xPeak
-                          << ", y=" << yPeak << ", tof=" << peak->getTOF() << ")\n";
+                          << ", y=" << yPeak << ", tof=" << peak.getTOF() << ")\n";
           continue;
         }
         else
+        PARALLEL_CRITICAL(tablews)
         {
           // append to the table workspace
           API::TableRow newrow = tablews->appendRow();
           newrow << x0 << xf << Kernel::Strings::toString(spectra);
         }
+        PARALLEL_END_INTERUPT_REGION
       } // end loop over peaks
-
+      PARALLEL_CHECK_INTERUPT_REGION
 
       // Mask bins
       API::IAlgorithm_sptr maskbinstb = this->createChildAlgorithm("MaskBinsFromTable", 0.5, 1.0, true);
@@ -211,28 +211,52 @@ namespace Mantid
       }
     }
 
-    size_t MaskPeaksWorkspace::getWkspIndex(detid2index_map *pixel_to_wi, Geometry::RectangularDetector_const_sptr det,
+    size_t MaskPeaksWorkspace::getWkspIndex(detid2index_map *pixel_to_wi, Geometry::IComponent_const_sptr comp,
                                             const int x, const int y)
     {
-      if ( (x >= det->xpixels()) || (x < 0)     // this check is unnecessary as callers are doing it too
-           || (y >= det->ypixels()) || (y < 0)) // but just to make debugging easier
+        Geometry::RectangularDetector_const_sptr det
+            = boost::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp);
+      if(det)
       {
-        std::stringstream msg;
-        msg << "Failed to find workspace index for x=" << x << " y=" << y
-            << "(max x=" << det->xpixels() << ", max y=" << det->ypixels() << ")";
-        throw std::runtime_error(msg.str());
-      }
+		  if(x >= det->xpixels() || x < 0 || y >= det->ypixels() || y < 0) return EMPTY_INT();
+		  if ( (x >= det->xpixels()) || (x < 0)     // this check is unnecessary as callers are doing it too
+			   || (y >= det->ypixels()) || (y < 0)) // but just to make debugging easier
+		  {
+			std::stringstream msg;
+			msg << "Failed to find workspace index for x=" << x << " y=" << y
+				<< "(max x=" << det->xpixels() << ", max y=" << det->ypixels() << ")";
+			throw std::runtime_error(msg.str());
+		  }
 
-      int pixelID = det->getAtXY(x,y)->getID();
+		  int pixelID = det->getAtXY(x,y)->getID();
 
-      //Find the corresponding workspace index, if any
-      if (pixel_to_wi->find(pixelID) == pixel_to_wi->end())
+		  //Find the corresponding workspace index, if any
+		  if (pixel_to_wi->find(pixelID) == pixel_to_wi->end())
+		  {
+			std::stringstream msg;
+			msg << "Failed to find workspace index for x=" << x << " y=" << y;
+			throw std::runtime_error(msg.str());
+		  }
+		  return (*pixel_to_wi)[pixelID];
+      }
+      else
       {
-        std::stringstream msg;
-        msg << "Failed to find workspace index for x=" << x << " y=" << y;
-        throw std::runtime_error(msg.str());
+		  std::vector<Geometry::IComponent_const_sptr> children;
+		  boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(comp);
+		  asmb->getChildren(children, false);
+		  boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
+		  std::vector<Geometry::IComponent_const_sptr> grandchildren;
+		  asmb2->getChildren(grandchildren,false);
+		  int NROWS = static_cast<int>(grandchildren.size());
+		  int NCOLS = static_cast<int>(children.size());
+		  // Wish pixels and tubes start at 1 not 0
+			  if(x-1 >= NCOLS || x-1 < 0 || y-1 >= NROWS || y-1 < 0) return EMPTY_INT();
+		  std::string bankName = comp->getName();
+		  detid2index_map::const_iterator it = pixel_to_wi->find(findPixelID(bankName, x, y));
+		  if ( it == pixel_to_wi->end() ) return EMPTY_INT();
+		  return (it->second);
       }
-      return (*pixel_to_wi)[pixelID];
+      return EMPTY_INT();
     }
 
     /**
@@ -254,6 +278,31 @@ namespace Mantid
           tofMax = tofPeak + m_tofMax;
       }
     }
+  int MaskPeaksWorkspace::findPixelID(std::string bankName, int col, int row)
+  {
+          Geometry::Instrument_const_sptr Iptr = inputW->getInstrument();
+          boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName);
+          if (parent->type().compare("RectangularDetector") == 0)
+          {
+                  boost::shared_ptr<const RectangularDetector> RDet = boost::shared_dynamic_cast<
+                                        const RectangularDetector>(parent);
 
-  } // namespace Crystal
+                  boost::shared_ptr<Detector> pixel = RDet->getAtXY(col, row);
+                  return pixel->getID();
+          }
+          else
+          {
+                  std::string bankName0 = bankName;
+                  //Only works for WISH
+                  bankName0.erase(0,4);
+                  std::ostringstream pixelString;
+                  pixelString << Iptr->getName() << "/" << bankName0 << "/" <<bankName
+                  << "/tube" << std::setw(3) << std::setfill('0')<< col
+                  << "/pixel" << std::setw(4) << std::setfill('0')<< row;
+                  boost::shared_ptr<const Geometry::IComponent> component = Iptr->getComponentByName(pixelString.str());
+                  boost::shared_ptr<const Detector> pixel = boost::dynamic_pointer_cast<const Detector>(component);
+                  return pixel->getID();
+          }
+  }
+} // namespace Crystal
 } // namespace Mantid
diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt
index 568d513d07228afc41640edcb9c73f8569aafc8c..3958a443a1f393c3d3d6442b1608e46345c35b4c 100644
--- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt
+++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt
@@ -281,7 +281,7 @@ set ( INC_FILES
 )
 
 set ( TEST_FILES
-	#LoadDAETest.h
+  LoadDAETest.h
 	#LoadSNSNexusTest.h # TODO has no active tests in it
 	#Needs fixing to not rely on network. SNSLiveEventDataListenerTest.h
 	ADARAPacketTest.h
diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadDAE.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadDAE.h
index a6f007cec1563b5a98b601607ef97cd0cfd37d2e..957e8a9725374d3872ae67491ae39444e5004726 100644
--- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadDAE.h
+++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadDAE.h
@@ -8,6 +8,7 @@
 #include "MantidDataObjects/Workspace2D.h"
 #include <climits>
 #include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 //----------------------------------------------------------------------
 // Forward declaration
@@ -64,7 +65,7 @@ namespace Mantid
     File change history is stored at: <https://github.com/mantidproject/mantid>. 
     Code Documentation is available at: <http://doxygen.mantidproject.org>
     */
-    class DLLExport LoadDAE : public API::Algorithm
+    class DLLExport LoadDAE : public API::Algorithm, public API::DeprecatedAlgorithm
     {
     public:
       /// Default constructor
@@ -76,7 +77,7 @@ namespace Mantid
       /// Algorithm's version for identification overriding a virtual method
       virtual int version() const { return 1; }
       /// Algorithm's category for identification overriding a virtual method
-      virtual const std::string category() const { return "DataHandling\\DataAcquisition"; }
+      virtual const std::string category() const { return "Deprecated"; }
       /// Personal wrapper for sqrt to allow msvs to compile
       static double dblSqrt(double in);
 
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadDAE.cpp b/Code/Mantid/Framework/DataHandling/src/LoadDAE.cpp
index f294cd1f79d4d9b2e37c0344b31e1a83b9509003..ebc8b9a41c1a21c93cc4f74e930abc88237cf4fe 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadDAE.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadDAE.cpp
@@ -60,7 +60,10 @@ namespace Mantid
     LoadDAE::LoadDAE() :
       Algorithm(), m_daename(""), m_numberOfSpectra(0), m_numberOfPeriods(0),
       m_list(false), m_interval(false), m_spec_list(), m_spec_min(0), m_spec_max(Mantid::EMPTY_INT()),m_firstRun(true)
-    {}
+    {
+        this->useAlgorithm("StartLiveData");
+        this->deprecatedDate("2013-04-22");
+    }
 
 
     /// load data from the DAE
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp
index 179cbe15911340d6a08361b5055c928cd18d8df2..b3357c27784c25870ae8637296663a31c118cb58 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp
@@ -2,7 +2,7 @@
 
 The LoadEventNeXus algorithm loads data from an EventNexus file into an [[EventWorkspace]]. The default histogram bin boundaries consist of a single bin able to hold all events (in all pixels), and will have their [[units]] set to time-of-flight. Since it is an [[EventWorkspace]], it can be rebinned to finer bins with no loss of data.
 
-Sample logs, such as motor positions or e.g. temperature vs time, are also loaded using the [[LoadLogsFromSNSNexus]] child algorithm.
+Sample logs, such as motor positions or e.g. temperature vs time, are also loaded using the [[LoadNexusLogs]] child algorithm.
 
 === Optional properties ===
 
@@ -1938,90 +1938,90 @@ BankPulseTimes * LoadEventNexus::runLoadNexusLogs(const std::string &nexusfilena
  */
 void LoadEventNexus::deleteBanks(API::MatrixWorkspace_sptr workspace, std::vector<std::string> bankNames)
 {
-	Instrument_sptr inst = boost::const_pointer_cast<Instrument>(workspace->getInstrument()->baseInstrument());
-	//Build a list of Rectangular Detectors
-	std::vector<boost::shared_ptr<RectangularDetector> > detList;
-	for (int i=0; i < inst->nelements(); i++)
-	{
-	  boost::shared_ptr<RectangularDetector> det;
-	  boost::shared_ptr<ICompAssembly> assem;
-	  boost::shared_ptr<ICompAssembly> assem2;
-
-	  det = boost::dynamic_pointer_cast<RectangularDetector>( (*inst)[i] );
-	  if (det)
-	  {
-		detList.push_back(det);
-	  }
-	  else
-	  {
-		//Also, look in the first sub-level for RectangularDetectors (e.g. PG3).
-		// We are not doing a full recursive search since that will be very long for lots of pixels.
-		assem = boost::dynamic_pointer_cast<ICompAssembly>( (*inst)[i] );
-		if (assem)
-		{
-		  for (int j=0; j < assem->nelements(); j++)
-		  {
-			det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem)[j] );
-			if (det)
-			{
-			  detList.push_back(det);
-
-			}
-			else
-			{
-			  //Also, look in the second sub-level for RectangularDetectors (e.g. PG3).
-			  // We are not doing a full recursive search since that will be very long for lots of pixels.
-			  assem2 = boost::dynamic_pointer_cast<ICompAssembly>( (*assem)[j] );
-			  if (assem2)
-			  {
-				for (int k=0; k < assem2->nelements(); k++)
-				{
-				  det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem2)[k] );
-				  if (det)
-				  {
-					detList.push_back(det);
-				  }
-				}
-			  }
-			}
-		  }
-		}
-	  }
-	}
+    Instrument_sptr inst = boost::const_pointer_cast<Instrument>(workspace->getInstrument()->baseInstrument());
+    //Build a list of Rectangular Detectors
+    std::vector<boost::shared_ptr<RectangularDetector> > detList;
+    for (int i=0; i < inst->nelements(); i++)
+    {
+      boost::shared_ptr<RectangularDetector> det;
+      boost::shared_ptr<ICompAssembly> assem;
+      boost::shared_ptr<ICompAssembly> assem2;
+
+      det = boost::dynamic_pointer_cast<RectangularDetector>( (*inst)[i] );
+      if (det)
+      {
+        detList.push_back(det);
+      }
+      else
+      {
+        //Also, look in the first sub-level for RectangularDetectors (e.g. PG3).
+        // We are not doing a full recursive search since that will be very long for lots of pixels.
+        assem = boost::dynamic_pointer_cast<ICompAssembly>( (*inst)[i] );
+        if (assem)
+        {
+          for (int j=0; j < assem->nelements(); j++)
+          {
+            det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem)[j] );
+            if (det)
+            {
+              detList.push_back(det);
+
+            }
+            else
+            {
+              //Also, look in the second sub-level for RectangularDetectors (e.g. PG3).
+              // We are not doing a full recursive search since that will be very long for lots of pixels.
+              assem2 = boost::dynamic_pointer_cast<ICompAssembly>( (*assem)[j] );
+              if (assem2)
+              {
+                for (int k=0; k < assem2->nelements(); k++)
+                {
+                  det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem2)[k] );
+                  if (det)
+                  {
+                    detList.push_back(det);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
     if (detList.size() == 0) return;
-	for (int i = 0; i<static_cast<int>(detList.size()); i++)
-	{
-		bool keep = false;
-	    boost::shared_ptr<RectangularDetector> det = detList[i];
-	    std::string det_name = det->getName();
-		for (int j = 0; j<static_cast<int>(bankNames.size()); j++)
-		{
-		    size_t pos = bankNames[j].find("_events");
-			if(det_name.compare(bankNames[j].substr(0,pos)) == 0) keep = true;
-			if(keep) break;
-		}
-		if (!keep)
-		{
-			boost::shared_ptr<const IComponent> parent = inst->getComponentByName(det_name);
-			std::vector<Geometry::IComponent_const_sptr> children;
-			boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
-			asmb->getChildren(children, false);
-	        for (int col = 0; col<static_cast<int>(children.size()); col++)
-	        {
-				boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[col]);
-				std::vector<Geometry::IComponent_const_sptr> grandchildren;
-				asmb2->getChildren(grandchildren,false);
-
-				for (int row = 0; row<static_cast<int>(grandchildren.size()); row++)
-				{
-					Detector* d = dynamic_cast<Detector*>(const_cast<IComponent*>(grandchildren[row].get()));
-					inst->removeDetector(d);
-				}
-	        }
-			IComponent* comp = dynamic_cast<IComponent*>(detList[i].get());
-			inst->remove(comp);
-		}
-	}
+    for (int i = 0; i<static_cast<int>(detList.size()); i++)
+    {
+        bool keep = false;
+        boost::shared_ptr<RectangularDetector> det = detList[i];
+        std::string det_name = det->getName();
+        for (int j = 0; j<static_cast<int>(bankNames.size()); j++)
+        {
+            size_t pos = bankNames[j].find("_events");
+            if(det_name.compare(bankNames[j].substr(0,pos)) == 0) keep = true;
+            if(keep) break;
+        }
+        if (!keep)
+        {
+            boost::shared_ptr<const IComponent> parent = inst->getComponentByName(det_name);
+            std::vector<Geometry::IComponent_const_sptr> children;
+            boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
+            asmb->getChildren(children, false);
+            for (int col = 0; col<static_cast<int>(children.size()); col++)
+            {
+                boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[col]);
+                std::vector<Geometry::IComponent_const_sptr> grandchildren;
+                asmb2->getChildren(grandchildren,false);
+
+                for (int row = 0; row<static_cast<int>(grandchildren.size()); row++)
+                {
+                    Detector* d = dynamic_cast<Detector*>(const_cast<IComponent*>(grandchildren[row].get()));
+                    inst->removeDetector(d);
+                }
+            }
+            IComponent* comp = dynamic_cast<IComponent*>(detList[i].get());
+            inst->remove(comp);
+        }
+    }
       return;
 }
 //-----------------------------------------------------------------------------
diff --git a/Code/Mantid/Framework/DataHandling/test/LoadDAETest.h b/Code/Mantid/Framework/DataHandling/test/LoadDAETest.h
index fe5bba2740ae3e20d0f68444e2d045f41bebe923..ef7884d632b0c4007671cdbbef048d18c5e6da3c 100644
--- a/Code/Mantid/Framework/DataHandling/test/LoadDAETest.h
+++ b/Code/Mantid/Framework/DataHandling/test/LoadDAETest.h
@@ -4,193 +4,30 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/LoadDAE.h"
-#include "MantidAPI/WorkspaceFactory.h"
-#include "MantidDataObjects/ManagedWorkspace2D.h"
-#include "MantidAPI/AnalysisDataService.h"
-#include "MantidAPI/FrameworkManager.h"
-#include "MantidKernel/ConfigService.h"
-#include "MantidKernel/TimeSeriesProperty.h"
 
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <netdb.h>
-#include <arpa/inet.h>
-#endif
-
-using namespace Mantid::API;
-using namespace Mantid::Kernel;
 using namespace Mantid::DataHandling;
-using namespace Mantid::DataObjects;
 
 class LoadDAETest : public CxxTest::TestSuite
 {
-private:
-  // Function to determine whether we're running test at RAL or not
-  // because it won't work anywhere else
-  bool atRAL()
-  {
-    char ac[80];
-    if (gethostname(ac, sizeof(ac)) == -1) {
-      // On failure assume outside of RAL
-      return 0;
-    }
-
-    struct hostent *phe = gethostbyname(ac);
-    if (phe == 0) {
-      // On failure assume outside of RAL
-      return 0;
-    }
-
-    for (int i = 0; phe->h_addr_list[i] != 0; ++i) {
-      struct in_addr addr;
-      memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
-      const std::string ip(inet_ntoa(addr));
-      if (ip.find("130.246")==0) return 1;  // Yes, we're at RAL!
-    }
-
-    return 0;
-  }
-
 public:
 
   static LoadDAETest *createSuite() { return new LoadDAETest(); }
   static void destroySuite(LoadDAETest *suite) { delete suite; }
 
-  LoadDAETest()
-  {
-    // Hostname of computer with DAE to connect to
-    m_inputDAE="ndw714.isis.cclrc.ac.uk";
-    //m_inputDAE="isis53147.nd.rl.ac.uk";
-  }
-
   void testInit()
   {
-    TS_ASSERT_THROWS_NOTHING( m_loader.initialize());
-    TS_ASSERT( m_loader.isInitialized() );
+    LoadDAE loader;
+    TS_ASSERT_THROWS_NOTHING( loader.initialize());
+    TS_ASSERT( loader.isInitialized() );
   }
 
-  void testExec()
+  void testDeprecated()
   {
-
-#ifdef _WIN32
-    WSADATA wsaData;
-    WSAStartup(MAKEWORD(2,2), &wsaData);
-#endif
-
-    if ( !m_loader.isInitialized() ) m_loader.initialize();
-
-    // Set inputs
-    TS_ASSERT_THROWS_NOTHING(m_loader.setPropertyValue("DAEname", m_inputDAE));
-    TS_ASSERT_THROWS_NOTHING(m_loader.setPropertyValue("SpectrumMin", "1"));
-    TS_ASSERT_THROWS_NOTHING(m_loader.setPropertyValue("SpectrumMax", "2"));
-
-    m_outputSpace = "DAEouter";
-    TS_ASSERT_THROWS_NOTHING(m_loader.setPropertyValue("OutputWorkspace", m_outputSpace));
-
-    std::string result;
-    TS_ASSERT_THROWS_NOTHING( result = m_loader.getPropertyValue("DAEname") );
-    TS_ASSERT( ! result.compare(m_inputDAE));
-
-    // Only do the rest if the test is being run on a machine at RAL,
-    // because it will fail if you're anywhere else 
-    // (can't reach the machine where the DAE instance is running)
-    if ( atRAL() )
-    {
-
-      TS_ASSERT_THROWS_NOTHING(m_loader.execute());
-      TS_ASSERT_EQUALS( m_loader.isExecuted(),true);
-
-      // Get back the saved workspace
-      Workspace_sptr output;
-      TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieve(m_outputSpace));
-      if (output != 0)
-      {
-	Workspace2D_sptr output2D = boost::dynamic_pointer_cast<Workspace2D>(output);
-
-	// As we are checking a live DAE, we cannot be sure what we will see
-	// as setup will change with experiments. All we can do is test
-	// things that must always be true irrespective of setup
-
-	// check number of spectra returned
-	TS_ASSERT_EQUALS( output2D->getNumberHistograms(), 2);
-
-	// Check two X vectors are the same
-	TS_ASSERT( (output2D->dataX(0)) == (output2D->dataX(1)) );
-
-	// Check two Y arrays have the same number of elements
-	TS_ASSERT_EQUALS( output2D->dataY(0).size(), output2D->dataY(1).size() );
-
-	// Check the unit has been set correctly
-	TS_ASSERT_EQUALS( output2D->getAxis(0)->unit()->unitID(), "TOF" );
-	TS_ASSERT( ! output2D-> isDistribution() );
-      }
-    }
+    LoadDAE loader;
+    TS_ASSERT( dynamic_cast<Mantid::API::DeprecatedAlgorithm*>(&loader) );
+    TS_ASSERT_EQUALS(loader.deprecationMsg(&loader), "LoadDAE is deprecated (on 2013-04-22). Use StartLiveData instead.");
   }
 
-//  void testExecMultiPeriod()
-//  {
-//
-//#ifdef _WIN32
-//    WSADATA wsaData;
-//    WSAStartup(MAKEWORD(2,2), &wsaData);
-//#endif
-//
-//	    if ( !m_loader.isInitialized() ) m_loader.initialize();
-//
-//    // Should fail because mandatory parameter has not been set
-//   // TS_ASSERT_THROWS(m_loader.execute(),std::runtime_error);
-//
-//	m_inputDAE="ndxcrisp";
-//    // Set inputs
-//    m_loader.setPropertyValue("DAEname", m_inputDAE);
-//    m_loader.setPropertyValue("SpectrumMin", "1");
-//    m_loader.setPropertyValue("SpectrumMax", "2");
-//
-//    m_outputSpace = "DAEouter";
-//    m_loader.setPropertyValue("OutputWorkspace", m_outputSpace);
-//
-//    std::string result;
-//    TS_ASSERT_THROWS_NOTHING( result = m_loader.getPropertyValue("DAEname") )
-//    TS_ASSERT( ! result.compare(m_inputDAE));
-//
-//    TS_ASSERT_THROWS_NOTHING(m_loader.execute());
-//    TS_ASSERT_EQUALS( m_loader.isExecuted(),true);
-//
-//	WorkspaceGroup_sptr outgrp;
-//	 TS_ASSERT_THROWS_NOTHING(outgrp =boost::dynamic_pointer_cast<WorkspaceGroup> (AnalysisDataService::Instance().retrieve(m_outputSpace)));
-//    // Get back the saved workspace
-//    Workspace_sptr output;
-//    TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieve(m_outputSpace+"_1"));
-//    if (output != 0)
-//    {
-//      Workspace2D_sptr output2D = boost::dynamic_pointer_cast<Workspace2D>(output);
-//
-//      // As we are checking a live DAE, we cannot be sure what we will see
-//      // as setup will change with experiments. All we can do is test
-//      // things that must always be true irrespective of setup
-//
-//      // check number of spectra returned
-//      TS_ASSERT_EQUALS( output2D->getNumberHistograms(), 4);
-//
-//      // Check two X vectors are the same
-//      TS_ASSERT( (output2D->dataX(0)) == (output2D->dataX(1)) );
-//
-//      // Check two Y arrays have the same number of elements
-//      TS_ASSERT_EQUALS( output2D->dataY(0).size(), output2D->dataY(1).size() );
-//
-//      // Check the unit has been set correctly
-//      TS_ASSERT_EQUALS( output2D->getAxis(0)->unit()->unitID(), "TOF" )
-//        TS_ASSERT( ! output2D-> isDistribution() )
-//    }
-//	 Workspace_sptr output2;
-//     TS_ASSERT_THROWS_NOTHING(output2 = AnalysisDataService::Instance().retrieve(m_outputSpace+"_2"));
-//  }
-
-private:
-  LoadDAE m_loader;
-  std::string m_inputDAE;
-  std::string m_outputSpace;
 };
 
 #endif /*LOADDAETEST_H_*/
diff --git a/Code/Mantid/Framework/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt
index 96d3beb6fe4c7b778ca3466009d408e7d721d9e1..b766f298a4782b8885ca566591d05c1cd194c27e 100644
--- a/Code/Mantid/Framework/Kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt
@@ -383,6 +383,7 @@ set ( PYTHONALG_DIRS "${MANTID_ROOT}/Framework/PythonAPI/PythonAlgorithms;${MANT
 set ( PYTHONPLUGIN_DIRS "${MANTID_ROOT}/Framework/PythonAPI/PythonAlgorithms;${MANTID_ROOT}/Framework/PythonInterface/plugins" )
 set ( DATADIRS ${MANTID_ROOT}/../../Test/AutoTestData;${MANTID_ROOT}/instrument )
 set ( COLORMAPS_FOLDER ${MANTID_ROOT}/Installers/colormaps/ )
+SET ( MANTIDPUBLISHER "http://upload.mantidproject.org/scriptrepository/payload/publish_debug" )
 
 # Construct script paths.
 set ( MANTID_SCRIPTS ${MANTID_ROOT}/scripts )
@@ -456,6 +457,7 @@ set ( PLUGINS ${MANTID_ROOT}/plugins )
 set ( PYTHONALG_DIRS ${PLUGINS}/PythonAlgs ) # deprecated
 set ( PYTHONPLUGIN_DIRS ${PLUGINS}/python )
 set ( DATADIRS "" )
+SET ( MANTIDPUBLISHER "http://upload.mantidproject.org/scriptrepository/payload/publish" )
 
 # Construct script paths by replacing the old MANTID_ROOT with the new one.
 # Unfortunately string (REGEX REPLACE ... )removes the semi-colons so we have to do this in a loop.
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
index 56b1cdd7fc1b227196565e1b9f7c4589caa4a45a..a1ff88242718a1853abe7c417d858da958a21b8e 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
@@ -82,8 +82,6 @@ public:
   std::vector<InstrumentInfo> instruments(const std::string& tech) const;
   /// Returns instruments with given name
   const InstrumentInfo & instrument(std::string iName = "") const;
-  /// Returns the proxy string related to ScriptRepository settings for its installation.
-  const std::string & getHTTPProxy() const {return m_HTTPProxy;}
 
 private:
   void fillZeroPadding(const Poco::XML::Element* elem);
@@ -94,7 +92,6 @@ private:
   void fillCatalogName(const Poco::XML::Element* elem);
   void fillInstruments(const Poco::XML::Element* elem);
   void fillLiveListener(const Poco::XML::Element* elem);
-  void fillHTTPProxy(const Poco::XML::Element* elem);
 
   /// Add new extension
   void addExtension(const std::string& ext);
@@ -108,7 +105,6 @@ private:
   std::vector<InstrumentInfo> m_instruments;   ///< list of instruments of this facility
   std::string m_catalogName;                   ///< name of the catalog system of this facility
   std::string m_liveListener;                  ///< name of the default live listener
-  std::string m_HTTPProxy;                     ///< name of the default httpProxy
   static Logger& g_log;                        ///< logger
 };
 
diff --git a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
index 10e43961db873c4a947da0cad5e3599d1411231a..d7261f5761831c3b15510954ae482643c46456d8 100644
--- a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
+++ b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
@@ -28,8 +28,7 @@ Logger& FacilityInfo::g_log(Logger::get("FacilityInfo"));
   */
 FacilityInfo::FacilityInfo(const Poco::XML::Element* elem) : 
   m_name(elem->getAttribute("name")), m_zeroPadding(0), m_delimiter(), m_extensions(),
-  m_soapEndPoint(), m_archiveSearch(), m_instruments(), m_catalogName(), m_liveListener(),
-  m_HTTPProxy()
+  m_soapEndPoint(), m_archiveSearch(), m_instruments(), m_catalogName(), m_liveListener()
 {
   if (m_name.empty())
   {
@@ -45,7 +44,6 @@ FacilityInfo::FacilityInfo(const Poco::XML::Element* elem) :
   fillArchiveNames(elem);
   fillCatalogName(elem);
   fillLiveListener(elem);
-  fillHTTPProxy(elem);
   fillInstruments(elem); // Make sure this is last as it picks up some defaults that are set above
 }
 
@@ -203,18 +201,6 @@ void FacilityInfo::fillLiveListener(const Poco::XML::Element* elem)
   }
 }
 
-/// Called from constructor to fill HTTP proxy name
-void FacilityInfo::fillHTTPProxy(const Poco::XML::Element* elem)
-{
-  // Get the first HTTP proxy element (will be NULL if there's none)
-  Element * proxy = elem->getChildElement("httpproxy");
-  if ( proxy )
-  {
-    // Get the name of the HTTP proxy - empty string will be returned if missing
-    m_HTTPProxy = proxy->getAttribute("url");
-  }
-}
-
 /**
   * Returns instrument with given name
   * @param  iName Instrument name
diff --git a/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h b/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h
index d1e8e2cebb8800af6c69902d1f4814713008dbd2..731f6bef95584f00907729694a90924bfd0d8345 100644
--- a/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h
+++ b/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h
@@ -76,7 +76,6 @@ public:
     TS_ASSERT_EQUALS( fac->extensions()[0],".xyz" );
     TS_ASSERT_EQUALS( fac->preferredExtension(), ".xyz" );
     TS_ASSERT( fac->getSoapEndPoint().empty() );
-    TS_ASSERT( fac->getHTTPProxy().empty() );
     TS_ASSERT( fac->catalogName().empty() );
     TS_ASSERT( fac->archiveSearch().empty() );
     TS_ASSERT( fac->liveListener().empty() );
diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h
index 9c0fcd8f17e3b0d6e2d3b7edc44a4fd7ad35e890..f87af0838d8256dad499f0e9054297f4c229c519 100644
--- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h
+++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h
@@ -68,19 +68,20 @@ namespace MDAlgorithms
     void exec();
    /// Sets documentation strings for this algorithm
     virtual void initDocs();  
-   /// the pointer to class which keeps output MD workspace and is responsible for adding data to N-dimensional workspace;
-   boost::shared_ptr<MDEvents::MDEventWSWrapper> m_OutWSWrapper;
    /// progress reporter
    boost::scoped_ptr<API::Progress > m_Progress;
-   /// pointer to the class, which does the particular conversion
-   boost::shared_ptr<MDEvents::ConvToMDBase> m_Convertor; 
  
   /// logger -> to provide logging, for MD dataset file operations
    static Mantid::Kernel::Logger& g_Log;
    //------------------------------------------------------------------------------------------------------------------------------------------
    protected: //for testing, otherwise private:
+      /// the pointer to class which keeps output MD workspace and is responsible for adding data to N-dimensional workspace;
+      boost::shared_ptr<MDEvents::MDEventWSWrapper> m_OutWSWrapper;
        /// pointer to the input workspace;
       Mantid::API::MatrixWorkspace_sptr m_InWS2D;
+      /// pointer to the class, which does the particular conversion
+      boost::shared_ptr<MDEvents::ConvToMDBase> m_Convertor; 
+
 
        static Mantid::Kernel::Logger & getLogger();
 
@@ -92,8 +93,8 @@ namespace MDAlgorithms
 
         bool buildTargetWSDescription(API::IMDEventWorkspace_sptr spws,const std::string &Q_mod_req,const std::string &dEModeRequested,const std::vector<std::string> &other_dim_names,
                                       const std::string &convert_to_,MDEvents::MDWSDescription &targWSDescr);
-       /// Store metadata
-       void copyMetaData(API::IMDEventWorkspace_sptr mdEventWS) const;
+       /// Store metadata and set some methadata, needed for plugin to run on the target workspace description
+       void copyMetaData(API::IMDEventWorkspace_sptr mdEventWS,MDEvents::MDWSDescription &targWSDescr) const;
 
        // 
        DataObjects::TableWorkspace_const_sptr preprocessDetectorsPositions( Mantid::API::MatrixWorkspace_const_sptr InWS2D,const std::string &dEModeRequested,bool updateMasks);
diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
index 538f8d41784544af017c7efc316547b5c1dc5ef8..e2cb4b745a6526dc49e2546289d6ff458616740e 100644
--- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
+++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
@@ -74,6 +74,11 @@ namespace MDAlgorithms
 
     void loadDimensions();
 
+    /// Load all the affine matricies
+    void loadAffineMatricies(API::IMDWorkspace_sptr ws);
+    /// Load a given affine matrix
+    API::CoordTransform *loadAffineMatrix(std::string entry_name);
+
     /// Open file handle
     ::NeXus::File * file;
 
diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD.h
index 483fdcfbf95ad7c2b77baa0c1878f2a09825c896..292b1dd7be324c43d18b34dae653d55b1527dd5b 100644
--- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD.h
+++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD.h
@@ -7,6 +7,7 @@
 
 namespace Mantid
 {
+
 namespace MDAlgorithms
 {
 
@@ -63,6 +64,17 @@ namespace MDAlgorithms
     /// Save the MDHistoWorkspace.
     void doSaveHisto(Mantid::MDEvents::MDHistoWorkspace_sptr ws);
 
+    /// Save all the affine matricies
+    void saveAffineTransformMatricies(::NeXus::File * const file,
+                                      API::IMDWorkspace_const_sptr ws);
+    /// Save a given affine matrix
+    void saveAffineTransformMatrix(::NeXus::File * const file,
+                                   API::CoordTransform *transform,
+                                   std::string entry_name);
+    /// Save a generic matrix
+    template<typename T>
+    void saveMatrix(::NeXus::File * const file, std::string name,
+                    Kernel::Matrix<T> &m, ::NeXus::NXnumtype type, std::string tag="");
   };
 
 
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp
index 22e20215dd5959a2190d86337c4d7d9966b72ea4..429025b89acc51a928cdf62d19fcaad1bb8cb0c8 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp
@@ -370,7 +370,9 @@ void ConvertToMD::exec()
     else // setup existing MD workspace as workspace target.
        m_OutWSWrapper->setMDWS(spws);
  
-    // preprocess detectors;
+    // copy the necessary methadata and get the unique number, that identifies the run, the source workspace came from.
+    copyMetaData(spws,targWSDescr);
+     // preprocess detectors;
     targWSDescr.m_PreprDetTable = this->preprocessDetectorsPositions(m_InWS2D,dEModReq,getProperty("UpdateMasks"));
 
  
@@ -386,7 +388,7 @@ void ConvertToMD::exec()
 
      g_log.information()<<" conversion started\n";
      m_Convertor->runConversion(m_Progress.get());
-     copyMetaData(spws);
+  
 
      //JOB COMPLETED:
      setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDEventWorkspace>(spws));
@@ -400,12 +402,24 @@ void ConvertToMD::exec()
 /**
  * Copy over the metadata from the input matrix workspace to output MDEventWorkspace
  * @param mdEventWS :: The output MDEventWorkspace
+ * @param targWSDescr :: The descrition of the target workspace, used in the algorithm 
+ *
+ * @return  :: the number of experiment info added from the current MD workspace
  */
-void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr mdEventWS) const
+void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr mdEventWS, MDEvents::MDWSDescription &targWSDescr) const
 {
+ // Copy ExperimentInfo (instrument, run, sample) to the output WS
+  API::ExperimentInfo_sptr ei(m_InWS2D->cloneExperimentInfo());
+
+  ei->mutableRun().addProperty("RUBW_MATRIX",targWSDescr.m_Wtransf.getVector(),true);
+  ei->mutableRun().addProperty("W_MATRIX",targWSDescr.getPropertyValueAsType<std::vector<double> >("W_MATRIX"),true);
+
+  uint16_t runIndex = mdEventWS->addExperimentInfo(ei);
+
   const MantidVec & binBoundaries = m_InWS2D->readX(0);
   auto mapping = m_InWS2D->spectraMap().createIDGroupsMap();
 
+
   uint16_t nexpts = mdEventWS->getNumExperimentInfo();
   for(uint16_t i = 0; i < nexpts; ++i)
   {
@@ -413,6 +427,10 @@ void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr mdEventWS) const
     expt->mutableRun().storeHistogramBinBoundaries(binBoundaries);
     expt->cacheDetectorGroupings(*mapping);
   }
+
+ // and add it to the target workspace description for further usage as identifier for the workspaces, which come from this run. 
+   targWSDescr.addProperty("RUN_INDEX",runIndex,true);
+  
 }
 
 /** Constructor */
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp
index d4bf79c5f50c4270bee84ad47ee32cbee0b7594f..3c032951e077c79858b32e5b0261bf76138de67a 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp
@@ -35,6 +35,7 @@ and used by other algorithms, they should not be needed in daily use.
 #include "MantidMDEvents/MDBoxFlatTree.h"
 #include "MantidMDEvents/MDHistoWorkspace.h"
 #include "MantidMDEvents/BoxControllerNeXusIO.h"
+#include "MantidMDEvents/CoordTransformAffine.h"
 #include <nexus/NeXusException.hpp>
 #include <boost/algorithm/string.hpp>
 #include <vector>
@@ -165,10 +166,74 @@ namespace Mantid
 
 
 
+    //----------------------------------------------------------------------------------------------
+    /** Load the ExperimentInfo blocks, if any, in the NXS file
+    *
+    * @param ws :: MDEventWorkspace/MDHisto to load
+    */
+    void LoadMD::loadExperimentInfos(boost::shared_ptr<Mantid::API::MultipleExperimentInfos> ws)
+    {
+      // First, find how many experimentX blocks there are
+      std::map<std::string,std::string> entries;
+      file->getEntries(entries);
+      std::map<std::string,std::string>::iterator it = entries.begin();
+      std::vector<bool> hasExperimentBlock;
+      uint16_t numExperimentInfo = 0;
+      for (; it != entries.end(); ++it)
+      {
+        std::string name = it->first;
+        if (boost::starts_with(name, "experiment"))
+        {
+          try
+          {
+            uint16_t num = boost::lexical_cast<uint16_t>(name.substr(10, name.size()-10));
+            if (num+1 > numExperimentInfo)
+            {
+              numExperimentInfo = uint16_t(num+uint16_t(1));
+              hasExperimentBlock.resize(numExperimentInfo, false);
+              hasExperimentBlock[num] = true;
+            }
+          }
+          catch (boost::bad_lexical_cast &)
+          { /* ignore */ }
+        }
+      }
+
+      // Now go through in order, loading and adding
+      for (uint16_t i=0; i < numExperimentInfo; i++)
+      {
+        std::string groupName = "experiment" + Strings::toString(i);
+        if (!numExperimentInfo)
+        {
+          g_log.warning() << "NXS file is missing a ExperimentInfo block " << groupName << ". Workspace will be missing ExperimentInfo." << std::endl;
+          break;
+        }
+        file->openGroup(groupName, "NXgroup");
+        ExperimentInfo_sptr ei(new ExperimentInfo);
+        std::string parameterStr;
+        try
+        {
+          // Get the sample, logs, instrument
+          ei->loadExperimentInfoNexus(file, parameterStr);
+          // Now do the parameter map
+          ei->readParameterMap(parameterStr);
+          // And set it in the workspace.
+          ws->addExperimentInfo(ei);
+        }
+        catch (std::exception & e)
+        {
+          g_log.information("Error loading section '" + groupName + "' of nxs file.");
+          g_log.information(e.what());
+        }
+        file->closeGroup();
+      }
+
+    }
+
 
-    ////----------------------------------------------------------------------------------------------
-    ///** Execute the algorithm.
-    //*/
+    //----------------------------------------------------------------------------------------------
+    /** Execute the algorithm.
+    */
     void LoadMD::exec()
     {
       m_filename = getPropertyValue("Filename");
@@ -254,10 +319,10 @@ namespace Mantid
       std::vector<int> size(1, static_cast<int>(ws->getNPoints()));
       file->getSlab(data, start, size);
       file->closeData();
-   }
+    }
 
     //----------------------------------------------------------------------------------------------
-   /** Perform loading for a MDHistoWorkspace.
+    /** Perform loading for a MDHistoWorkspace.
     * The entry should be open already.
     */
     void LoadMD::loadHisto()
@@ -271,6 +336,8 @@ namespace Mantid
       // Load the WorkspaceHistory "process"
       ws->history().loadNexus(file);
 
+      this->loadAffineMatricies(boost::dynamic_pointer_cast<IMDWorkspace>(ws));
+
       // Load each data slab
       this->loadSlab("signal", ws->getSignalArray(), ws, ::NeXus::FLOAT64);
       this->loadSlab("errors_squared", ws->getErrorSquaredArray(), ws, ::NeXus::FLOAT64);
@@ -316,12 +383,12 @@ namespace Mantid
     template<typename MDE, size_t nd>
     void LoadMD::doLoad(typename MDEventWorkspace<MDE, nd>::sptr ws)
     {
-    //  // Are we using the file back end?
+      // Are we using the file back end?
       bool FileBackEnd = getProperty("FileBackEnd");
       bool BoxStructureOnly = getProperty("BoxStructureOnly");
 
       if (FileBackEnd && BoxStructureOnly)
-         throw std::invalid_argument("Both BoxStructureOnly and FileBackEnd were set to TRUE: this is not possible.");
+        throw std::invalid_argument("Both BoxStructureOnly and FileBackEnd were set to TRUE: this is not possible.");
 
       CPUTimer tim;
       Progress * prog = new Progress(this, 0.0, 1.0, 100);
@@ -334,6 +401,8 @@ namespace Mantid
       // Load the WorkspaceHistory "process"
       ws->history().loadNexus(file);
 
+      this->loadAffineMatricies(boost::dynamic_pointer_cast<IMDWorkspace>(ws));
+
       file->closeGroup();
       file->close();
       // Add each of the dimension
@@ -363,6 +432,7 @@ namespace Mantid
           // boxes have been already made file-backed when restoring the boxTree;
       // How much memory for the cache?
         {
+        // TODO: Clean up, only a write buffer now
           double mb = getProperty("Memory");
        
           // Defaults have changed, defauld disk buffer size should be 10 data chunks TODO: find optimal, 100 may be better. 
@@ -392,6 +462,8 @@ namespace Mantid
         for (size_t i=0; i<numBoxes; i++)
         {
           prog->report();
+          MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(boxTree[i]);
+          if(!box)continue;
 
           if(BoxEventIndex[2*i+1]>0) // Load in memory NOT using the file as the back-end,
               boxTree[i]->loadAndAddFrom(loader.get(),BoxEventIndex[2*i],static_cast<size_t>(BoxEventIndex[2*i+1]));
@@ -413,10 +485,69 @@ namespace Mantid
       //TODO:if(!FileBackEnd)ws->refreshCache();
       ws->refreshCache();
       g_log.debug() << tim << " to refreshCache(). " << ws->getNPoints() << " points after refresh." << std::endl;
+
       g_log.debug() << tim << " to finish up." << std::endl;
       delete prog;
     }
 
+  /**
+   * Load all of the affine matricies from the file, create the
+   * appropriate coordinate transform and set those on the workspace.
+   * @param ws : workspace to set the coordinate transforms on
+   */
+  void LoadMD::loadAffineMatricies(IMDWorkspace_sptr ws)
+  {
+    std::map<std::string, std::string> entries;
+    file->getEntries(entries);
+
+    if (entries.find("transform_to_orig") != entries.end())
+    {
+      CoordTransform *transform = this->loadAffineMatrix("transform_to_orig");
+      ws->setTransformToOriginal(transform);
+    }
+    if (entries.find("transform_from_orig") != entries.end())
+    {
+      CoordTransform *transform = this->loadAffineMatrix("transform_from_orig");
+      ws->setTransformFromOriginal(transform);
+    }
+  }
+
+  /**
+   * Do that actual loading and manipulating of the read data to create
+   * the affine matrix and then the appropriate transformation. This is
+   * currently limited to CoordTransformAffine transforms.
+   * @param entry_name : the entry point in the NeXus file to read
+   * @return the coordinate transform object
+   */
+  CoordTransform *LoadMD::loadAffineMatrix(std::string entry_name)
+  {
+    file->openData(entry_name);
+    std::vector<coord_t> vec;
+    file->getData<coord_t>(vec);
+    std::string type;
+    int inD;
+    int outD;
+    file->getAttr("type", type);
+    file->getAttr<int>("rows", outD);
+    file->getAttr<int>("columns", inD);
+    file->closeData();
+    // Adjust dimensions
+    inD--;
+    outD--;
+    Matrix<coord_t> mat(vec);
+    CoordTransform *transform = NULL;
+    if ("CoordTransformAffine" == type)
+    {
+      CoordTransformAffine *affine = new CoordTransformAffine(inD, outD);
+      affine->setMatrix(mat);
+      transform = affine;
+    }
+    else
+    {
+      g_log.notice("Do not know how to process coordinate transform " + type);
+    }
+    return transform;
+  }
 
   } // namespace Mantid
 } // namespace MDEvents
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
index 1545df45bc686058c46177e9456ed98cb5745fbe..0d25f5e775ecf7ecb06372a0e01129ffdba3b77f 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
@@ -9,8 +9,10 @@ If you specify UpdateFileBackEnd, then any changes (e.g. events added using the
 
 *WIKI*/
 
+#include "MantidAPI/CoordTransform.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidKernel/Matrix.h"
 #include "MantidKernel/System.h"
 #include "MantidMDEvents/MDBoxIterator.h"
 #include "MantidMDEvents/MDEventFactory.h"
@@ -118,17 +120,17 @@ namespace MDAlgorithms
 
     if(!wsIsFileBacked)
     {   // Erase the file if it exists
-        Poco::File oldFile(filename);
-        if (oldFile.exists())
-              oldFile.remove();
+      Poco::File oldFile(filename);
+      if (oldFile.exists())
+        oldFile.remove();
     }
 
     Progress * prog = new Progress(this, 0.0, 0.05,1);
     if(update)  // workspace has its own file and ignores any changes to the algorithm parameters
     {
-       if(!ws->isFileBacked())
-            throw std::runtime_error(" attemtp to update non-file backed workspace");
-        filename = bc->getFileIO()->getFileName();
+      if(!ws->isFileBacked())
+        throw std::runtime_error(" attemtp to update non-file backed workspace");
+      filename = bc->getFileIO()->getFileName();
     }
 
     //-----------------------------------------------------------------------------------------------------
@@ -138,86 +140,89 @@ namespace MDAlgorithms
     MDBoxFlatTree::saveExperimentInfos(file.get(),ws);
 
     if(!update)
-    {    
-        // Save the algorithm history under "process"
-        ws->getHistory().saveNexus(file.get());  
-
-        // Save some info as attributes. (Note: need to use attributes, not data sets because those cannot be resized).
-        file->putAttr("definition",  ws->id());
-        file->putAttr("title",  ws->getTitle() );
-        // Save each dimension, as their XML representation
-        for (size_t d=0; d<nd; d++)
-        {
-            std::ostringstream mess;
-            mess << "dimension" << d;
-            file->putAttr( mess.str(), ws->getDimension(d)->toXMLString() );
-        }      
+    {
+      // Save the algorithm history under "process"
+      ws->getHistory().saveNexus(file.get());
+
+      // Write out the affine matrices
+      this->saveAffineTransformMatricies(file.get(),
+                                         boost::dynamic_pointer_cast<const IMDWorkspace>(ws));
+
+      // Save some info as attributes. (Note: need to use attributes, not data sets because those cannot be resized).
+      file->putAttr("definition",  ws->id());
+      file->putAttr("title",  ws->getTitle() );
+      // Save each dimension, as their XML representation
+      for (size_t d=0; d<nd; d++)
+      {
+        std::ostringstream mess;
+        mess << "dimension" << d;
+        file->putAttr( mess.str(), ws->getDimension(d)->toXMLString() );
+      }
     }
     file->closeGroup();
     file->close();
 
-
-    MDBoxFlatTree BoxFlatStruct; 
+    MDBoxFlatTree BoxFlatStruct;
     //-----------------------------------------------------------------------------------------------------
     if(update) // the workspace is already file backed; We not usually use this mode but want to leave it for compartibility
     {
-        // remove all boxes from the DiskBuffer. DB will calculate boxes positions on HDD.
-        bc->getFileIO()->flushCache();
-       // flatten the box structure; this will remember boxes file positions in the box structure
-        BoxFlatStruct.initFlatStructure(ws,filename);
+      // remove all boxes from the DiskBuffer. DB will calculate boxes positions on HDD.
+      bc->getFileIO()->flushCache();
+      // flatten the box structure; this will remember boxes file positions in the box structure
+      BoxFlatStruct.initFlatStructure(ws,filename);
     }
     else   // not file backed;
     {
-        // the boxes file positions are unknown and we need to calculate it.
-        BoxFlatStruct.initFlatStructure(ws,filename);
-        // create saver class
-        auto Saver = boost::shared_ptr<API::IBoxControllerIO>(new MDEvents::BoxControllerNeXusIO(bc.get()));
-        Saver->setDataType(sizeof(coord_t),MDE::getTypeName());
-        if(MakeFileBacked)
+      // the boxes file positions are unknown and we need to calculate it.
+      BoxFlatStruct.initFlatStructure(ws,filename);
+      // create saver class
+      auto Saver = boost::shared_ptr<API::IBoxControllerIO>(new MDEvents::BoxControllerNeXusIO(bc.get()));
+      Saver->setDataType(sizeof(coord_t),MDE::getTypeName());
+      if(MakeFileBacked)
+      {
+        // store saver with box controller
+        bc->setFileBacked(Saver,filename);
+        // get access to boxes array
+        std::vector<API::IMDNode *> &boxes = BoxFlatStruct.getBoxes();
+        // calculate the position of the boxes on file, indicating to make them saveable and that the boxes were not saved.
+        BoxFlatStruct.setBoxesFilePositions(true);
+        prog->resetNumSteps(boxes.size(),0.06,0.90);
+        for(size_t i=0;i<boxes.size();i++)
         {
-            // store saver with box controller
-            bc->setFileBacked(Saver,filename);         
-            // get access to boxes array
-            std::vector<API::IMDNode *> &boxes = BoxFlatStruct.getBoxes();
-            // calculate the position of the boxes on file, indicating to make them saveable and that the boxes were not saved. 
-            BoxFlatStruct.setBoxesFilePositions(true);
-            prog->resetNumSteps(boxes.size(),0.06,0.90);
-            for(size_t i=0;i<boxes.size();i++)
-            {
-                auto saveableTag = boxes[i]->getISaveable();
-                if(saveableTag) // only boxes can be saveable 
-                {
-                 // do not spend time on empty boxes 
-                    if(boxes[i]->getDataInMemorySize()==0)continue;
-                    // save boxes directly using the boxes file postion, precalculated in boxFlatStructure.
-                    saveableTag->save();
-                    // remove boxes data from memory. This will actually correctly set the tag indicatin that data were not loaded.
-                    saveableTag->clearDataFromMemory();
-                    // put boxes into write buffer wich will save them when necessary
-                    //Saver->toWrite(saveTag);
-                    prog->report("Saving Box");
-                }
-            }
-            // remove everything from diskBuffer;  (not sure if it really necessary but just in case , should not make any harm)
-            Saver->flushCache();
-            // drop NeXus on HDD (not sure if it really necessary but just in case )
-            Saver->flushData();
+          auto saveableTag = boxes[i]->getISaveable();
+          if(saveableTag) // only boxes can be saveable
+          {
+            // do not spend time on empty boxes
+            if(boxes[i]->getDataInMemorySize()==0)continue;
+            // save boxes directly using the boxes file postion, precalculated in boxFlatStructure.
+            saveableTag->save();
+            // remove boxes data from memory. This will actually correctly set the tag indicatin that data were not loaded.
+            saveableTag->clearDataFromMemory();
+            // put boxes into write buffer wich will save them when necessary
+            //Saver->toWrite(saveTag);
+            prog->report("Saving Box");
+          }
         }
-        else  // just save data, and finish with it
+        // remove everything from diskBuffer;  (not sure if it really necessary but just in case , should not make any harm)
+        Saver->flushCache();
+        // drop NeXus on HDD (not sure if it really necessary but just in case )
+        Saver->flushData();
+      }
+      else  // just save data, and finish with it
+      {
+        Saver->openFile(filename,"w");
+        BoxFlatStruct.setBoxesFilePositions(false);
+        std::vector<API::IMDNode *> &boxes = BoxFlatStruct.getBoxes();
+        std::vector<uint64_t> &eventIndex  = BoxFlatStruct.getEventIndex();
+        prog->resetNumSteps(boxes.size(),0.06,0.90);
+        for(size_t i=0;i<boxes.size();i++)
         {
-            Saver->openFile(filename,"w");
-            BoxFlatStruct.setBoxesFilePositions(false);
-            std::vector<API::IMDNode *> &boxes = BoxFlatStruct.getBoxes();
-            std::vector<uint64_t> &eventIndex  = BoxFlatStruct.getEventIndex();
-            prog->resetNumSteps(boxes.size(),0.06,0.90);
-            for(size_t i=0;i<boxes.size();i++)
-            {
-                if(eventIndex[2*i+1]==0)continue;
-                boxes[i]->saveAt(Saver.get(),eventIndex[2*i]);
-                prog->report("Saving Box");
-            }
-            Saver->closeFile();
+          if(eventIndex[2*i+1]==0)continue;
+          boxes[i]->saveAt(Saver.get(),eventIndex[2*i]);
+          prog->report("Saving Box");
         }
+        Saver->closeFile();
+      }
     }
 
 
@@ -225,12 +230,13 @@ namespace MDAlgorithms
     // OK, we've filled these big arrays of data representing flat box structrre. Save them.
     progress(0.91, "Writing Box Data");
     prog->resetNumSteps(8, 0.92, 1.00);
+
     //Save box structure;
     BoxFlatStruct.saveBoxStructure(filename);
 
     delete prog;
 
-     ws->setFileNeedsUpdating(false);
+    ws->setFileNeedsUpdating(false);
   }
 
 
@@ -284,6 +290,9 @@ namespace MDAlgorithms
       file->putAttr( mess.str(), ws->getDimension(d)->toXMLString() );
     }
 
+    // Write out the affine matrices
+    this->saveAffineTransformMatricies(file, boost::dynamic_pointer_cast<const IMDWorkspace>(ws));
+
     // Check that the typedef has not been changed. The NeXus types would need changing if it does!
     assert(sizeof(signal_t) == sizeof(double));
 
@@ -314,7 +323,7 @@ namespace MDAlgorithms
 
   }
 
-//
+
   //----------------------------------------------------------------------------------------------
   /** Execute the algorithm.
    */
@@ -337,6 +346,79 @@ namespace MDAlgorithms
       throw std::runtime_error("SaveMD can only save MDEventWorkspaces and MDHistoWorkspaces.\nPlease use SaveNexus or another algorithm appropriate for this workspace type.");
   }
 
+  /**
+   * Save the affine matricies to both directional conversions to the
+   * data.
+   * @param file : pointer to the NeXus file
+   * @param ws : workspace to get matrix from
+   */
+  void SaveMD::saveAffineTransformMatricies(::NeXus::File *const file,
+                                            IMDWorkspace_const_sptr ws)
+  {
+    try {
+      this->saveAffineTransformMatrix(file,
+                                      ws->getTransformToOriginal(),
+                                      "transform_to_orig");
+    }
+    catch (std::runtime_error &)
+    {
+      // Do nothing
+    }
+    try {
+      this->saveAffineTransformMatrix(file,
+                                      ws->getTransformFromOriginal(),
+                                      "transform_from_orig");
+    }
+    catch (std::runtime_error &)
+    {
+      // Do nothing
+    }
+  }
+
+  /**
+   * Extract and save the requested affine matrix.
+   * @param file : pointer to the NeXus file
+   * @param transform : the object to extract the affine matrix from
+   * @param entry_name : the tag in the NeXus file to save under
+   */
+  void SaveMD::saveAffineTransformMatrix(::NeXus::File *const file,
+                                         CoordTransform *transform,
+                                         std::string entry_name)
+  {
+    Matrix<coord_t> matrix = transform->makeAffineMatrix();
+    g_log.debug() << "TRFM: " << matrix.str() << std::endl;
+    this->saveMatrix<coord_t>(file, entry_name, matrix,
+                              ::NeXus::FLOAT32, transform->id());
+  }
+
+
+  /**
+   * Save routine for a generic matrix
+   * @param file : pointer to the NeXus file
+   * @param name : the tag in the NeXus file to save under
+   * @param m : matrix to save
+   * @param type : NXnumtype for the matrix data
+   * @param tag : id for an affine matrix conversion
+   */
+  template<typename T>
+  void SaveMD::saveMatrix(::NeXus::File *const file, std::string name,
+                         Matrix<T> &m, ::NeXus::NXnumtype type, std::string tag)
+  {
+    std::vector<T> v = m.getVector();
+    // Number of data points
+    int nPoints = static_cast<int>(v.size());
+
+    file->makeData(name, type, nPoints, true);
+    // Need a pointer
+    file->putData(&v[0]);
+    if (!tag.empty())
+    {
+      file->putAttr("type", tag);
+      file->putAttr("rows", static_cast<int>(m.numRows()));
+      file->putAttr("columns", static_cast<int>(m.numCols()));
+    }
+    file->closeData();
+  }
 
 
 } // namespace Mantid
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h
index 520603e65ede51a013dd7ab95a77b88b9002cd0d..3d695740829106ca7716870a6d2a85977f1cb63a 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h
@@ -13,6 +13,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/LibraryWrapper.h"
+#include "MantidMDEvents/MDWSTransform.h"
 #include <cxxtest/TestSuite.h>
 #include <iomanip>
 #include <iostream>
@@ -33,13 +34,28 @@ public:
     }
     void setSourceWS(Mantid::API::MatrixWorkspace_sptr InWS2D)
     {
-      m_InWS2D = InWS2D;
+      this->m_InWS2D = InWS2D;
+      // and create the class, which will deal with the target workspace
+      if(!this->m_OutWSWrapper) this->m_OutWSWrapper = boost::shared_ptr<MDEvents::MDEventWSWrapper>(new MDEvents::MDEventWSWrapper());
     }
     Convert2MDComponentsTestHelper()
     {
       ConvertToMD::initialize();
     }
+    bool buildTargetWSDescription(API::IMDEventWorkspace_sptr spws,const std::string &Q_mod_req,const std::string &dEModeRequested,const std::vector<std::string> &other_dim_names,
+                                      const std::string &convert_to_,MDEvents::MDWSDescription &targWSDescr)
+    {
+        return ConvertToMD::buildTargetWSDescription(spws,Q_mod_req,dEModeRequested,other_dim_names,convert_to_,targWSDescr);
+    }
+    void copyMetaData(API::IMDEventWorkspace_sptr mdEventWS,MDEvents::MDWSDescription &targWSDescr) const
+    {
+        ConvertToMD::copyMetaData(mdEventWS,targWSDescr);
+    }
 
+    API::IMDEventWorkspace_sptr createNewMDWorkspace(const MDEvents::MDWSDescription &NewMDWSDescription)
+    {
+            return ConvertToMD::createNewMDWorkspace(NewMDWSDescription);
+    }
 };
 
 
@@ -184,7 +200,58 @@ void testCalcDECol()
 
 }
 
+void testCopyMethadata()
+{
+     Mantid::API::MatrixWorkspace_sptr ws2Dp = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("testWSProcessed");
+
+     API::IMDEventWorkspace_sptr spws;
+     // create testing part of the algorithm
+     Convert2MDComponentsTestHelper subAlgo;
+     // set source workspace as it would be used by the algorithm iteslt;
+     subAlgo.setSourceWS(ws2Dp);
+     // and min-max values (they are still needed by the algorithm)
+     subAlgo.setPropertyValue("MinValues","-10");
+     subAlgo.setPropertyValue("MaxValues","10");
+
+     bool createNewTargetWs(false);
+     std::vector<std::string> Q_modes = MDEvents::MDTransfFactory::Instance().getKeys();
+     std::string dE_mode = Kernel::DeltaEMode().asString(Kernel::DeltaEMode::Elastic);
+     MDWSTransform QScl;
+     std::vector<std::string> QScales = QScl.getQScalings();
+
+     MDEvents::MDWSDescription targWSDescr;
+     TS_ASSERT_THROWS_NOTHING(createNewTargetWs=subAlgo.buildTargetWSDescription(spws,Q_modes[0],dE_mode,std::vector<std::string>(),QScales[CnvrtToMD::NoScaling],targWSDescr));
 
+     TSM_ASSERT("as spws is null pointer, this should request creating new workspace ",createNewTargetWs)
+
+     TS_ASSERT_THROWS_NOTHING(spws = subAlgo.createNewMDWorkspace(targWSDescr));
+     TS_ASSERT(spws);
+     if(!spws)return;
+ 
+    // copy the necessary methadata and get the unique number, that identifies the run, the source workspace came from.
+    TS_ASSERT_THROWS_NOTHING(subAlgo.copyMetaData(spws,targWSDescr));
+
+    uint16_t runIndex(1000);
+    TS_ASSERT_THROWS_NOTHING(runIndex=targWSDescr.getPropertyValueAsType<uint16_t>("RUN_INDEX"));
+    TS_ASSERT_EQUALS(0,runIndex);
+
+    // target workspace has W-matrix, which should be unit matrix
+    TS_ASSERT(spws->getExperimentInfo(0)->run().hasProperty("W_MATRIX"));
+    // it also has transformation matrix    
+    TS_ASSERT(spws->getExperimentInfo(0)->run().hasProperty("RUBW_MATRIX"));
+
+    if(!spws->getExperimentInfo(0)->run().hasProperty("W_MATRIX"))return;
+
+    Kernel::DblMatrix UnitMatr(3,3,true);
+    std::vector<double> libWMatr;
+
+    TS_ASSERT_THROWS_NOTHING(libWMatr=spws->getExperimentInfo(0)->run().getPropertyValueAsType<std::vector<double> >("W_MATRIX"));
+
+    Kernel::DblMatrix wMatr(libWMatr);
+    TSM_ASSERT("We have not set up anything so it should be unit matrix",wMatr.equals(UnitMatr));
+
+
+}
 
 
 ConvertToMDComponentsTest()
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h
index e72ea4761be31baedbf818eef1a71234636a66e1..fdbd0255b5cb9be2f683b56b02b4084510dc51a5 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h
@@ -268,155 +268,154 @@ static void destroySuite(ConvertToMDTestPerformance * suite) { delete suite; }
 
 void test_EventNoUnitsConv()
 {
-    TS_WARN("Disabled untill meged with #6852");
-
-    //NumericAxis *pAxis0 = new NumericAxis(2); 
-    //pAxis0->setUnit("DeltaE");
-    //inWsEv->replaceAxis(0,pAxis0);
-
-    //MDWSDescription WSD;
-    //std::vector<double> min(4,-1e+30),max(4,1e+30);
-    //WSD.setMinMax(min,max);
-
-    //WSD.buildFromMatrixWS(inWsEv,"Q3D","Indirect");
-
-    //WSD.m_PreprDetTable =pDetLoc_events;
-    //WSD.m_RotMatrix = Rot;
-    //// this one comes from ticket #6852 and would not exist in clear branch.
-    //WSD.addProperty("RUN_INDEX",10,true);
-
-    //// create new target MD workspace
-    //pTargWS->releaseWorkspace();   
-    //pTargWS->createEmptyMDWS(WSD);
-
-    //ConvToMDSelector AlgoSelector;
-    //pConvMethods = AlgoSelector.convSelector(inWsEv);
-    //TS_ASSERT_THROWS_NOTHING(pConvMethods->initialize(WSD,pTargWS));
-
-    //pMockAlgorithm->resetProgress(numHist);
-    ////Clock.elapsedCPU();
-    //std::time (&start);
-    //TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
-    //std::time (&end);
-    //double sec = std::difftime (end,start);
-    //TS_WARN("Time to complete: <EventWSType,Q3D,Indir,ConvertNo,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
+   
+
+    NumericAxis *pAxis0 = new NumericAxis(2); 
+    pAxis0->setUnit("DeltaE");
+    inWsEv->replaceAxis(0,pAxis0);
+
+    MDWSDescription WSD;
+    std::vector<double> min(4,-1e+30),max(4,1e+30);
+    WSD.setMinMax(min,max);
+
+    WSD.buildFromMatrixWS(inWsEv,"Q3D","Indirect");
+
+    WSD.m_PreprDetTable =pDetLoc_events;
+    WSD.m_RotMatrix = Rot;
+    // this one comes from ticket #6852 and would not exist in clear branch.
+    WSD.addProperty("RUN_INDEX",static_cast<uint16_t>(10),true);
+
+    // create new target MD workspace
+    pTargWS->releaseWorkspace();   
+    pTargWS->createEmptyMDWS(WSD);
+
+    ConvToMDSelector AlgoSelector;
+    pConvMethods = AlgoSelector.convSelector(inWsEv);
+    TS_ASSERT_THROWS_NOTHING(pConvMethods->initialize(WSD,pTargWS));
+
+    pMockAlgorithm->resetProgress(numHist);
+    //Clock.elapsedCPU();
+    std::time (&start);
+    TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
+    std::time (&end);
+    double sec = std::difftime (end,start);
+    TS_WARN("Time to complete: <EventWSType,Q3D,Indir,ConvertNo,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
 }
 
 void test_EventFromTOFConv()
 {
-    TS_WARN("Disabled untill meged with #6852");
+   
 
-    //NumericAxis *pAxis0 = new NumericAxis(2); 
-    //pAxis0->setUnit("TOF");
-    //inWsEv->replaceAxis(0,pAxis0);
+    NumericAxis *pAxis0 = new NumericAxis(2); 
+    pAxis0->setUnit("TOF");
+    inWsEv->replaceAxis(0,pAxis0);
   
-    //MDWSDescription WSD;
-    //std::vector<double> min(4,-1e+30),max(4,1e+30);
-    //WSD.setMinMax(min,max);
-    //WSD.buildFromMatrixWS(inWsEv,"Q3D","Indirect");
-
-    //WSD.m_PreprDetTable =pDetLoc_events;
-    //WSD.m_RotMatrix = Rot;
-    //// this one comes from ticket #6852 and would not exist in clear branch.
-    //WSD.addProperty("RUN_INDEX",10,true);
-
-    //// create new target MD workspace
-    //pTargWS->releaseWorkspace();   
-    //pTargWS->createEmptyMDWS(WSD);
-
-
-    //ConvToMDSelector AlgoSelector;
-    //pConvMethods = AlgoSelector.convSelector(inWsEv);
-    //pConvMethods->initialize(WSD,pTargWS);
-
-    //pMockAlgorithm->resetProgress(numHist);
-    ////Clock.elapsedCPU();
-    //std::time (&start);
-    //TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
-    //std::time (&end);
-    //double sec = std::difftime (end,start);
-    ////float sec = Clock.elapsedCPU();
-    //TS_WARN("Time to complete: <EventWSType,Q3D,Indir,ConvFromTOF,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
+    MDWSDescription WSD;
+    std::vector<double> min(4,-1e+30),max(4,1e+30);
+    WSD.setMinMax(min,max);
+    WSD.buildFromMatrixWS(inWsEv,"Q3D","Indirect");
+
+    WSD.m_PreprDetTable =pDetLoc_events;
+    WSD.m_RotMatrix = Rot;
+    // this one comes from ticket #6852 and would not exist in clear branch.
+    WSD.addProperty("RUN_INDEX",static_cast<uint16_t>(10),true);
+
+    // create new target MD workspace
+    pTargWS->releaseWorkspace();   
+    pTargWS->createEmptyMDWS(WSD);
+
+
+    ConvToMDSelector AlgoSelector;
+    pConvMethods = AlgoSelector.convSelector(inWsEv);
+    pConvMethods->initialize(WSD,pTargWS);
+
+    pMockAlgorithm->resetProgress(numHist);
+    //Clock.elapsedCPU();
+    std::time (&start);
+    TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
+    std::time (&end);
+    double sec = std::difftime (end,start);
+    //float sec = Clock.elapsedCPU();
+    TS_WARN("Time to complete: <EventWSType,Q3D,Indir,ConvFromTOF,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
 }
 void test_HistoFromTOFConv()
 {
-    TS_WARN("Disabled untill meged with #6852");  
 
-    //NumericAxis *pAxis0 = new NumericAxis(2); 
-    //pAxis0->setUnit("TOF");
-    //inWs2D->replaceAxis(0,pAxis0);
+    NumericAxis *pAxis0 = new NumericAxis(2); 
+    pAxis0->setUnit("TOF");
+    inWs2D->replaceAxis(0,pAxis0);
 
-    //MDWSDescription WSD;
-    //std::vector<double> min(4,-1e+30),max(4,1e+30);
-    //WSD.setMinMax(min,max);
+    MDWSDescription WSD;
+    std::vector<double> min(4,-1e+30),max(4,1e+30);
+    WSD.setMinMax(min,max);
 
-    //WSD.buildFromMatrixWS(inWs2D,"Q3D","Indirect");
+    WSD.buildFromMatrixWS(inWs2D,"Q3D","Indirect");
 
-    //WSD.m_PreprDetTable =pDetLoc_histo;
-    //WSD.m_RotMatrix = Rot;
-    //// this one comes from ticket #6852 and would not exist in clear branch.
-    //WSD.addProperty("RUN_INDEX",10,true);
+    WSD.m_PreprDetTable =pDetLoc_histo;
+    WSD.m_RotMatrix = Rot;
+    // this one comes from ticket #6852 and would not exist in clear branch.
+    WSD.addProperty("RUN_INDEX",static_cast<uint16_t>(10),true);
 
-    //// create new target MD workspace
-    //pTargWS->releaseWorkspace();   
-    //pTargWS->createEmptyMDWS(WSD);
+    // create new target MD workspace
+    pTargWS->releaseWorkspace();   
+    pTargWS->createEmptyMDWS(WSD);
 
 
-    //pTargWS->createEmptyMDWS(WSD);
+    pTargWS->createEmptyMDWS(WSD);
 
-    //ConvToMDSelector AlgoSelector;
-    //pConvMethods = AlgoSelector.convSelector(inWs2D);
-    //pConvMethods->initialize(WSD,pTargWS);
+    ConvToMDSelector AlgoSelector;
+    pConvMethods = AlgoSelector.convSelector(inWs2D);
+    pConvMethods->initialize(WSD,pTargWS);
 
-    //pMockAlgorithm->resetProgress(numHist);
-    ////Clock.elapsedCPU();
-    //std::time (&start);
-    //TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
-    //std::time (&end);
-    //double sec = std::difftime (end,start);
+    pMockAlgorithm->resetProgress(numHist);
+    //Clock.elapsedCPU();
+    std::time (&start);
+    TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
+    std::time (&end);
+    double sec = std::difftime (end,start);
 
-    //TS_WARN("Time to complete: <Ws2DHistoType,Q3D,Indir,ConvFromTOF,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
+    TS_WARN("Time to complete: <Ws2DHistoType,Q3D,Indir,ConvFromTOF,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
 }
 
 void test_HistoNoUnitsConv()
 {
 
-    TS_WARN("Disabled untill meged with #6852");  
+  
 
-    //NumericAxis *pAxis0 = new NumericAxis(2); 
-    //pAxis0->setUnit("DeltaE");
-    //inWs2D->replaceAxis(0,pAxis0);
+    NumericAxis *pAxis0 = new NumericAxis(2); 
+    pAxis0->setUnit("DeltaE");
+    inWs2D->replaceAxis(0,pAxis0);
 
-    //MDWSDescription WSD;
-    //std::vector<double> min(4,-1e+30),max(4,1e+30);
-    //WSD.setMinMax(min,max);
+    MDWSDescription WSD;
+    std::vector<double> min(4,-1e+30),max(4,1e+30);
+    WSD.setMinMax(min,max);
 
-    //WSD.buildFromMatrixWS(inWs2D,"Q3D","Indirect");
+    WSD.buildFromMatrixWS(inWs2D,"Q3D","Indirect");
 
-    //WSD.m_PreprDetTable =pDetLoc_histo;
-    //WSD.m_RotMatrix = Rot;
-    //// this one comes from ticket #6852 and would not exist in clear branch.
-    //WSD.addProperty("RUN_INDEX",10,true);
+    WSD.m_PreprDetTable =pDetLoc_histo;
+    WSD.m_RotMatrix = Rot;
+    // this one comes from ticket #6852 and would not exist in clear branch.
+    WSD.addProperty("RUN_INDEX",static_cast<uint16_t>(10),true);
 
-    //// create new target MD workspace
-    //pTargWS->releaseWorkspace();   
-    //pTargWS->createEmptyMDWS(WSD);
+    // create new target MD workspace
+    pTargWS->releaseWorkspace();   
+    pTargWS->createEmptyMDWS(WSD);
 
 
-    //pTargWS->createEmptyMDWS(WSD);
+    pTargWS->createEmptyMDWS(WSD);
 
-    //ConvToMDSelector AlgoSelector;
-    //pConvMethods = AlgoSelector.convSelector(inWs2D);
-    //pConvMethods->initialize(WSD,pTargWS);
+    ConvToMDSelector AlgoSelector;
+    pConvMethods = AlgoSelector.convSelector(inWs2D);
+    pConvMethods->initialize(WSD,pTargWS);
 
-    //pMockAlgorithm->resetProgress(numHist);
-    ////Clock.elapsedCPU();
-    //std::time (&start);
-    //TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
-    //std::time (&end);
-    //double sec = std::difftime (end,start);
+    pMockAlgorithm->resetProgress(numHist);
+    //Clock.elapsedCPU();
+    std::time (&start);
+    TS_ASSERT_THROWS_NOTHING(pConvMethods->runConversion(pMockAlgorithm->getProgress()));
+    std::time (&end);
+    double sec = std::difftime (end,start);
 
-    //TS_WARN("Time to complete: <Ws2DHistoType,Q3D,Indir,ConvertNo,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
+    TS_WARN("Time to complete: <Ws2DHistoType,Q3D,Indir,ConvertNo,CrystType>: "+boost::lexical_cast<std::string>(sec)+" sec");
 }
 
 
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h
index c21e96173b7ba8d5f19e002a53e5e9540b64179e..5a0fc5f9ed7eacc90dca5b1a734a954490866ba7 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h
@@ -567,6 +567,57 @@ public:
     AnalysisDataService::Instance().remove("OutputWorkspace");
   }
 
+  void test_loadAffine()
+  {
+    std::string filename("SaveMDAffineTest.nxs");
+    // Make a 4D MDEventWorkspace
+    MDEventWorkspace4Lean::sptr ws = MDEventsTestHelper::makeMDEW<4>(10, 0.0, 10.0, 2);
+    AnalysisDataService::Instance().addOrReplace("SaveMDAffineTest_ws", ws);
+
+    // Bin data to get affine matrix
+    BinMD balg;
+    balg.initialize();
+    balg.setProperty("InputWorkspace", "SaveMDAffineTest_ws");
+    balg.setProperty("OutputWorkspace", "SaveMDAffineTestHisto_ws");
+    balg.setProperty("AlignedDim0", "Axis2,0,10,10");
+    balg.setProperty("AlignedDim1", "Axis0,0,10,5");
+    balg.setProperty("AlignedDim2", "Axis1,0,10,5");
+    balg.setProperty("AlignedDim3", "Axis3,0,10,2");
+    balg.execute();
+
+    SaveMD alg;
+    alg.initialize();
+    alg.setPropertyValue("InputWorkspace", "SaveMDAffineTestHisto_ws");
+    alg.setPropertyValue("Filename", filename);
+    alg.setProperty("MakeFileBacked","0");
+    alg.execute();
+    TS_ASSERT( alg.isExecuted() );
+
+    LoadMD loadAlg;
+    loadAlg.initialize();
+    loadAlg.isInitialized();
+    loadAlg.setPropertyValue("Filename", filename);
+    loadAlg.setProperty("FileBackEnd", false);
+    loadAlg.setPropertyValue("OutputWorkspace", "reloaded_affine");
+    loadAlg.execute();
+    TS_ASSERT( loadAlg.isExecuted() );
+
+    // Check the affine matrix over at a couple of locations
+    MDHistoWorkspace_sptr newWS = AnalysisDataService::Instance().retrieveWS<MDHistoWorkspace>("reloaded_affine");
+    Matrix<coord_t> affMat = newWS->getTransformToOriginal()->makeAffineMatrix();
+    TS_ASSERT_EQUALS( affMat[0][1], 1.0 );
+    TS_ASSERT_EQUALS( affMat[2][0], 1.0 );
+
+    if (Poco::File(filename).exists())
+    {
+      Poco::File(filename).remove();
+    }
+
+    AnalysisDataService::Instance().remove("SaveMDAffineTest_ws");
+    AnalysisDataService::Instance().remove("SaveMDAffineTestHisto_ws");
+    AnalysisDataService::Instance().remove("OutputWorkspace");
+  }
+
 };
 
 #endif /* MANTID_MDEVENTS_LOADMDEWTEST_H_ */
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/SaveMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/SaveMDTest.h
index b256c611c6b8eb461ad8b3cf0088393df3fa5e83..1c90b386e9e2b04c39a3da8d80733d6bd55014a7 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/SaveMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/SaveMDTest.h
@@ -4,6 +4,7 @@
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
 #include "MantidMDEvents/MDEventFactory.h"
+#include "MantidMDAlgorithms/BinMD.h"
 #include "MantidMDAlgorithms/SaveMD.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "MantidAPI/FrameworkManager.h"
@@ -208,6 +209,39 @@ public:
 
   }
 
+  void test_saveAffine()
+  {
+    std::string filename("MDAffineSaveTest.nxs");
+    // Make a 4D MDEventWorkspace
+    MDEventWorkspace4Lean::sptr ws = MDEventsTestHelper::makeMDEW<4>(10, 0.0, 10.0, 2);
+    AnalysisDataService::Instance().addOrReplace("SaveMDTest_ws", ws);
+
+    // Bin data to get affine matrix
+    BinMD balg;
+    balg.initialize();
+    balg.setProperty("InputWorkspace", "SaveMDTest_ws");
+    balg.setProperty("OutputWorkspace", "SaveMDTestHisto_ws");
+    balg.setProperty("AlignedDim0", "Axis2,0,10,10");
+    balg.setProperty("AlignedDim1", "Axis0,0,10,5");
+    balg.setProperty("AlignedDim2", "Axis1,0,10,5");
+    balg.setProperty("AlignedDim3", "Axis3,0,10,2");
+    balg.execute();
+
+    SaveMD alg;
+    TS_ASSERT_THROWS_NOTHING( alg.initialize() )
+    TS_ASSERT( alg.isInitialized() )
+    TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", "SaveMDTestHisto_ws") );
+    TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", filename) );
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("MakeFileBacked","0") );
+    alg.execute();
+    TS_ASSERT( alg.isExecuted() );
+
+    ws->clearFileBacked(false);
+    if (Poco::File(filename).exists())
+    {
+      Poco::File(filename).remove();
+    }
+  }
 
   /** Run SaveMD with the MDHistoWorkspace */
   void doTestHisto(MDHistoWorkspace_sptr ws)
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAffine.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAffine.h
index d0a9243da8328833b22ba14bc7f38e058c594e62..69725cbca68a1aefe6b5f11f55b0be62f41ac258 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAffine.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAffine.h
@@ -37,6 +37,7 @@ namespace MDEvents
     virtual CoordTransform * clone() const;
     virtual ~CoordTransformAffine();
     virtual std::string toXMLString() const;
+    virtual std::string id() const;
     void addTranslation(const coord_t * translationVector);
     const Mantid::Kernel::Matrix<coord_t> & getMatrix() const;
     Mantid::Kernel::Matrix<coord_t> makeAffineMatrix() const;
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h
index d3cf482d3a0981a7ea249e082f17a3356839a07e..0e1161ae807fc33e6b612667eb513f9663ec52bf 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h
@@ -64,6 +64,7 @@ namespace MDEvents
     virtual ~CoordTransformAligned();
     
     std::string toXMLString() const;
+    std::string id() const;
     void apply(const coord_t * inputVector, coord_t * outVector) const;
     Mantid::Kernel::Matrix<coord_t> makeAffineMatrix() const;
 
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h
index 89d9d5a29244772f18f23631827da9e91e6dc1d8..d969b047154e05d4ad73573e235c791ab279ce2a 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h
@@ -37,6 +37,7 @@ namespace MDEvents
     virtual CoordTransform * clone() const;
     virtual ~CoordTransformDistance();
     virtual std::string toXMLString() const;
+    virtual std::string id() const;
 
     void apply(const coord_t * inputVector, coord_t * outVector) const;
 
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDWSDescription.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDWSDescription.h
index a6d7979245aa20b9577f8668f8477ff7d92b50d2..4c6fc8af3c4d21ceacfc3817e99d6851d7c006aa 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDWSDescription.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDWSDescription.h
@@ -11,8 +11,8 @@
 
 #include "MantidMDEvents/MDEvent.h"
 #include "MantidMDEvents/ConvToMDPreprocDet.h"
-//#include "MantidMDEvents/MDTransfDEHelper.h"
 #include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/LogManager.h"
 
 
 namespace Mantid
@@ -56,7 +56,7 @@ namespace MDEvents
 
 
 /// helper class describes the properties of target MD workspace, which should be obtained as the result of conversion algorithm. 
-class DLLExport MDWSDescription : public Kernel::PropertyManager
+    class DLLExport MDWSDescription : public API::LogManager
 {
 public:  // for the time being
     /// the string which describes ChildAlgorithm, used to convert source ws to target MD ws. At the moment, it coinsides with Q-mode
@@ -156,6 +156,7 @@ protected: // until MDWSDesctiptionDepricatedExist
 //********************* internal helpers
      /// helper function to resize all vectors, responsible for MD dimensions in one go
      void resizeDimDescriptions(unsigned int Dims,size_t nBins=10);
+
 private:
   /// Coordinate system.
   Mantid::API::SpecialCoordinateSystem m_coordinateSystem;
diff --git a/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp b/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp
index 6406cae75ee55f26bbb11bdfd5e94cf5fc701742..f4c0dbab3001c22e17db3d8658d2bbad16f97092 100644
--- a/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp
@@ -33,10 +33,9 @@ namespace Mantid
 
       // set up output MD workspace wrapper
       m_OutWSWrapper = inWSWrapper;
-
-      // Copy ExperimentInfo (instrument, run, sample) to the output WS
-      API::ExperimentInfo_sptr ei(m_InWS2D->cloneExperimentInfo());
-      m_RunIndex            = m_OutWSWrapper->pWorkspace()->addExperimentInfo(ei);
+      // get the index which identify the run the source workspace came from.
+      // This index will mark the workspace' events for diffetent worksapces to combine
+      m_RunIndex            = WSD.getPropertyValueAsType<uint16_t>("RUN_INDEX");
 
       m_NDims       = m_OutWSWrapper->nDimensions();
       // allocate space for single MDEvent coordinates 
diff --git a/Code/Mantid/Framework/MDEvents/src/CoordTransformAffine.cpp b/Code/Mantid/Framework/MDEvents/src/CoordTransformAffine.cpp
index af724579ce4916cf8f8bf27caf06325c26f6746a..67dcd7383e9db1189487c392f31baf610cdf61d1 100644
--- a/Code/Mantid/Framework/MDEvents/src/CoordTransformAffine.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/CoordTransformAffine.cpp
@@ -267,6 +267,14 @@ namespace MDEvents
       return formattedXMLString;
   }
 
+  /**
+   * Coordinate transform id
+   * @return the type of coordinate transform
+   */
+  std::string CoordTransformAffine::id() const
+  {
+    return "CoordTransformAffine";
+  }
 
   //----------------------------------------------------------------------------------------------
   /** Combine two transformations into a single affine transformations
diff --git a/Code/Mantid/Framework/MDEvents/src/CoordTransformAligned.cpp b/Code/Mantid/Framework/MDEvents/src/CoordTransformAligned.cpp
index 210580588ea1a1709114aabadd1f5c333a3559f3..a29269ca2e1742555f3d1e2ead5d16bab417764d 100644
--- a/Code/Mantid/Framework/MDEvents/src/CoordTransformAligned.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/CoordTransformAligned.cpp
@@ -183,6 +183,14 @@ namespace MDEvents
      return formattedXMLString;
   }
 
+  /**
+   * Coordinate transform id
+   * @return the type of coordinate transform
+   */
+  std::string CoordTransformAligned::id() const
+  {
+    return "CoordTransformAligned";
+  }
 
 } // namespace Mantid
 } // namespace MDEvents
diff --git a/Code/Mantid/Framework/MDEvents/src/CoordTransformDistance.cpp b/Code/Mantid/Framework/MDEvents/src/CoordTransformDistance.cpp
index 398786fc001e31d2a316a41c2813f1140a9cec32..5671395593c2295165ba4d6ade032ecb98d6372b 100644
--- a/Code/Mantid/Framework/MDEvents/src/CoordTransformDistance.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/CoordTransformDistance.cpp
@@ -133,6 +133,15 @@ namespace MDEvents
       return formattedXMLString;
   }
 
+  /**
+   * Coordinate transform id
+   * @return the type of coordinate transform
+   */
+  std::string CoordTransformDistance::id() const
+  {
+    return "CoordTransformDistance";
+  }
+
 } // namespace Mantid
 } // namespace MDEvents
 
diff --git a/Code/Mantid/Framework/MDEvents/src/MDWSTransform.cpp b/Code/Mantid/Framework/MDEvents/src/MDWSTransform.cpp
index 17458ad61caea6a5dc40bd1d3a28fd2780ae3660..d459d9fb0333eea7bea7f70552cc0e5290a7e998 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDWSTransform.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDWSTransform.cpp
@@ -198,7 +198,7 @@ Kernel::DblMatrix MDWSTransform::buildQTrahsf(MDEvents::MDWSDescription &TargWSD
   default: throw(std::invalid_argument("unrecognized conversion mode"));
 
   }
-
+  TargWSDescription.addProperty("W_MATRIX",Wmat.getVector(),true);
   return Transf*Scale*Wmat;
 }
 
diff --git a/Code/Mantid/Framework/Properties/Mantid.properties.template b/Code/Mantid/Framework/Properties/Mantid.properties.template
index ab9edf72aa619386b9d7e4c4099c8d7edf432797..a629dd29127e5bafcb85de1d5ff48f673d3820d2 100644
--- a/Code/Mantid/Framework/Properties/Mantid.properties.template
+++ b/Code/Mantid/Framework/Properties/Mantid.properties.template
@@ -200,11 +200,11 @@ algorithms.categories.hidden=Workflow\\Inelastic\\UsesPropertyManager;Workflow\\
 
 # ScriptRepository Properties: 
 
-# Url for the WebServer that support the upload of the files that the users want to share (not in usage)
-UploaderWebServer =
+# Url for the WebServer that support the upload of the files that the users want to share
+UploaderWebServer = @MANTIDPUBLISHER@
 # Local system path for the script repository.
 ScriptLocalRepository = 
 # Url for the remote script repository.
-ScriptRepository = http://download.mantidproject.org/master_builds/
+ScriptRepository = http://download.mantidproject.org/scriptrepository/
 # Pattern given to ScriptRepository that is used to hide entries from repository to the users. It is a csv string separated with ';' 
 ScriptRepositoryIgnore = *pyc;
diff --git a/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp b/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp
index aec78f1d7bb0bdb4680bb7627bd7f3fc8692b23f..32d26cdb9ca854a0c05647e3ec8d837e07b809e2 100644
--- a/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp
+++ b/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp
@@ -813,7 +813,8 @@ void export_dataitem()
       .def("isText", & API::Axis::isText)
       .def("label", & API::Axis::label)
       .def("getUnit", (const Mantid::Kernel::Unit_sptr & (Mantid::API::Axis::*)() const) &API::Axis::unit, return_value_policy<copy_const_reference>() )
-      .def("setUnit", & API::Axis::setUnit)
+      .def("setUnit", & API::Axis::setUnit,
+           return_value_policy<copy_const_reference>())
       .def("getValue", & API::NumericAxis::getValue)
       ;
 
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp
index 82b49b046a037f25e610f87b6dacb89e66c05a38..53e50346978a89023902a800f236560911e691a3 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp
@@ -98,7 +98,8 @@ void export_Axis()
     .def("getValue", &Axis::getValue,
         Axis_getValue(args("index", "vertical_index"), "Returns the value at the given point on the Axis. The vertical axis index [default=0]")) 
     .def("extractValues", &extractAxisValues, "Return a numpy array of the axis values")
-    .def("setUnit", & Axis::setUnit, "Set the unit for this axis")
+    .def("setUnit", & Axis::setUnit, return_value_policy<copy_const_reference>(),
+         "Set the unit for this axis by name.")
     .def("setValue", &Axis::setValue, "Set a value at the given index")
     .def("getMin", &Axis::getMin, "Get min value specified on the axis")
     .def("getMax", &Axis::getMax, "Get max value specified on the axis")
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
index d8ca3d48dbfca33e9da6b0de96efee2bb6e0a665..f99bf353b2f7f2c60c24f83c8cf26208ea497678 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
@@ -20,6 +20,7 @@ set ( EXPORT_FILES
   src/Exports/StlContainers.cpp
   src/Exports/Logger.cpp
   src/Exports/Unit.cpp
+  src/Exports/Units.cpp
   src/Exports/BoundedValidator.cpp
   src/Exports/TimeSeriesProperty.cpp
   src/Exports/FilteredTimeSeriesProperty.cpp
@@ -174,4 +175,4 @@ endif()
 install ( FILES ${PY_FILES} DESTINATION ${BIN_DIR}/mantid/kernel )
 # packagesetup.py that will overwrite the ones from the built target
 install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGESETUP_PY}.install.py DESTINATION
-          ${BIN_DIR}/mantid/kernel RENAME ${PACKAGESETUP_PY}.py )
\ No newline at end of file
+          ${BIN_DIR}/mantid/kernel RENAME ${PACKAGESETUP_PY}.py )
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/UnitFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/UnitFactory.cpp
index 9b9046baa84e4ada9e77719977da395b8733d4e4..bd0850258e48776cbdd8b281d18e539e14a6debf 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/UnitFactory.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/UnitFactory.cpp
@@ -1,4 +1,5 @@
 #include "MantidKernel/UnitFactory.h"
+#include "MantidKernel/Unit.h"
 
 #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"
 
@@ -14,6 +15,8 @@ using namespace boost::python;
 void export_UnitFactory()
 {
   class_<UnitFactoryImpl, boost::noncopyable>("UnitFactoryImpl", no_init)
+    .def("create", &UnitFactoryImpl::create, "Creates a named unit if it exists in the factory")
+
     .def("getKeys", &UnitFactoryImpl::getKeys, return_value_policy<Policies::VectorToNumpy>(),
          "Returns a list of units available from the factory")
 
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Units.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Units.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..17fe520efe9788be48fe01cc1a5042e031d54479
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Units.cpp
@@ -0,0 +1,20 @@
+#include "MantidKernel/Unit.h"
+
+#include <boost/python/class.hpp>
+
+using Mantid::Kernel::Unit;
+using namespace Mantid::Kernel::Units;
+using namespace boost::python;
+
+// We only export the concrete unit classes that
+// have additional functionality over the base class
+
+void export_Label()
+{
+  class_<Label, bases<Unit>, boost::noncopyable>("Label", no_init)
+    .def("setLabel", (void (Label::*)(const std::string &,const std::string &))&Label::setLabel, 
+         (arg("caption"),arg("label")), "Set the caption (e.g.Temperature) & label (K) on the unit")
+    ;
+
+}
+
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
index acdd7cb027539a901ba9a2af5d5eba3d4c4955af..7d7f02a754463db829bac46b923563d0e9cc22b5 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
@@ -607,7 +607,7 @@ class SNSPowderReduction(PythonAlgorithm):
             print "[DB1050-1] Unable to get events of %s.  Error message: %s" % (str(wksp), str(e))
 
         if HAVE_MPI:
-            msg = "MPI Task = %s ;" %s (str(mpi.world.rank))
+            msg = "MPI Task = %s ;" % (str(mpi.world.rank))
             try: 
                 msg += "Number Events = ", wksp.getNumberEvents()
             except Exception as e: 
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/AxisTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/AxisTest.py
index bf2964aedd860ca1abfb2067387392d1835a5679..65d135871c4044ef8101792cfc6f6771a859c459 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/AxisTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/AxisTest.py
@@ -1,6 +1,6 @@
 import unittest
 from testhelpers import run_algorithm
-from mantid.api import NumericAxis, TextAxis
+from mantid.api import NumericAxis, TextAxis, mtd
 import numpy as np
 
 class AxisTest(unittest.TestCase):
@@ -9,13 +9,14 @@ class AxisTest(unittest.TestCase):
   
     def setUp(self):
         if self.__class__._test_ws is None:
-            alg = run_algorithm("Load", Filename="LOQ48127.raw", SpectrumMax=3, child=True)
+            alg = run_algorithm('CreateWorkspace', DataX=datY,DataY=datY,DataE=datY,NSpec=3,
+                                child=True)
             self.__class__._test_ws = alg.getProperty("OutputWorkspace").value
 
     def test_constructor_methods_return_the_correct_type(self):
         self.assertTrue(isinstance(NumericAxis.create(2),NumericAxis))
         self.assertTrue(isinstance(TextAxis.create(2),TextAxis))
-  
+
     def test_axis_meta_data(self):
         yAxis = self._test_ws.getAxis(1)
         self.assertTrue(isinstance(yAxis, SpectraAxis))
@@ -30,6 +31,23 @@ class AxisTest(unittest.TestCase):
         self.assertEquals(xunit.unitID(), "TOF")
         self.assertEquals(xunit.caption(), "Time-of-flight")
         self.assertEquals(xunit.label(), "microsecond")
+
+    def test_axis_unit_can_be_replaced(self):
+        datY=np.arange(100)
+        ns=3
+        alg = run_algorithm('CreateWorkspace', DataX=datY,DataY=datY,DataE=datY,NSpec=ns,
+                            VerticalAxisUnit="Label", VerticalAxisValues=taxis, child=True)
+        ws = alg.getPropertyValue("OutputWorkspace")
+
+        ws.getAxis(0).setUnit("Label").setLabel("Time", "ns")
+        ws.getAxis(1).setUnit("Label").setLabel("Temperature", "K")
+        
+        unitx = ws.getAxis(0).getUnit()
+        unity = ws.getAxis(1).getUnit()
+        self.assertEquals("Time",unitx.caption())
+        self.assertEquals("ns",unitx.label())
+        self.assertEquals("Temperature",unity.caption())
+        self.assertEquals("K",unity.label())
         
     def test_value_axis(self):
         yAxis = self._test_ws.getAxis(1)
@@ -46,7 +64,8 @@ class AxisTest(unittest.TestCase):
     def test_extract_string_axis_values_to_list(self):
         data = [1.,2.,3.]
         axis_values = ["a","b","c"]
-        alg = run_algorithm("CreateWorkspace", DataX=data, DataY=data, NSpec=3,VerticalAxisUnit="Text",VerticalAxisValues=axis_values,child=True)
+        alg = run_algorithm("CreateWorkspace", DataX=data, DataY=data, NSpec=3,
+                            VerticalAxisUnit="Text",VerticalAxisValues=axis_values,child=True)
         workspace = alg.getProperty("OutputWorkspace").value
         txtAxis = workspace.getAxis(1)
         self.assertTrue(txtAxis.isText())
@@ -54,4 +73,4 @@ class AxisTest(unittest.TestCase):
         self.assertTrue(isinstance(values, list))
         for index, value in enumerate(values):
             self.assertEquals(value, axis_values[index])
-        
\ No newline at end of file
+        
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt
index 9048ccb36195ca2a93977a53d262d7b756c68598..910c2d392132e22810cb74c4c466b2d613c7355f 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt
@@ -25,6 +25,7 @@ set ( TEST_PY_FILES
   QuatTest.py
   UnitConversionTest.py
   UnitFactoryTest.py
+  UnitsTest.py
   V3DTest.py
 )
 
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitFactoryTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitFactoryTest.py
index cc5db6043cdd00f853625d2f1f66980eb026bec2..7d4834abfc059561d12422cac8e880443ed5f207 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitFactoryTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitFactoryTest.py
@@ -1,10 +1,18 @@
 import unittest
-from mantid import UnitFactory, UnitFactoryImpl
+from mantid.kernel import UnitFactory, UnitFactoryImpl, Unit
 
 class UnitFactoryTest(unittest.TestCase):
 
     def test_alias_is_of_type_UnitFactoryImpl(self):
         self.assertTrue(isinstance(UnitFactory, UnitFactoryImpl))
+
+    def test_known_unit_can_be_created(self):
+        energy = UnitFactory.create("Energy")
+        self.assertTrue(isinstance(energy, Unit))
+
+    def test_unknown_unit_raises_error(self):
+        self.assertRaises(RuntimeError, UnitFactory.create, 
+                          "NotAUnit")
         
     def test_keys_returns_a_non_empty_python_list_of_unit_keys(self):
         known_units = UnitFactory.getKeys()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitsTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitsTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..c2b72d8743d5772ebe2ba3ea7129b11c0474e18e
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/UnitsTest.py
@@ -0,0 +1,15 @@
+import unittest
+from mantid.kernel import UnitFactory, Unit, Label
+
+class UnitsTest(unittest.TestCase):
+
+    def test_Label_is_returned_from_Factory(self):
+        label_unit = UnitFactory.Instance().create("Label")
+        self.assertTrue(isinstance(label_unit, Unit))
+        self.assertTrue(isinstance(label_unit, Label))
+        label_unit.setLabel("Temperature", "K")
+        self.assertEquals("Temperature", label_unit.caption())
+        self.assertEquals("K", label_unit.label())
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h b/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h
index c0f5d8e4fff9cff5026fc3809f4d8a8d8b5e43df..f20983fcd9f4b46b86543ffadcab1c52414758be 100644
--- a/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h
+++ b/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h
@@ -99,7 +99,7 @@ namespace API{
     
     void upload(const std::string & file_path, const std::string & comment,
                 const std::string & author, 
-                const std::string & description = std::string());
+                const std::string & email);
 
     /* Return true if there is a local repository installed*/
     bool isValid(void);
@@ -135,6 +135,8 @@ namespace API{
     std::string local_repository; 
     /// URL for the remote repository, usually: 
     std::string remote_url;
+    /// URL for the upload
+    std::string remote_upload;
 
 
   private:
diff --git a/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp b/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp
index d78ab5d86ebbae1ce93ecacb24965333f2562e42..79290bda08d5aec3e3c55071ed81233d783ec70b 100644
--- a/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp
+++ b/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp
@@ -18,6 +18,9 @@ using Mantid::Kernel::ConfigServiceImpl;
 #include <Poco/Exception.h>
 #include <Poco/Net/HTTPResponse.h>
 #include <Poco/Net/NetException.h>
+#include <Poco/Net/HTMLForm.h>
+#include "Poco/Net/FilePartSource.h"
+
 
 // Visual Studion compains with the inclusion of Poco/FileStream
 // disabling this warning.
@@ -46,17 +49,11 @@ using Mantid::Kernel::ConfigServiceImpl;
 
 using boost::property_tree::ptree;
 
-const std::string SCRIPTREPPATH = "scripts_repo/";
-
 namespace Mantid
 {
 namespace API
 {
 
-  static void notImplemented(){
-    throw ScriptRepoException("This method is not implemented yet"); 
-  };
-  
   static ScriptRepoException pocoException(const std::string & info, 
                                            Poco::Exception & ex){
     std::stringstream ss;     
@@ -112,10 +109,11 @@ namespace API
   {    
     // get the local path and the remote path
     std::string loc, rem; 
+    ConfigServiceImpl & config = ConfigService::Instance();
+    remote_upload = config.getString("UploaderWebServer"); 
     if (local_rep.empty() || remote.empty()){
-      ConfigServiceImpl & config = ConfigService::Instance();
       loc = config.getString("ScriptLocalRepository"); 
-      rem = config.getString("ScriptRepository");     
+      rem = config.getString("ScriptRepository");      
     }else{
       local_repository = local_rep; 
       remote_url = remote; 
@@ -265,7 +263,7 @@ namespace API
     // install the two files inside the given folder
     
     // download the repository json
-    doDownloadFile(std::string(remote_url).append("/repository.json"),
+    doDownloadFile(std::string(remote_url).append("repository.json"),
                    rep_json_file);
     g_log.debug() << "ScriptRepository downloaded repository information" << std::endl; 
     // creation of the instance of local_json file
@@ -442,7 +440,7 @@ namespace API
             st |= LOC; 
           // the file is remote_changed if the date of the pub_date file is 
           // diferent from the local downloaded pubdate.
-          if (entry.pub_date != entry.downloaded_pubdate)
+          if (entry.pub_date > entry.downloaded_pubdate)
             st |= REMO; 
           
           
@@ -616,7 +614,7 @@ namespace API
       return;
            
     // download the file
-    std::string url_path = std::string(remote_url).append(SCRIPTREPPATH).append(file_path); 
+    std::string url_path = std::string(remote_url).append(file_path); 
     Poco::TemporaryFile tmpFile; 
     doDownloadFile(url_path, tmpFile.path());
 
@@ -693,20 +691,131 @@ namespace API
   }
 
   /**
-     @todo Describe
-
+   * Uploads one file to the ScriptRepository web server, pushing, indirectly, to the 
+   * git repository. It will send in a POST method, the file and the following fields: 
+   *  - author : Will identify the author of the change
+   *  - email:  Will identify the email of the author
+   *  - comment: Description of the nature of the file or of the update
+   *  
+   * It will them upload to the URL pointed to UploaderWebServer. It will them receive a json file 
+   * with some usefull information about the success or failure of the attempt to upload. 
+   * In failure, it will be converted to an appropriated ScriptRepoException.
   */
   void ScriptRepositoryImpl::upload(const std::string & file_path, 
                                     const std::string & comment,
                                     const std::string & author, 
-                                   const std::string & description)
+                                    const std::string & email)
     
   {
-    UNUSED_ARG(file_path); 
-    UNUSED_ARG(comment);
-    UNUSED_ARG(author);
-    UNUSED_ARG(description);    
-    notImplemented();
+    using namespace Poco::Net;
+    try{
+      g_log.notice() << "ScriptRepository uploading " << file_path << " ..." << std::endl; 
+      Poco::URI uri(remote_upload); 
+      std::string path(uri.getPathAndQuery());
+      HTTPClientSession session(uri.getHost(), uri.getPort()); 
+      HTTPRequest req(HTTPRequest::HTTP_POST, path, 
+                      HTTPMessage::HTTP_1_0); 
+      HTMLForm form(HTMLForm::ENCODING_MULTIPART); 
+      
+      // add the fields author, email and comment
+      form.add("author",author); 
+      form.add("mail", email); 
+      form.add("comment",comment); 
+      
+      // deal with the folder
+      std::string relative_path = convertPath(file_path); 
+      std::string absolute_path = local_repository + relative_path; 
+      std::string folder = "./"; 
+      size_t pos = relative_path.rfind('/'); 
+      if (pos != std::string::npos)
+        folder += std::string(relative_path.begin(), relative_path.begin() + pos);
+      if (folder[folder.size()-1] != '/')
+        folder += "/";
+      g_log.information() << "Uploading to folder: " << folder << std::endl; 
+      form.add("path",folder); 
+      
+      // inserting the file
+      FilePartSource * m_file = new FilePartSource(absolute_path);
+      form.addPart("file",m_file); 
+      form.prepareSubmit(req);
+      
+      // get the size of everything
+      std::stringstream sst; 
+      form.write(sst); 
+      // move back to the begining of the file
+      m_file->stream().clear();
+      m_file->stream().seekg(0,std::ios::beg);  
+      // set the size
+      req.setContentLength((int)sst.str().size());
+      
+      std::ostream& ostr = session.sendRequest(req);
+      // send the request.
+      ostr << sst.str(); 
+      
+      HTTPResponse response;
+      std::istream & rs = session.receiveResponse(response);
+
+      g_log.information() << "ScriptRepository upload status: " 
+                          << response.getStatus() << " " << response.getReason() << std::endl;
+      std::stringstream answer; 
+      { // remove the status message from the end of the reply, in order not to get exception from the read_json parser
+        std::stringstream server_reply; 
+        std::string server_reply_str; 
+        Poco::StreamCopier::copyStream(rs, server_reply);
+        server_reply_str= server_reply.str(); 
+        size_t pos = server_reply_str.rfind("}");
+        if (pos != std::string::npos)
+          answer << std::string(server_reply_str.begin() , server_reply_str.begin() + pos + 1); 
+        else
+          answer << server_reply_str; 
+      }
+      g_log.debug() << "Form Output: " << answer.str() << std::endl; 
+
+      std::string info; 
+      std::string detail;
+      std::string published_date;
+        
+      ptree pt; 
+      try{
+        read_json(answer, pt); 
+        info = pt.get<std::string>("message",""); 
+        detail = pt.get<std::string>("detail","");
+        published_date = pt.get<std::string>("pub_date","");
+        std::string cmd = pt.get<std::string>("shell",""); 
+        if (!cmd.empty())
+          detail.append("\nFrom Command: ").append(cmd);
+                
+      }catch (boost::property_tree::json_parser_error & ex){
+        throw ScriptRepoException("Bad answer from the Server",
+                                  ex.what()); 
+      }
+
+      if (info == "success"){
+        g_log.notice() << "ScriptRepository:" << file_path <<  " uploaded!"<< std::endl; 
+        
+        // update the file
+        RepositoryEntry & entry = repo.at(file_path);
+        {
+          Poco::File local(absolute_path);
+          entry.downloaded_date = DateAndTime(Poco::DateTimeFormatter::format(local.getLastModified(),
+                                                                              timeformat));
+          // update the pub_date and downloaded_pubdate with the pub_date given by the upload. 
+          // this ensures that the status will be correctly defined.
+          if (!published_date.empty())
+            entry.pub_date = DateAndTime(published_date);
+          entry.downloaded_pubdate = entry.pub_date;
+          entry.status = BOTH_UNCHANGED;      
+        }
+        g_log.information() << "ScriptRepository update local json " << std::endl; 
+        updateLocalJson(file_path, entry); ///FIXME: performance! 
+        
+        
+      }else
+        throw ScriptRepoException(info, detail); 
+      
+    }catch(Poco::Exception & ex){
+      throw ScriptRepoException(ex.displayText(), ex.className()); 
+    }
   }
 
   /** The ScriptRepositoryImpl is set to be valid when the local repository path
@@ -733,7 +842,7 @@ namespace API
       f.moveTo(backup); 
     }
     try{
-      doDownloadFile(std::string(remote_url).append("/repository.json"),
+      doDownloadFile(std::string(remote_url).append("repository.json"),
                    rep_json_file);
     }catch(...){
       // restore file
@@ -851,10 +960,11 @@ namespace API
     Poco::URI uri(url_file);
     std::string path(uri.getPathAndQuery());
     if (path.empty()) path = "/";
-    std::string given_path = std::string(path.begin()+28, path.end());// remove the "/master_builds/scripts_repo/" from the path
+    std::string given_path = std::string(path.begin()+18, path.end());// remove the "/scriptrepository/" from the path
     //Configure Poco HTTP Client Session
     try{
       Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
+      session.setTimeout(Poco::Timespan(2,0));// 2 secconds
       Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path,
                                      Poco::Net::HTTPMessage::HTTP_1_1);
       Poco::Net::HTTPResponse response;
@@ -1056,8 +1166,12 @@ namespace API
       //      array.push_back(std::make_pair("auto_update",entry.auto_update)));
       local_json.push_back( std::pair<std::string, boost::property_tree::basic_ptree<std::string,std::string> >(path,array) );
     }else{
-      local_json.put(std::string(path).append(".downloaded_pubdate"), 
-                     entry.downloaded_pubdate.toFormattedString());
+      local_json.put(
+                boost::property_tree::ptree::path_type( std::string(path).append("!downloaded_pubdate"), '!'), 
+                entry.downloaded_pubdate.toFormattedString().c_str());
+      local_json.put(
+                boost::property_tree::ptree::path_type( std::string(path).append("!downloaded_date"), '!'), 
+                entry.downloaded_date.toFormattedString().c_str());
     }
     //g_log.debug() << "Update LOCAL JSON FILE" << std::endl; 
     #if defined(_WIN32) ||  defined(_WIN64)
diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt
index e6acb18a6b089d15335cf9f8098eaa663f06cf8c..e9d022d192817c63784430e80e66c3fa841eabef 100644
--- a/Code/Mantid/MantidPlot/CMakeLists.txt
+++ b/Code/Mantid/MantidPlot/CMakeLists.txt
@@ -901,6 +901,7 @@ add_subdirectory( docs )
 # List of .py files than must be run WITHIN MantidPlot.
 set ( MANTIDPLOT_TEST_PY_FILES
     MantidPlotAlgorithmDialogTest.py
+    MantidPlotInstrumentViewTest.py
 	MantidPlotSliceViewerTest.py 
 	MantidPlot1DPlotTest.py
 	MantidPlotProxiesTest.py
diff --git a/Code/Mantid/MantidPlot/mantidplot.py b/Code/Mantid/MantidPlot/mantidplot.py
index eecafdfcfddf47ce42fc0c6b379d1e61e5ce55de..a5c8831440ddc2065e7fa51c913e8febbbdf13e2 100644
--- a/Code/Mantid/MantidPlot/mantidplot.py
+++ b/Code/Mantid/MantidPlot/mantidplot.py
@@ -17,8 +17,9 @@ import os
 import time
 
 # Import into the global namespace qti classes that:
-#   (a) don't need a proxy & (b) can be constructed from python
-from _qti import PlotSymbol, ImageSymbol, ArrowMarker, ImageMarker
+#   (a) don't need a proxy & (b) can be constructed from python or (c) have enumerations within them
+from _qti import (PlotSymbol, ImageSymbol, ArrowMarker, ImageMarker,
+                  GraphOptions, InstrumentWindow, InstrumentWindowPickTab, InstrumentWindowMaskTab)
 
 # Make the ApplicationWindow instance accessible from the mantidplot namespace
 from _qti import app
@@ -446,17 +447,20 @@ def getMantidMatrix(name):
     """Get a handle to the named Mantid matrix"""
     return new_proxy(proxies.MantidMatrix, _qti.app.mantidUI.getMantidMatrix, name)
 
-def getInstrumentView(name, tab=-1):
+def getInstrumentView(name, tab=InstrumentWindow.RENDER):
     """Create an instrument view window based on the given workspace.
     
     Args:
         name: The name of the workspace.
-        tab: The index of the tab to display initially.
+        tab: The index of the tab to display initially, (default=InstrumentWindow.RENDER)
         
     Returns:
         A handle to the created instrument view widget.
     """
-    return new_proxy(proxies.MDIWindow, _qti.app.mantidUI.getInstrumentView, name,tab)
+    ads = _get_analysis_data_service()
+    if name not in ads:
+        raise ValueError("Workspace %s does not exist" % name)
+    return new_proxy(proxies.InstrumentWindow, _qti.app.mantidUI.getInstrumentView, name, tab)
 
 def importMatrixWorkspace(name, firstIndex=None, lastIndex=None, showDialog=False, visible=False):
     """Create a MantidMatrix object from the named workspace.
diff --git a/Code/Mantid/MantidPlot/mantidplotpy/proxies.py b/Code/Mantid/MantidPlot/mantidplotpy/proxies.py
index 51912424c3a4bc41ce52dffb9d3d2da99a810363..eebc64f417a687bf1bf309b4716ea002aa693659 100644
--- a/Code/Mantid/MantidPlot/mantidplotpy/proxies.py
+++ b/Code/Mantid/MantidPlot/mantidplotpy/proxies.py
@@ -527,6 +527,73 @@ class MantidMatrix(MDIWindow):
         """
         return new_proxy(Graph, self._getHeldObject().plotGraph2D, type)
 
+#-----------------------------------------------------------------------------
+class InstrumentWindow(MDIWindow):
+    """Proxy for the instrument window
+    """
+
+    def __init__(self, toproxy):
+        """Creates a proxy object around an instrument window
+
+        Args:
+            toproxy: The raw C object to proxy
+        """
+        QtProxyObject.__init__(self, toproxy)
+
+    def getTab(self, name_or_tab):
+        """Retrieve a handle to the given tab
+
+        Args:
+            name_or_index: A string containing the title or tab type
+
+        Returns:
+            A handle to a tab widget
+        """
+        handle = new_proxy(QtProxyObject, self._getHeldObject().getTab, name_or_tab)
+        if handle is None:
+            raise ValueError("Invalid tab title '%s'" % str(name_or_tab))
+        return handle
+
+    # ----- Deprecated functions -----
+    def changeColormap(self, filename=None):
+        import warnings
+        warnings.warn("InstrumentWindow.changeColormap has been deprecated. Use the render tab method instead.")
+        callable = QtProxyObject.__getattr__(self, "changeColormap")
+        if filename is None:
+            callable()
+        else:
+            callable(filename)
+        
+    def setColorMapMinValue(self, value):
+        import warnings
+        warnings.warn("InstrumentWindow.setColorMapMinValue has been deprecated. Use the render tab setMinValue method instead.")
+        QtProxyObject.__getattr__(self, "setColorMapMinValue")(value)
+
+    def setColorMapMaxValue(self, value):
+        import warnings
+        warnings.warn("InstrumentWindow.setColorMapMaxValue has been deprecated. Use the render tab setMaxValue method instead.")
+        QtProxyObject.__getattr__(self, "setColorMapMaxValue")(value)
+
+    def setColorMapRange(self, minvalue, maxvalue):
+        import warnings
+        warnings.warn("InstrumentWindow.setColorMapRange has been deprecated. Use the render tab setRange method instead.")
+        QtProxyObject.__getattr__(self, "setColorMapRange")(minvalue,maxvalue)
+
+    def setScaleType(self, scale_type):
+        import warnings
+        warnings.warn("InstrumentWindow.setScaleType has been deprecated. Use the render tab setScaleType method instead.")
+        QtProxyObject.__getattr__(self, "setScaleType")(scale_type)
+
+    def setViewType(self, view_type):
+        import warnings
+        warnings.warn("InstrumentWindow.setViewType has been deprecated. Use the render tab setSurfaceType method instead.")
+        QtProxyObject.__getattr__(self, "setViewType")(view_type)
+        
+    def selectComponent(self, name):
+        import warnings
+        warnings.warn("InstrumentWindow.selectComponent has been deprecated. Use the tree tab selectComponentByName method instead.")
+        QtProxyObject.__getattr__(self, "selectComponent")(name)
+        
 #-----------------------------------------------------------------------------
 class SliceViewerWindowProxy(QtProxyObject):
     """Proxy for a C++ SliceViewerWindow object.
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp
index ac03e821bacb8f7434f188bdc36710e12334f9c3..5beb2c4a50969359492d7f83866d76e2ff45c39c 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp
@@ -215,12 +215,20 @@ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspaceIfExists() const
 void InstrumentActor::applyMaskWorkspace()
 {
     if ( !m_maskWorkspace ) return;
-    Mantid::API::IAlgorithm * alg = Mantid::API::FrameworkManager::Instance().createAlgorithm("MaskDetectors",-1);
-    alg->setPropertyValue( "Workspace", getWorkspace()->name() );
-    alg->setProperty( "MaskedWorkspace", m_maskWorkspace );
-    alg->execute();
-    // After the algorithm finishes the InstrumentWindow catches the after-replace notification 
-    // and updates this instrument actor.
+    try
+    {
+        Mantid::API::IAlgorithm * alg = Mantid::API::FrameworkManager::Instance().createAlgorithm("MaskDetectors",-1);
+        alg->setPropertyValue( "Workspace", getWorkspace()->name() );
+        alg->setProperty( "MaskedWorkspace", m_maskWorkspace );
+        alg->execute();
+        // After the algorithm finishes the InstrumentWindow catches the after-replace notification
+        // and updates this instrument actor.
+    }
+    catch(...)
+    {
+        QMessageBox::warning(NULL,"MantidPlot - Warning","An error accured when applying the mask.","OK");
+    }
+    clearMaskWorkspace();
 }
 
 /**
@@ -621,15 +629,15 @@ void InstrumentActor::setAutoscaling(bool on)
 void InstrumentActor::initMaskHelper() const
 {
   if ( m_maskWorkspace ) return;
-  // extract the mask (if any) from the data to the mask workspace
-  const std::string maskName = "__InstrumentActor_MaskWorkspace";
-  Mantid::API::IAlgorithm * alg = Mantid::API::FrameworkManager::Instance().createAlgorithm("ExtractMask",-1);
-  alg->setPropertyValue( "InputWorkspace", getWorkspace()->name() );
-  alg->setPropertyValue( "OutputWorkspace", maskName );
-  alg->execute();
-
   try
   {
+    // extract the mask (if any) from the data to the mask workspace
+    const std::string maskName = "__InstrumentActor_MaskWorkspace";
+    Mantid::API::IAlgorithm * alg = Mantid::API::FrameworkManager::Instance().createAlgorithm("ExtractMask",-1);
+    alg->setPropertyValue( "InputWorkspace", getWorkspace()->name() );
+    alg->setPropertyValue( "OutputWorkspace", maskName );
+    alg->execute();
+
     m_maskWorkspace = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(Mantid::API::AnalysisDataService::Instance().retrieve(maskName));
     Mantid::API::AnalysisDataService::Instance().remove( maskName );
   }
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp
index bce9beee83537b120e922c4e8161770ff37544cd..2ed736f0ba377bd198014468605a06576c671347 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp
@@ -231,11 +231,38 @@ void InstrumentWindow::selectTab(int tab)
 }
 
 /**
- * Return the currently displayed tab.
+ * Returns the named tab or the current tab if none supplied
+ * @param title Optional title of a tab (default="")
  */
-InstrumentWindowTab *InstrumentWindow::getTab()const
+InstrumentWindowTab *InstrumentWindow::getTab(const QString & title)const
 {
-    return static_cast<InstrumentWindowTab*>(mControlsTab->currentWidget());
+  QWidget *tab(NULL);
+  if(title.isEmpty()) tab = mControlsTab->currentWidget();
+  else 
+  {
+    for(int i = 0; i < mControlsTab->count(); ++i)
+    {
+      if(mControlsTab->tabText(i) == title)
+      {
+        tab = mControlsTab->widget(i);
+        break;
+      }
+    }
+  }
+
+  if(tab) return qobject_cast<InstrumentWindowTab*>(tab);
+  else return NULL;
+}
+
+/**
+ * @param tab An enumeration for the tab to select
+ * @returns A pointer to the requested tab
+ */
+InstrumentWindowTab * InstrumentWindow::getTab(const Tab tab) const
+{
+  QWidget *widget = mControlsTab->widget(static_cast<int>(tab));
+  if(widget) return qobject_cast<InstrumentWindowTab*>(widget);
+  else return NULL;
 }
 
 /**
@@ -628,39 +655,53 @@ void InstrumentWindow::pickBackgroundColor()
 	setBackgroundColor(color);
 }
 
-void InstrumentWindow::saveImage()
+/**
+ * Saves the current image buffer as a png file.
+ * @param filename Optional filename. Empty string raises a save dialog
+ */
+void InstrumentWindow::saveImage(QString filename)
 {
+  QString defaultExt = ".png";
   QList<QByteArray> formats = QImageWriter::supportedImageFormats();
-  QListIterator<QByteArray> itr(formats);
-  QString filter("");
-  while( itr.hasNext() )
+  if(filename.isEmpty())
   {
-    filter += "*." + itr.next();
-    if( itr.hasNext() )
+    QListIterator<QByteArray> itr(formats);
+    QString filter("");
+    while( itr.hasNext() )
     {
-      filter += ";;";
+      filter += "*." + itr.next();
+      if( itr.hasNext() )
+      {
+        filter += ";;";
+      }
     }
-  }
-  QString selectedFilter = "*.png";
-  QString filename = getSaveFileName("Save image ...", filter, &selectedFilter);
+    QString selectedFilter = "*" + defaultExt;
+    filename = getSaveFileName("Save image ...", filter, &selectedFilter);
 
-  // If its empty, they cancelled the dialog
-  if( filename.isEmpty() ) return;
+    // If its empty, they cancelled the dialog
+    if( filename.isEmpty() ) return;
+  }
   
   QFileInfo finfo(filename);
-
   QString ext = finfo.completeSuffix();
+
   if( ext.isEmpty() )
   {
-    filename += selectedFilter.section("*", 1);
+    filename += defaultExt;
     ext = QFileInfo(filename).completeSuffix();
   }
   else
   {
-    QStringList extlist = filter.split(";;");
-    if( !extlist.contains("*." + ext) )
+    if( !formats.contains(ext.toAscii()) )
     {
-      QMessageBox::warning(this, "MantidPlot", "Unsupported file extension, please use one from the supported list.");
+      QString msg("Unsupported file extension. Choose one of the following: ");
+      QListIterator<QByteArray> itr(formats);
+      while( itr.hasNext() )
+      {
+        msg += itr.next() + ", ";
+      }
+      msg.chop(2);// Remove last space and comma
+      QMessageBox::warning(this, "MantidPlot", msg);
       return;
     }
   }
@@ -983,20 +1024,7 @@ void InstrumentWindow::dropEvent( QDropEvent* e )
   if (text.startsWith("Workspace::"))
   {
     QStringList wsName = text.split("::");
-    Mantid::API::IPeaksWorkspace_sptr pws = boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(
-      Mantid::API::AnalysisDataService::Instance().retrieve(wsName[1].toStdString()));
-    auto surface = boost::dynamic_pointer_cast<UnwrappedSurface>( getSurface() );
-    if (pws && surface)
-    {
-      surface->setPeaksWorkspace(pws);
-      updateInstrumentView();
-      e->accept();
-      return;
-    }
-    else if (pws && !surface)
-    {
-      QMessageBox::warning(this,"MantidPlot - Warning","Please change to an unwrapped view to see peak labels.");
-    }
+    if(this->overlay(wsName[1])) e->accept();    
   }
   e->ignore();
 }
@@ -1046,6 +1074,30 @@ void InstrumentWindow::setColorMapAutoscaling(bool on)
   updateInstrumentView();
 }
 
+/**
+ *  Overlay a workspace with the given name
+ * @param wsName The name of a workspace in the ADS
+ * @returns True if the overlay was successful, false otherwise
+ */
+bool InstrumentWindow::overlay(const QString & wsName)
+{
+  using namespace Mantid::API;
+  auto pws = boost::dynamic_pointer_cast<IPeaksWorkspace>(AnalysisDataService::Instance().retrieve(wsName.toStdString()));
+  auto surface = boost::dynamic_pointer_cast<UnwrappedSurface>( getSurface() );
+  bool success(false);
+  if (pws && surface)
+  {
+    surface->setPeaksWorkspace(pws);
+    updateInstrumentView();
+    success = true;
+  }
+  else if (pws && !surface)
+  {
+    QMessageBox::warning(this,"MantidPlot - Warning","Please change to an unwrapped view to see peak labels.");
+  }
+  return success;
+}
+
 /**
  * Remove all peak overlays from the instrument display.
  */
@@ -1224,17 +1276,10 @@ void InstrumentWindow::enableOpenGL( bool on )
 /// Private slot to toggle between the GL and simple instrument display widgets
 void InstrumentWindow::enableGL( bool on )
 {
-  m_useOpenGL = on;
-  if ( m_surfaceType == FULL3D )
-  {
-    // always OpenGL in 3D
-    selectOpenGLDisplay( true );
-  }
-  else
-  {
-    // select the display
-    selectOpenGLDisplay( on );
-  }
+  if ( m_surfaceType == FULL3D ) m_useOpenGL = true; // always OpenGL in 3D
+  else m_useOpenGL = on;
+
+  selectOpenGLDisplay(m_useOpenGL);
 }
 
 /// True if the GL instrument display is currently on
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h
index 9dde5ddc70da9f56372f3483354095da3fe9ab30..be9f36b9bed213aef3e0a5e670e7bca97aeb5f6b 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h
@@ -51,7 +51,10 @@ class QSettings;
   \date   September 2008
   \version 1.0
 
-  This is a QT widget for the controls and display of instrument geometry
+  This is a QT widget for the controls and display of instrument geometry. 
+  The user documentation can be found at http://www.mantidproject.org/MantidPlot:_Instrument_View
+  and needs to be updated whenever the instrument view functionality changes.
+
  */
 class InstrumentWindow : public MdiSubWindow, public MantidQt::API::WorkspaceObserver, public Mantid::API::AlgorithmObserver
 {
@@ -91,7 +94,8 @@ public:
   bool blocked()const{return m_blocked;}
   void selectTab(int tab);
   void selectTab(Tab tab){selectTab(int(tab));}
-  InstrumentWindowTab *getTab()const;
+  InstrumentWindowTab *getTab(const QString & title="") const;
+  InstrumentWindowTab *getTab(const Tab tab) const;
   /// Get a filename for saving
   QString getSaveFileName(const QString& title, const QString& filters, QString* selectedFilter = NULL);
 
@@ -133,23 +137,26 @@ public slots:
   void executeAlgorithm(Mantid::API::IAlgorithm_sptr);
 
   void setupColorMap();
-  void changeColormap(const QString & filename = "");
-  void changeScaleType(int);
-  void changeColorMapMinValue(double minValue);
-  void changeColorMapMaxValue(double maxValue);
-  void changeColorMapRange(double minValue, double maxValue);
+
+  void changeColormap(const QString & filename = ""); // Deprecated
+  void changeScaleType(int);// Deprecated
+  void changeColorMapMinValue(double minValue); // Deprecated
+  void changeColorMapMaxValue(double maxValue); // Deprecated
+  void changeColorMapRange(double minValue, double maxValue); // Deprecated
   void setIntegrationRange(double,double);
   void setBinRange(double,double);
-  void setColorMapAutoscaling(bool);
+  void setColorMapAutoscaling(bool); // Deprecated
 
   void setViewDirection(const QString&);
   void pickBackgroundColor();
-  void saveImage();
+  void saveImage(QString filename);
   void setInfoText(const QString&);
   void set3DAxesState(bool);
   void setSurfaceType(int);
   void setWireframe(bool);
 
+  /// Overlay a workspace with the given name
+  bool overlay(const QString & wsName);
   void clearPeakOverlays();
   void setPeakLabelPrecision(int n);
   void setShowPeakRowFlag(bool on);
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp
index e922c4097834694baa56aa92942157da52730c9e..3fc0b19ac6b94e2373af0f86156bb7819bfdd49a 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp
@@ -47,6 +47,7 @@
 #include <QToolTip>
 #include <QTemporaryFile>
 #include <QGroupBox>
+#include <QCheckBox>
 
 #include "MantidQtAPI/FileDialogHandler.h"
 
@@ -147,13 +148,13 @@ m_userEditing(true)
 
   // Create property browser
 
-    /* Create property managers: they create, own properties, get and set values  */
+  /* Create property managers: they create, own properties, get and set values  */
 
   m_groupManager = new QtGroupPropertyManager(this);
   m_doubleManager = new QtDoublePropertyManager(this);
   connect(m_doubleManager,SIGNAL(propertyChanged(QtProperty*)),this,SLOT(doubleChanged(QtProperty*)));
 
-     /* Create editors and assign them to the managers */
+  /* Create editors and assign them to the managers */
 
   DoubleEditorFactory *doubleEditorFactory = new DoubleEditorFactory(this);
 
@@ -164,14 +165,22 @@ m_userEditing(true)
 
   // Algorithm buttons
 
-  m_apply = new QPushButton("Apply Mask(s) to Workspace(data)");
+  m_apply = new QPushButton("Apply to Data");
   m_apply->setToolTip("Apply current mask to the data workspace. Cannot be reverted.");
   connect(m_apply,SIGNAL(clicked()),this,SLOT(applyMask()));
 
+  m_apply_to_view = new QPushButton("Apply to View");
+  m_apply_to_view->setToolTip("Apply current mask to the view.");
+  connect(m_apply_to_view,SIGNAL(clicked()),this,SLOT(applyMaskToView()));
+
   m_clear_all = new QPushButton("Clear All");
   m_clear_all->setToolTip("Clear all masking that have not been applied to the data.");
   connect(m_clear_all,SIGNAL(clicked()),this,SLOT(clearMask()));
 
+  m_savegroupdet = new QCheckBox("Grouped Detectors");
+  m_savegroupdet->setToolTip("If checked, then save masked with grouped detectors. ");
+  m_savegroupdet->setChecked(false);
+
   m_save_as_workspace_exclude = new QAction("As Mask to workspace",this);
   m_save_as_workspace_exclude->setToolTip("Save current mask to mask workspace.");
   connect(m_save_as_workspace_exclude,SIGNAL(activated()),this,SLOT(saveMaskToWorkspace()));
@@ -213,7 +222,7 @@ m_userEditing(true)
   connect(m_sum_to_workspace,SIGNAL(activated()),this,SLOT(sumDetsToWorkspace()));
 
   // Save button and its menus
-  m_saveButton = new QPushButton("Save");
+  m_saveButton = new QPushButton("Apply and Save");
   m_saveButton->setToolTip("Save current masking/grouping to a file or a workspace.");
 
   m_saveMask = new QMenu(this);
@@ -237,26 +246,77 @@ m_userEditing(true)
   m_saveGroup->addAction(m_save_group_file_exclude);
   connect(m_saveGroup,SIGNAL(hovered(QAction*)),this,SLOT(showSaveMenuTooltip(QAction*)));
 
-
+  QGroupBox *box = new QGroupBox("View");
   QGridLayout* buttons = new QGridLayout();
-  buttons->addWidget(m_apply,0,0,1,2);
+  buttons->addWidget(m_apply_to_view,0,0,1,2);
   buttons->addWidget(m_saveButton,1,0);
   buttons->addWidget(m_clear_all,1,1);
-  
-  layout->addLayout(buttons);
+  buttons->addWidget(m_savegroupdet, 2, 0, 1, 2);
+
+  box->setLayout(buttons);
+  layout->addWidget(box);
+
+  box = new QGroupBox("Workspace");
+  buttons = new QGridLayout();
+  buttons->addWidget(m_apply,0,0);
+  box->setLayout(buttons);
+  layout->addWidget(box);
 
 }
 
+/**
+  * Initialize the tab when new projection surface is created.
+  */
 void InstrumentWindowMaskTab::initSurface()
 {
   connect(m_instrWindow->getSurface().get(),SIGNAL(shapeCreated()),this,SLOT(shapeCreated()));
   connect(m_instrWindow->getSurface().get(),SIGNAL(shapeSelected()),this,SLOT(shapeSelected()));
   connect(m_instrWindow->getSurface().get(),SIGNAL(shapesDeselected()),this,SLOT(shapesDeselected()));
   connect(m_instrWindow->getSurface().get(),SIGNAL(shapeChanged()),this,SLOT(shapeChanged()));
-  enableApply();
-  enableClear();
+  connect(m_instrWindow->getSurface().get(),SIGNAL(shapesCleared()),this,SLOT(shapesCleared()));
+  enableApplyButtons();
 }
 
+/**
+ * Selects between masking/grouping
+ * @param mode The required mode, @see Mode
+ */
+void InstrumentWindowMaskTab::setMode(Mode mode)
+{
+  switch(mode)
+  {
+  case Mask: toggleMaskGroup(true);
+    break;
+  case Group: toggleMaskGroup(false);
+    break;
+  default: throw std::invalid_argument("Invalid Mask tab mode. Use Mask/Group.");
+  };
+
+
+}
+
+void InstrumentWindowMaskTab::selectTool(Activity tool)
+{
+  switch(tool)
+  {
+  case Move: m_move->setChecked(true);
+    break;
+  case Select: m_pointer->setChecked(true);
+    break;
+  case DrawEllipse: m_ellipse->setChecked(true);
+    break;
+  case DrawRectangle: m_rectangle->setChecked(true);
+    break;
+  case DrawEllipticalRing: m_ring_ellipse->setChecked(true);
+    break;
+  case DrawRectangularRing: m_ring_rectangle->setChecked(true);
+    break;
+  default: throw std::invalid_argument("Invalid tool type.");
+  }
+  setActivity();
+}
+
+
 /**
   * Set tab's activity based on the currently selected tool button.
   */
@@ -282,42 +342,53 @@ void InstrumentWindowMaskTab::setActivity()
   }
   else if (m_rectangle->isChecked())
   {
-    m_activity = DrawEllipse;
+    m_activity = DrawRectangle;
     m_instrWindow->getSurface()->startCreatingShape2D("rectangle",borderColor,fillColor);
     m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
   }
   else if (m_ring_ellipse->isChecked())
   {
-    m_activity = DrawEllipse;
+    m_activity = DrawEllipticalRing;
     m_instrWindow->getSurface()->startCreatingShape2D("ring ellipse",borderColor,fillColor);
     m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
   }
   else if (m_ring_rectangle->isChecked())
   {
-    m_activity = DrawEllipse;
+    m_activity = DrawRectangularRing;
     m_instrWindow->getSurface()->startCreatingShape2D("ring rectangle",borderColor,fillColor);
     m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
   }
   m_instrWindow->updateInfoText();
 }
 
+/**
+  * Slot responding on creation of a new masking shape.
+  */
 void InstrumentWindowMaskTab::shapeCreated()
 {
   setSelectActivity();
-  enableApply();
-  enableClear();
+  enableApplyButtons();
 }
 
+/**
+  * Slot responding on selection of a new masking shape.
+  */
 void InstrumentWindowMaskTab::shapeSelected()
 {
   setProperties();
 }
 
+/**
+  * Slot responding on deselecting all masking shapes.
+  */
 void InstrumentWindowMaskTab::shapesDeselected()
 {
   clearProperties();
 }
 
+/**
+  * Slot responding on a change of a masking shape.
+  */
 void InstrumentWindowMaskTab::shapeChanged()
 {
   if (!m_left) return; // check that everything is ok
@@ -343,6 +414,14 @@ void InstrumentWindowMaskTab::shapeChanged()
   m_userEditing = true;
 }
 
+/**
+  * Slot responding on removing all masking shapes.
+  */
+void InstrumentWindowMaskTab::shapesCleared()
+{
+    enableApplyButtons();
+}
+
 /**
   * Removes the mask shapes from the screen.
   */
@@ -355,8 +434,7 @@ void InstrumentWindowMaskTab::showEvent (QShowEvent *)
 {
   setActivity();
   m_instrWindow->setMouseTracking(true);
-  enableApply();
-  enableClear();
+  enableApplyButtons();
   m_instrWindow->updateInstrumentView(true);
 }
 
@@ -456,11 +534,19 @@ void InstrumentWindowMaskTab::applyMask()
   storeMask();
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
   m_instrWindow->getInstrumentActor()->applyMaskWorkspace();
-  enableApply();
-  enableClear();
+  enableApplyButtons();
   QApplication::restoreOverrideCursor();
 }
 
+/**
+  * Apply the constructed mask to the view only.
+  */
+void InstrumentWindowMaskTab::applyMaskToView()
+{
+    storeMask();
+    enableApplyButtons();
+}
+
 /**
   * Remove all masking that has not been applied to the data workspace.
   */
@@ -469,8 +555,7 @@ void InstrumentWindowMaskTab::clearMask()
   clearShapes();
   m_instrWindow->getInstrumentActor()->clearMaskWorkspace();
   m_instrWindow->updateInstrumentView();
-  enableApply();
-  enableClear();
+  enableApplyButtons();
 }
 
 /**
@@ -619,14 +704,21 @@ void InstrumentWindowMaskTab::showSaveMenuTooltip(QAction *action)
   */
 void InstrumentWindowMaskTab::toggleMaskGroup(bool maskOn)
 {
-    enableApply();
+    m_masking_on->blockSignals(true);
+    m_masking_on->setChecked(maskOn);
+    m_grouping_on->setChecked(!maskOn);
+    m_masking_on->blockSignals(false);
+
+    enableApplyButtons();
     if ( maskOn )
     {
         m_saveButton->setMenu(m_saveMask);
+        m_saveButton->setText("Apply and Save");
     }
     else
     {
         m_saveButton->setMenu(m_saveGroup);
+        m_saveButton->setText("Save");
     }
     m_instrWindow->getSurface()->changeBorderColor(getShapeBorderColor());
     m_instrWindow->updateInstrumentView();
@@ -640,13 +732,11 @@ void InstrumentWindowMaskTab::toggleMaskGroup(bool maskOn)
 void InstrumentWindowMaskTab::saveMaskingToWorkspace(bool invertMask)
 {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-
   // Make sure we have stored the Mask in the helper MaskWorkspace
   storeMask();
-
   setSelectActivity();
   createMaskWorkspace(invertMask, false);
-
+  enableApplyButtons();
   QApplication::restoreOverrideCursor();
 }
 
@@ -671,14 +761,19 @@ void InstrumentWindowMaskTab::saveMaskingToFile(bool invertMask)
 
     if (!fileName.isEmpty())
     {
+      // Check option "GroupedDetectors"
+      bool groupeddetectors = m_savegroupdet->isChecked();
+
+      // Call "SaveMask()"
       Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("SaveMask",-1);
       alg->setProperty("InputWorkspace",boost::dynamic_pointer_cast<Mantid::API::Workspace>(outputWS));
       alg->setPropertyValue("OutputFile",fileName.toStdString());
-      alg->setProperty("GroupedDetectors",true);
+      alg->setProperty("GroupedDetectors", groupeddetectors);
       alg->execute();
     }
     Mantid::API::AnalysisDataService::Instance().remove( outputWS->name() );
   }
+  enableApplyButtons();
   QApplication::restoreOverrideCursor();
 }
 
@@ -700,9 +795,6 @@ void InstrumentWindowMaskTab::saveMaskingToCalFile(bool invertMask)
     {
       clearShapes();
       QString fileName = m_instrWindow->getSaveFileName("Select location and name for the mask file", "cal files (*.cal)");
-
-      std::cerr << "File " << fileName.toStdString() << std::endl;
-
       if (!fileName.isEmpty())
       {
         Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("MaskWorkspaceToCalFile",-1);
@@ -713,6 +805,7 @@ void InstrumentWindowMaskTab::saveMaskingToCalFile(bool invertMask)
       }
       Mantid::API::AnalysisDataService::Instance().remove( outputWS->name() );
     }
+    enableApplyButtons();
     QApplication::restoreOverrideCursor();
 }
 
@@ -745,31 +838,26 @@ std::string InstrumentWindowMaskTab::generateMaskWorkspaceName(bool temp) const
 
 /**
   * Sets the m_hasMaskToApply flag and
-  * enables/disables the Apply button.
+  * enables/disables the apply and clear buttons.
   */
-void InstrumentWindowMaskTab::enableApply()
+void InstrumentWindowMaskTab::enableApplyButtons()
 {
+    bool hasMaskShapes = m_instrWindow->getSurface()->hasMasks();
+    bool hasMaskWorkspace = m_instrWindow->getInstrumentActor()->hasMaskWorkspace();
+    bool hasMask = hasMaskShapes || hasMaskWorkspace;
     if ( isMasking() )
     {
-        bool hasMasks = m_instrWindow->getSurface()->hasMasks();
-        m_hasMaskToApply = hasMasks;
-        m_apply->setEnabled(hasMasks);
+        m_hasMaskToApply = hasMask;
+        m_apply->setEnabled(hasMask);
+        m_apply_to_view->setEnabled(hasMaskShapes);
     }
     else
     {
         m_apply->setEnabled(false);
+        m_apply_to_view->setEnabled(false);
     }
-}
-
-/**
-  * Enables/disables the ClearAll button.
-  */
-void InstrumentWindowMaskTab::enableClear()
-{
-    m_clear_all->setEnabled(
-                   m_instrWindow->getSurface()->hasMasks()
-                || m_instrWindow->getInstrumentActor()->hasMaskWorkspace()
-                );
+    m_saveButton->setEnabled(hasMask);
+    m_clear_all->setEnabled(hasMask);
 }
 
 /**
@@ -824,6 +912,7 @@ void InstrumentWindowMaskTab::storeMask()
     m_instrWindow->updateInstrumentView(); // to refresh the pick image
 
     QList<int> dets;
+    // get detectors covered by the shapes
     m_instrWindow->getSurface()->getMaskedDetectors(dets);
     if (!dets.isEmpty())
     {
@@ -834,11 +923,21 @@ void InstrumentWindowMaskTab::storeMask()
       }
       if ( !detList.empty() )
       {
-        m_instrWindow->getInstrumentActor()->getMaskWorkspace()->setMasked( detList );
-        m_instrWindow->getInstrumentActor()->update();
-        m_instrWindow->updateInstrumentDetectors();
+          // try to mask each detector separatly and ignore any failure
+          for(auto det = detList.begin(); det != detList.end(); ++det)
+          {
+              try
+              {
+                  m_instrWindow->getInstrumentActor()->getMaskWorkspace()->setMasked( *det );
+              }
+              catch(...){}
+          }
+          // update detector colours
+          m_instrWindow->getInstrumentActor()->update();
+          m_instrWindow->updateInstrumentDetectors();
       }
     }
+    // remove masking shapes
     clearShapes();
     QApplication::restoreOverrideCursor();
 }
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h
index 665653b37d2b55c95978c3881dc977cd39e179bc..6ba2d70d556a9bca57fb4c558765e48306031412 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h
@@ -51,9 +51,14 @@ class InstrumentWindowMaskTab: public InstrumentWindowTab
 {
   Q_OBJECT
 public:
-  enum Activity {Move = 0, Select = 1, DrawEllipse};
+  enum Mode {Mask, Group};
+  enum Activity {Move,Select,DrawEllipse,DrawRectangle,DrawEllipticalRing,DrawRectangularRing};
+
   InstrumentWindowMaskTab(InstrumentWindow* instrWindow);
   void initSurface();
+  void setMode(Mode mode);
+  void selectTool(Activity tool);
+
 signals:
   void executeAlgorithm(const QString&, const QString&);
 protected slots:
@@ -62,8 +67,10 @@ protected slots:
   void shapeSelected();
   void shapesDeselected();
   void shapeChanged();
+  void shapesCleared();
   void clearShapes();
   void applyMask();
+  void applyMaskToView();
   void storeMask();
   void clearMask();
   void saveInvertedMaskToWorkspace();
@@ -90,8 +97,7 @@ protected:
   void saveMaskingToFile(bool invertMask = false);
   void saveMaskingToCalFile(bool invertMask = false);
   std::string generateMaskWorkspaceName(bool temp = false) const;
-  void enableApply();
-  void enableClear();
+  void enableApplyButtons();
   void setSelectActivity();
   /// True if in masking mode, flase if in grouping.
   bool isMasking() const;
@@ -119,8 +125,11 @@ protected:
   QPushButton* m_ring_rectangle;
 
   QPushButton* m_apply;
+  QPushButton* m_apply_to_view;
   QPushButton* m_clear_all;
   QPushButton* m_saveButton;
+  QCheckBox* m_savegroupdet;
+
 
   QMenu* m_saveMask;
   QAction* m_save_as_workspace_include;
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
index 1a8c6c1097c2bb3c979c43239a456006fa844514..b2b281f00fda64779cebb490bb1decbc8d05d38a 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
@@ -1223,6 +1223,30 @@ bool InstrumentWindowPickTab::addToDisplayContextMenu(QMenu &context) const
     return res;
 }
 
+/**
+ * Select a tool on the tab
+ * @param tool One of the enumerated tool types, @see ToolType
+ */
+void InstrumentWindowPickTab::selectTool(const ToolType tool)
+{
+  switch(tool)
+  {
+  case Zoom: m_zoom->setChecked(true);
+    break;
+  case PixelSelect: m_one->setChecked(true);
+    break;
+  case TubeSelect: m_tube->setChecked(true);
+    break;
+  case PeakSelect: m_peak->setChecked(true);
+    break;
+  case PeakErase: m_peakSelect->setChecked(true);
+    break;
+  default: throw std::invalid_argument("Invalid tool type.");
+  }
+  setSelectionType();
+}
+
+
 void InstrumentWindowPickTab::singleDetectorTouched(int detid)
 {
   if (canUpdateTouchedDetector())
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h
index 33ec2226777b860033685b2d238804b4ff2b807f..a3ba9312c7ba3cb2c827a80d203956bdb5963458 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h
@@ -43,7 +43,9 @@ public:
   ///   SelectPeak: click on a peak marker or draw a rubber-band selector to select peak
   ///               markers. Selected peaks can be deleted by pressing the Delete key.
   enum SelectionType {Single=0,AddPeak,ErasePeak,SingleDetectorSelection,Tube};
+  enum ToolType {Zoom,PixelSelect,TubeSelect,PeakSelect,PeakErase};
   enum TubeXUnits {DETECTOR_ID = 0,LENGTH,PHI,NUMBER_OF_UNITS};
+
   InstrumentWindowPickTab(InstrumentWindow* instrWindow);
   void updatePick(int detid);
   bool canUpdateTouchedDetector()const;
@@ -53,6 +55,7 @@ public:
   void saveSettings(QSettings& settings) const;
   void loadSettings(const QSettings& settings);
   bool addToDisplayContextMenu(QMenu&) const;
+  void selectTool(const ToolType tool);
 
 public slots:
   void setTubeXUnits(int units);
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.cpp
index 155ca0f22abc24f068670353b1afcc13bd44857d..54397d67471429f8f722bc60095257f9b7dde0df 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.cpp
@@ -51,14 +51,14 @@ InstrumentWindowTab(instrWindow)
   // Save image control
   mSaveImage = new QPushButton(tr("Save image"));
   mSaveImage->setToolTip("Save the instrument image to a file");
-  connect(mSaveImage, SIGNAL(clicked()), m_instrWindow, SLOT(saveImage()));
+  connect(mSaveImage, SIGNAL(clicked()), this, SLOT(saveImage()));
 
   // Setup Display Setting menu
   QPushButton* displaySettings = new QPushButton("Display Settings",this);
   QMenu* displaySettingsMenu = new QMenu(this);
   connect(displaySettingsMenu, SIGNAL(aboutToShow()),this,SLOT(displaySettingsAboutToshow()));
   m_colorMap = new QAction("Color Map",this);
-  connect(m_colorMap,SIGNAL(triggered()),this,SLOT(changeColormap()));
+  connect(m_colorMap,SIGNAL(triggered()),this,SLOT(changeColorMap()));
   m_backgroundColor = new QAction("Background Color",this);
   connect(m_backgroundColor,SIGNAL(triggered()),m_instrWindow,SLOT(pickBackgroundColor()));
   m_lighting = new QAction("Lighting",this);
@@ -86,7 +86,7 @@ InstrumentWindowTab(instrWindow)
   bool useOpenGL = setting == "ON";
   m_instrWindow->enableGL( useOpenGL );
   m_GLView->setChecked( useOpenGL );
-  connect(m_GLView, SIGNAL( toggled(bool) ), m_instrWindow, SLOT( enableGL(bool) ));
+  connect(m_GLView, SIGNAL( toggled(bool) ), this, SLOT( enableGL(bool) ));
 
   displaySettingsMenu->addAction(m_colorMap);
   displaySettingsMenu->addAction(m_backgroundColor);
@@ -210,7 +210,7 @@ void InstrumentWindowRenderTab::setupColorBarScaling(const MantidColorMap& cmap,
 /**
  * Change color map button slot. This provides the file dialog box to select colormap or sets it directly a string is provided
  */
-void InstrumentWindowRenderTab::changeColormap(const QString &filename)
+void InstrumentWindowRenderTab::changeColorMap(const QString &filename)
 {
   m_instrWindow->changeColormap(filename);
 }
@@ -334,6 +334,20 @@ void InstrumentWindowRenderTab::displayDetectorsOnly(bool yes)
   m_displayDetectorsOnly->blockSignals(false);
 }
 
+/**
+ * Toggle use of OpenGL
+ *
+ * @param on :: True of false for on and off.
+ */
+void InstrumentWindowRenderTab::enableGL(bool on)
+{
+  m_instrWindow->enableGL(on);
+  m_GLView->blockSignals(true);
+  m_GLView->setChecked(m_instrWindow->isGLEnabled());
+  m_GLView->blockSignals(false);
+}
+
+
 void InstrumentWindowRenderTab::showEvent (QShowEvent *)
 {
   auto surface = getSurface();
@@ -357,6 +371,21 @@ void InstrumentWindowRenderTab::flipUnwrappedView(bool on)
   if (!surface) return;
   surface->setFlippedView(on);
   m_instrWindow->updateInstrumentView();
+  // Sync checkbox
+  m_flipCheckBox->blockSignals(true);
+  m_flipCheckBox->setChecked(on);
+  m_flipCheckBox->blockSignals(false);
+
+}
+
+/**
+ * Saves the current image buffer to the given file. An empty string raises a dialog
+ * for finding the file
+ * @param filename Optional full path of the saved image
+ */
+void InstrumentWindowRenderTab::saveImage(QString filename)
+{
+  m_instrWindow->saveImage(filename);
 }
 
 /**
@@ -466,6 +495,10 @@ void InstrumentWindowRenderTab::displaySettingsAboutToshow()
  */
 void InstrumentWindowRenderTab::setSurfaceType(int index)
 {
+  m_renderMode->blockSignals(true);
+  m_renderMode->setCurrentIndex( index );
+  m_renderMode->blockSignals(false);
+  
   m_instrWindow->setSurfaceType( index );
   showResetView( index );
   showFlipControl( index );
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.h
index bb32cd5d79ec2fcbf8daf5badadeb903a0be1508..4618868106f90cc3017bfea013176b4560969dab 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.h
@@ -47,17 +47,20 @@ public slots:
   void setRange(double minValue, double maxValue, bool apply = true);
   void showAxes(bool on);
   void displayDetectorsOnly(bool yes);
+  void enableGL(bool on);
   void setColorMapAutoscaling(bool);
+  void changeColorMap(const QString & filename = "");
+  void setSurfaceType(int);
+  void flipUnwrappedView(bool);
+  void saveImage(QString filename = "");
 
 private slots:
-  void changeColormap(const QString & filename = "");
+
   void showResetView(int);
   void showFlipControl(int);
-  void flipUnwrappedView(bool);
   /// Called before the display setting menu opens. Filters out menu options.
   void displaySettingsAboutToshow();
-  /// Change the type of the surface
-  void setSurfaceType(int);
+  /// Change the type of the surfac
   void surfaceTypeChanged(int);
   void colorMapChanged();
   void scaleTypeChanged(int);
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp
index c705a951913b385fd653741abc037f4a564eeea9..df3df8f36bf31436139dfc99a6b18f74f5143504 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp
@@ -45,10 +45,11 @@ ProjectionSurface::ProjectionSurface(const InstrumentActor* rootActor,const Mant
     m_redrawPicking(true)
 {
   connect(rootActor,SIGNAL(colorMapChanged()),this,SLOT(colorMapChanged()));
-  connect(&m_maskShapes,SIGNAL(shapeCreated()),this,SLOT(catchShapeCreated()));
-  connect(&m_maskShapes,SIGNAL(shapeSelected()),this,SLOT(catchShapeSelected()));
-  connect(&m_maskShapes,SIGNAL(shapesDeselected()),this,SLOT(catchShapesDeselected()));
-  connect(&m_maskShapes,SIGNAL(shapeChanged()),this,SLOT(catchShapeChanged()));
+  connect(&m_maskShapes,SIGNAL(shapeCreated()),this,SIGNAL(shapeCreated()));
+  connect(&m_maskShapes,SIGNAL(shapeSelected()),this,SIGNAL(shapeSelected()));
+  connect(&m_maskShapes,SIGNAL(shapesDeselected()),this,SIGNAL(shapesDeselected()));
+  connect(&m_maskShapes,SIGNAL(shapeChanged()),this,SIGNAL(shapeChanged()));
+  connect(&m_maskShapes,SIGNAL(cleared()),this,SIGNAL(shapesCleared()));
 
   // create and connect the pick input controller
   InputControllerPick* pickController = new InputControllerPick(this);
@@ -585,26 +586,6 @@ void ProjectionSurface::startCreatingShape2D(const QString& type,const QColor& b
   emit signalToStartCreatingShape2D(type,borderColor,fillColor);
 }
 
-void ProjectionSurface::catchShapeCreated()
-{
-  emit shapeCreated();
-}
-
-void ProjectionSurface::catchShapeSelected()
-{
-  emit shapeSelected();
-}
-
-void ProjectionSurface::catchShapesDeselected()
-{
-  emit shapesDeselected();
-}
-
-void ProjectionSurface::catchShapeChanged()
-{
-    emit shapeChanged();
-}
-
 /**
  * Return a combined list of peak parkers from all overlays
  * @param detID :: The detector ID of interest
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
index 0274e5410392ff9a961ecf3f28f23ba493c4ca88..e3ad67718dfd8711cee95172a7a5dccb89394a44 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
@@ -198,6 +198,7 @@ signals:
   void shapeSelected();
   void shapesDeselected();
   void shapeChanged();
+  void shapesCleared();
 
   // peaks
   void peaksWorkspaceAdded();
@@ -218,10 +219,6 @@ protected slots:
   void erasePeaks(const QRect& rect);
 
   void colorMapChanged();
-  void catchShapeCreated();
-  void catchShapeSelected();
-  void catchShapesDeselected();
-  void catchShapeChanged();
 
 protected:
   
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
index fb486cb76878cb1b2aabd576c475403a8c106b56..d239fdf0c22d6381b7a41ae0075b507413767e4b 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
@@ -105,6 +105,10 @@ void Shape2DCollection::removeShape(Shape2D* shape)
     m_shapes.removeOne(shape);
     delete shape;
   }
+  if (m_shapes.isEmpty())
+  {
+      emit cleared();
+  }
 }
 
 /**
@@ -121,6 +125,10 @@ void Shape2DCollection::removeShapes(const QList<Shape2D*>& shapeList)
     }
     removeShape( shape );
   }
+  if (m_shapes.isEmpty())
+  {
+      emit cleared();
+  }
 }
 
 /**
@@ -130,19 +138,6 @@ void Shape2DCollection::setWindow(const RectF &surface,const QRect& viewport) co
   m_viewport = viewport;
   m_surfaceRect = surface;
   m_surfaceRect.findTransform( m_transform, viewport );
-
-//  std::cerr << "surface:" << std::endl;
-//  std::cerr << surface.x0() << ' ' << surface.y0() << ' ' << surface.width() << ' ' << surface.height() << std::endl;
-//  std::cerr << "Viewport:" << std::endl;
-//  std::cerr << viewport.x() << ' ' << viewport.y() << ' ' << viewport.width() << ' ' << viewport.height() << std::endl;
-//  std::cerr << "Transform:" << std::endl;
-//  std::cerr << m_transform.m11() << ' '
-//            << m_transform.m12() << ' '
-//            << m_transform.m22() << ' '
-//            << m_transform.m31() << ' '
-//            << m_transform.m32() << ' '
-//            << m_transform.m33() << ' '
-//            << std::endl;
 }
 
 void Shape2DCollection::refit()
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
index f72f5db05dac198bdb3994d14dc4cf4bfe241b2f..2c97513987d66d8934239d40239efaa99c352f30 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
@@ -80,6 +80,7 @@ signals:
   void shapeSelected();
   void shapesDeselected();
   void shapeChanged();
+  void cleared();
 
 public slots:
   void addShape(const QString& type,int x,int y,const QColor& borderColor,const QColor& fillColor);
diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp
index 0a52878011aa3acb8d3436590beb389af98beb03..7f01a322e0e38cc5984dfb30000d03da04ff07c7 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp
@@ -89,15 +89,15 @@ QDockWidget(tr("Workspaces"),parent), m_mantidUI(mui), m_known_groups(), m_rerun
   m_loadMenu = new QMenu(this);
   
   QAction* loadFileAction = new QAction("File",this);
-  QAction *loadDAEAction = new QAction("from DAE",this);
+  QAction *liveDataAction = new QAction("Live Data",this);
   m_loadMapper = new QSignalMapper(this);
-  m_loadMapper->setMapping(loadDAEAction,"LoadDAE");
+  m_loadMapper->setMapping(liveDataAction,"StartLiveData");
   m_loadMapper->setMapping(loadFileAction,"Load");
-  connect(loadDAEAction,SIGNAL(activated()), m_loadMapper, SLOT(map()));
+  connect(liveDataAction,SIGNAL(activated()), m_loadMapper, SLOT(map()));
   connect(loadFileAction,SIGNAL(activated()),m_loadMapper,SLOT(map()));
   connect(m_loadMapper, SIGNAL(mapped(const QString &)), m_mantidUI, SLOT(executeAlgorithm(const QString&)));
   m_loadMenu->addAction(loadFileAction);
-  m_loadMenu->addAction(loadDAEAction);
+  m_loadMenu->addAction(liveDataAction);
   m_loadButton->setMenu(m_loadMenu);
 
   // SET UP SORT
diff --git a/Code/Mantid/MantidPlot/src/qti.sip b/Code/Mantid/MantidPlot/src/qti.sip
index a317b00acd1c75b89b644ea257cbdfd18df3fa19..79c181933fbcf9b2ca2cf9fe827b84a917808bb4 100644
--- a/Code/Mantid/MantidPlot/src/qti.sip
+++ b/Code/Mantid/MantidPlot/src/qti.sip
@@ -1272,25 +1272,306 @@ private:
   MantidMatrix(const MantidMatrix&);
 };
 
+class InstrumentWindowTab: QFrame
+{
+%TypeHeaderCode
+#include "src/Mantid/InstrumentWidget/InstrumentWindowTab.h"
+%End
+private:
+  InstrumentWindowTab(const InstrumentWindowTab &);
+};
+
 class InstrumentWindow: MdiSubWindow
 {
 %TypeHeaderCode
 #include "src/Mantid/InstrumentWidget/InstrumentWindow.h"
 %End
+
+%Docstring
+
+InstrumentWindow
+================
+
+    The InstrumentWindow contains functionality for exploring
+    a 3D model of an instrument. It is a tabbed widget offering
+    rendering, picking, masking and grouping functions. There is
+    also a tree view of the instrument hierarchy.
+
+    For further help see the functions defined on each of the following
+        - InstrumentWindowRenderTab
+        - InstrumentWindowPickTab
+        - InstrumentWindowMaskTab
+%End
+
 public:
-  void changeColormap() /PyName = changeColorMap/;
-  void changeColormap(const QString & file) /PyName = changeColorMap/;
+  enum SurfaceType { FULL3D, CYLINDRICAL_X, CYLINDRICAL_Y, CYLINDRICAL_Z, 
+                     SPHERICAL_X, SPHERICAL_Y, SPHERICAL_Z,
+                     RENDERMODE_SIZE };
+  enum Tab { RENDER, PICK, MASK, TREE };
+
+
+  InstrumentWindowTab * getTab(const QString & title) const;
+%Docstring
+    Returns a handler to the requested tab
+    
+    Args:
+        title The full title of a tab in the window
+
+    Returns:
+        a pointer to the requested tab widget   
+%End
+
+  InstrumentWindowTab * getTab(const Tab tab) const;
+%Docstring
+    Returns a handler to the requested tab
+
+    Args:
+        tab One of the Tab enumeration types: 
+	    InstrumentWindow.RENDER,InstrumentWindow.PICK,
+	    InstrumentWindow.MASK,InstrumentWindow.TREE
+
+    Returns:
+        a pointer to the requested tab widget   
+%End
+
+  void setBinRange(double min_value, double max_value);
+%Docstring
+    Updates the integration range over which the colours
+    are calculated
+
+    Args:
+        min_value The minimum value over which the data is integrated
+        max_value The maximum value over which the data is integrated
+%End
+
+  bool overlay(const QString & wsName);
+%Docstring
+    Overlays a workspace onto an unwrapped surface on the instrument view.
+    Raises a dialog box if the current surface is not unwrapped.
+
+    Args:
+        wsName The name of the workspace
+
+    Returns:
+        A boolean indicating if the overlay was successful or not 
+%End
+
+  // -- Deprecated in favour of specific tab functions --
+  // Deprecation is done in mantidplot.py module rather than using
+  // sip /Deprecated/annotation so that the message can be customised
+  void changeColormap();
+  void changeColormap(const QString & file);
   void setColorMapMinValue(double);
   void setColorMapMaxValue(double);
   void setColorMapRange(double, double);
-  void setBinRange(double, double);// /PyName = setBinRange/;
   void selectComponent(const QString &);
   void setScaleType(GraphOptions::ScaleType);
   void setViewType(const QString &);
+
 private:
+InstrumentWindow();
 InstrumentWindow(const InstrumentWindow &);
 };
 
+class InstrumentWindowRenderTab: InstrumentWindowTab
+{
+%TypeHeaderCode
+#include "src/Mantid/InstrumentWidget/InstrumentWindowRenderTab.h"
+%End
+
+public:
+
+  GraphOptions::ScaleType getScaleType() const;
+%Docstring
+    Returns the current scale type. 0=Linear, 1=Log10
+%End
+
+  void setScaleType(GraphOptions::ScaleType type);
+%Docstring
+    Set the scale type for the colour bar. 
+
+    Args:
+        type The new type Options are: GraphOptions.Linear, GraphOptions.Log10
+%End
+
+  void setAxis(const QString& axisName);
+%Docstring
+    Set the current viewing axis by name.
+
+    Args:
+       axisName The name of a view in a string: X+,X-,Y+,Y-,Z+,Z-
+%End
+
+  void setMinValue(double value, bool apply = true);
+%Docstring
+    Set the minimum value for the colour scale
+
+    Args:
+       value The new value for the minimum
+%End
+
+  void setMaxValue(double value, bool apply = true);
+%Docstring
+    Set the maximum value for the colour scale
+
+    Args:
+       value The new value for the maximum
+%End
+
+  void setRange(double minValue, double maxValue, bool apply = true);
+%Docstring
+    Set the range of the colour bar
+
+    Args:
+        minValue The new value for the minimum
+        maxValue The new value for the maximum 
+%End
+
+  void showAxes(bool on);
+%Docstring
+    Set the axes on/off
+
+    Args:
+        on True/False indicating whether the axes are visible
+%End
+
+  void setColorMapAutoscaling(bool on);
+%Docstring
+    Set whether the colour scale should auto scale when the data is updated
+
+    Args:
+        on True/False indicating whether auto scaling is active
+%End
+
+  void displayDetectorsOnly(bool yes);
+%Docstring
+    Set whether only detectors should be shown.
+
+    Args:
+        yes True/False indicating whether only detectors are shown
+%End
+
+  void enableGL(bool on);
+%Docstring
+    Toggle the use of OpenGL. This can only be used for the unwrapped views.
+
+    Args:
+        on True/False indicating whether OpenGL should be used.
+%End
+
+  void changeColorMap(const QString & filename = "");
+%Docstring
+    Change the color map for the given one. If blank then a dialog is raised
+
+    Args:
+        filename A filename giving the full path to a color map file
+%End
+
+  void setSurfaceType(int type);
+%Docstring
+    Set the surface type of the current window.
+
+    Args:
+        type A known suface type: FULL3D, CYLINDRICAL_X, CYLINDRICAL_Y, 
+                                  CYLINDRICAL_Z,SPHERICAL_X, SPHERICAL_Y, 
+                                  SPHERICAL_Z
+%End
+
+  void flipUnwrappedView(bool on);
+%Docstring
+    Set whether an unwrapped view is flipped
+
+    Args:
+        on True/False indicatingif to flip the view
+%End
+
+  void saveImage(QString filename = "");
+%Docstring
+    Save the current display buffer to an image file. The format is chosen by the filename extension and must
+    be one of .bmp,.jpeg,.jpeg,.png,.ppm,.tiff,.xbm,.xpm
+    
+    Args:
+        filename The filename for the saved image. An empty string raises a dialog box.
+%End
+
+private:
+  InstrumentWindowRenderTab();
+  InstrumentWindowRenderTab(const InstrumentWindowRenderTab &);
+};
+
+class InstrumentWindowPickTab: InstrumentWindowTab
+{
+%TypeHeaderCode
+#include "src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h"
+%End
+
+public:
+  enum ToolType {Zoom, PixelSelect, TubeSelect, PeakSelect, PeakErase};
+
+  void selectTool(const ToolType tool);
+%Docstring
+    Select the active tool.
+    
+    Args:
+        tool One of InstrumentWindowPickTab.{Zoom, PixelSelect, TubeSelect, PeakSelect, PeakErase}
+%End
+
+private:
+  InstrumentWindowPickTab();
+  InstrumentWindowPickTab(const InstrumentWindowPickTab &);
+};
+
+class InstrumentWindowMaskTab: InstrumentWindowTab
+{
+%TypeHeaderCode
+#include "src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h"
+%End
+
+public:
+  enum Mode {Mask, Group};
+  enum Activity {Move,Select,DrawEllipse,DrawRectangle,DrawEllipticalRing,DrawRectangularRing};
+
+  void setMode(Mode mode);
+%Docstring
+  Set the mode to either group/mask
+  
+  Args:
+      mode One of the Mode enumerations InstrumentWindowMaskTab.{Mask, Group}
+%End
+
+  void selectTool(Activity tool);
+%Docstring
+  Set the mode to either group/mask
+  
+  Args:
+      tool One of the Activity enumerations InstrumentWindowMaskTab.{Move,Select,DrawEllipse,DrawRectangle,DrawEllipticalRing,DrawRectangularRing}
+%End
+
+private:
+  InstrumentWindowMaskTab();
+  InstrumentWindowMaskTab(const InstrumentWindowMaskTab &);
+};
+
+class InstrumentWindowTreeTab: InstrumentWindowTab
+{
+%TypeHeaderCode
+#include "src/Mantid/InstrumentWidget/InstrumentWindowTreeTab.h"
+%End
+
+public:
+  void selectComponentByName(const QString& name);
+%Docstring
+    Sets the tree tab to center the view on the named component
+
+    Args:
+        name The name of a component in the instrument
+%End
+
+private:
+  InstrumentWindowTreeTab();
+  InstrumentWindowTreeTab(const InstrumentWindowTreeTab &);
+};
+
 class MantidUI: QObject
 {
 %TypeHeaderCode
@@ -1316,7 +1597,7 @@ public:
   InstrumentWindow* getInstrumentView(const QString &, int tab = -1);
 %MethodCode
   sipRes = sipCpp->getInstrumentView(*a0,a1);
-  sipRes->hide();
+  if(sipRes) sipRes->hide();
 %End
   MantidMatrix* importMatrixWorkspace(const QString&,int = -1, int = -1, bool = false, bool = false);
   Table* createTableFromSpectraList(const QString& tableName, const QString& workspaceName, 
diff --git a/Code/Mantid/MantidPlot/test/MantidPlotInstrumentViewTest.py b/Code/Mantid/MantidPlot/test/MantidPlotInstrumentViewTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..494737cd32d0ce57f76e7535b37edf5030779328
--- /dev/null
+++ b/Code/Mantid/MantidPlot/test/MantidPlotInstrumentViewTest.py
@@ -0,0 +1,74 @@
+""" 
+Test the interaction with the instrument view.
+Assertion that things work is difficult so mosts
+test will just that things don't crash.
+"""
+import mantidplottests
+from mantidplottests import *
+import time
+import numpy as np
+from PyQt4 import QtGui, QtCore
+
+# ===== Test workspace ======
+X1 = np.linspace(0,10, 100)
+Y1 = 1000*(np.sin(X1)**2) + X1*10
+X1 = np.append(X1, 10.1)
+
+X2 = np.linspace(2,12, 100)
+Y2 = 500*(np.cos(X2/2.)**2) + 20
+X2 = np.append(X2, 12.10)
+
+X = np.append(X1, X2)
+Y = np.append(Y1, Y2)
+E = np.sqrt(Y)
+
+CreateWorkspace(OutputWorkspace="loq_inst", DataX=list(X), DataY=list(Y), 
+                DataE=list(E), NSpec=2, UnitX="TOF", YUnitLabel="Counts",  
+                WorkspaceTitle="Faked data Workspace")
+LoadInstrument(Workspace="loq_inst", InstrumentName="LOQ")
+INST_WIN = getInstrumentView("loq_inst")
+
+class MantidPlotInstrumentViewTest(unittest.TestCase):
+
+    def test_invalid_tab_title_raises_exception(self):
+        self.assertRaises(ValueError, INST_WIN.getTab, "wont see this tab")
+
+    def test_get_tab_can_use_title_index_or_enum(self):
+        render_tab = INST_WIN.getTab("Render")
+        self.assertTrue(render_tab is not None)
+        render_tab = INST_WIN.getTab(InstrumentWindow.RENDER)
+        self.assertTrue(render_tab is not None)
+        render_tab = INST_WIN.getTab(0)
+        self.assertTrue(render_tab is not None)
+
+    def test_integration_range_can_be_changed(self):
+        INST_WIN.setBinRange(5,10)
+
+    def test_scale_type_can_be_changed(self):
+        render_tab = INST_WIN.getTab("Render")
+        current_scale = render_tab.getScaleType()
+        self.assertTrue(isinstance(current_scale, GraphOptions.ScaleType))
+        render_tab.setScaleType(GraphOptions.Log10)
+
+    def test_colour_range_can_be_changed(self):
+        render_tab = INST_WIN.getTab("Render")
+        render_tab.setMinValue(1.25)
+        render_tab.setMaxValue(1.75)
+        render_tab.setRange(1.35,1.85)
+
+    def test_display_options(self):
+        render_tab = INST_WIN.getTab("Render")
+        render_tab.showAxes(True)
+        render_tab.displayDetectorsOnly(True)
+        render_tab.setColorMapAutoscaling(False)
+        render_tab.setSurfaceType(0)
+        render_tab.setAxis("Y-")
+        render_tab.flipUnwrappedView(True)
+    
+    def test_closing_window_invalidates_reference(self):
+        inst = getInstrumentView("loq_inst")
+        inst.close()
+        self.assertTrue(inst._getHeldObject() is None)
+    
+# Run the unit tests
+mantidplottests.runTests(MantidPlotInstrumentViewTest)
diff --git a/Code/Mantid/MantidQt/API/src/RepoModel.cpp b/Code/Mantid/MantidQt/API/src/RepoModel.cpp
index 525e4d6feb9d030ae510773230eb2aa67662a318..00f7917e9e1a60a052b2b55ee2e9622ed8c89262 100644
--- a/Code/Mantid/MantidQt/API/src/RepoModel.cpp
+++ b/Code/Mantid/MantidQt/API/src/RepoModel.cpp
@@ -366,7 +366,6 @@ bool RepoModel::setData(const QModelIndex & index, const QVariant & value,
       }
 
       QWidget * father = qobject_cast<QWidget*>(QObject::parent());
-
       if (repo_ptr->fileInfo(path).directory){
         QMessageBox::information(father, 
                                  "Not Supported", 
diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml
index e5f3fd626c72e116b7805d3f8e67c067918b468e..3125b7b45a30691c6c9ee81a6e7e894b9c0e60ca 100644
--- a/Code/Mantid/instrument/Facilities.xml
+++ b/Code/Mantid/instrument/Facilities.xml
@@ -9,9 +9,6 @@
   <catalog name="ICat3Catalog">
   </catalog>
 
-  <httpproxy url="http://wwwcache.rl.ac.uk:8080">
-  </httpproxy>
-  
   <soapEndPoint url="https://facilities01.esc.rl.ac.uk:443/ICATService/ICAT">
   </soapEndPoint>