diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h
index 44567ab6c6297fe360294448a1f9a101cec99aae..ef9e1fb3ef3d11c1480515a422fab94808025f00 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h
@@ -9,6 +9,9 @@
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/System.h"
+#include "MantidDataObjects/WorkspaceSingleValue.h"
+
+using Mantid::DataObjects::WorkspaceSingleValue;
 
 
 namespace Mantid
@@ -57,6 +60,23 @@ namespace MDEvents
     /// Creates a new iterator pointing to the first cell in the workspace
     virtual Mantid::API::IMDIterator* createIterator(Mantid::Geometry::MDImplicitFunction * function = NULL) const;
 
+    void checkWorkspaceSize(const MDHistoWorkspace & other, std::string operation);
+
+    // --------------------------------------------------------------------------------------------
+    MDHistoWorkspace & operator+=(const MDHistoWorkspace & b);
+    MDHistoWorkspace & operator+=(const Mantid::DataObjects::WorkspaceSingleValue & b);
+
+    MDHistoWorkspace & operator-=(const MDHistoWorkspace & b);
+    MDHistoWorkspace & operator-=(const Mantid::DataObjects::WorkspaceSingleValue & b);
+
+    MDHistoWorkspace & operator*=(const MDHistoWorkspace & b);
+    MDHistoWorkspace & operator*=(const Mantid::DataObjects::WorkspaceSingleValue & b);
+
+    MDHistoWorkspace & operator/=(const MDHistoWorkspace & b);
+    MDHistoWorkspace & operator/=(const Mantid::DataObjects::WorkspaceSingleValue & b);
+
+
+
     // --------------------------------------------------------------------------------------------
     /** @return a const reference to the indexMultiplier array.
      * To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 + ...
@@ -81,12 +101,12 @@ namespace MDEvents
     /** @return the direct pointer to the error squared array. For speed */
     signal_t * getErrorSquaredArray()
     {
-      return m_errors;
+      return m_errorsSquared;
     }
 
-    void setTo(signal_t signal, signal_t error);
+    void setTo(signal_t signal, signal_t errorSquared);
 
-    void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t error);
+    void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t errorSquared);
 
     coord_t * getVertexesArray(size_t linearIndex, size_t & numVertices) const;
 
@@ -101,35 +121,35 @@ namespace MDEvents
       m_signals[index] = value;
     }
 
-    /// Sets the error at the specified index.
+    /// Sets the error (squared) at the specified index.
     void setErrorAt(size_t index, signal_t value)
     {
-      m_errors[index] = value;
+      m_errorsSquared[index] = value;
     }
 
 
     /// Get the error of the signal at the specified index.
     signal_t getErrorAt(size_t index) const
     {
-      return m_errors[index];
+      return m_errorsSquared[index];
     }
 
     /// Get the error at the specified index given in 4 dimensions (typically X,Y,Z,t)
     signal_t getErrorAt(size_t index1, size_t index2) const
     {
-      return m_errors[index1 + indexMultiplier[0]*index2];
+      return m_errorsSquared[index1 + indexMultiplier[0]*index2];
     }
 
     /// Get the error at the specified index given in 4 dimensions (typically X,Y,Z,t)
     signal_t getErrorAt(size_t index1, size_t index2, size_t index3) const
     {
-      return m_errors[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3];
+      return m_errorsSquared[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3];
     }
 
     /// Get the error at the specified index given in 4 dimensions (typically X,Y,Z,t)
     signal_t getErrorAt(size_t index1, size_t index2, size_t index3, size_t index4) const
     {
-      return m_errors[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3 + indexMultiplier[2]*index4];
+      return m_errorsSquared[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3 + indexMultiplier[2]*index4];
     }
 
 
@@ -190,7 +210,7 @@ namespace MDEvents
     /// Get the error of the signal at the specified index, normalized by cell volume
     signal_t getErrorNormalizedAt(size_t index) const
     {
-      return m_errors[index] * m_inverseVolume;
+      return m_errorsSquared[index] * m_inverseVolume;
     }
 
     /// Get the signal at the specified index given in 4 dimensions (typically X,Y,Z,t), normalized by cell volume
@@ -230,9 +250,9 @@ namespace MDEvents
     signal_t * m_signals;
 
     /// Linear array of errors for each bin
-    signal_t * m_errors;
+    signal_t * m_errorsSquared;
 
-    /// Length of the m_signals / m_errors arrays.
+    /// Length of the m_signals / m_errorsSquared arrays.
     size_t m_length;
 
     /// To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 + ...
diff --git a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
index 07cefdc99dee80b59e6b3467943df25ed8be723f..8a4badd49f43d10a15e76b14f35318795007553a 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
@@ -48,7 +48,7 @@ namespace MDEvents
   MDHistoWorkspace::~MDHistoWorkspace()
   {
     delete [] m_signals;
-    delete [] m_errors;
+    delete [] m_errorsSquared;
     delete [] indexMultiplier;
     delete [] m_vertexesArray;
     delete [] m_boxLength;
@@ -91,7 +91,7 @@ namespace MDEvents
 
     // Allocate the linear arrays
     m_signals = new signal_t[m_length];
-    m_errors = new signal_t[m_length];
+    m_errorsSquared = new signal_t[m_length];
 
     // Initialize them to NAN (quickly)
     signal_t nan = std::numeric_limits<signal_t>::quiet_NaN();
@@ -112,14 +112,14 @@ namespace MDEvents
   /** Sets all signals/errors in the workspace to the given values
    *
    * @param signal :: signal value to set
-   * @param error :: error value to set
+   * @param errorSquared :: error (squared) value to set
    */
-  void MDHistoWorkspace::setTo(signal_t signal, signal_t error)
+  void MDHistoWorkspace::setTo(signal_t signal, signal_t errorSquared)
   {
     for (size_t i=0; i < m_length; i++)
     {
       m_signals[i] = signal;
-      m_errors[i] = error;
+      m_errorsSquared[i] = errorSquared;
     }
   }
 
@@ -129,7 +129,7 @@ namespace MDEvents
   * @param signal :: signal value to set when function evaluates to false
   * @param error :: error value to set when function evaluates to false
   */
-  void MDHistoWorkspace::applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t error)
+  void MDHistoWorkspace::applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t errorSquared)
   {
     if (numDimensions<3) throw std::invalid_argument("Need 3 dimensions for ImplicitFunction.");
     Mantid::coord_t coord[3];
@@ -146,7 +146,7 @@ namespace MDEvents
           if (!function->isPointContained(coord))
           {
             m_signals[x + indexMultiplier[0]*y + indexMultiplier[1]*z] = signal;
-            m_errors[x + indexMultiplier[0]*y + indexMultiplier[1]*z] = error;
+            m_errorsSquared[x + indexMultiplier[0]*y + indexMultiplier[1]*z] = errorSquared;
           }
         }
       }
@@ -319,11 +319,54 @@ namespace MDEvents
     std::vector<signal_t> out;
     out.resize(m_length, 0.0);
     for (size_t i=0; i<m_length; ++i)
-        out[i] = m_errors[i];
+        out[i] = m_errorsSquared[i];
     // This copies again! :(
     return out;
   }
 
+  void MDHistoWorkspace::checkWorkspaceSize(const MDHistoWorkspace & other, std::string operation)
+  {
+    if (other.getNumDims() != this->getNumDims())
+      throw std::invalid_argument("Cannot perform the " + operation + " operation on this workspace. The number of dimensions does not match.");
+    if (other.m_length != this->m_length)
+      throw std::invalid_argument("Cannot perform the " + operation + " operation on this workspace. The length of the signals vector does not match.");
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Perform the += operation, element-by-element, for two MDHistoWorkspace's
+   *
+   * @param b :: workspace on the RHS of the operation
+   * @return *this after operation */
+  MDHistoWorkspace & MDHistoWorkspace::operator+=(const MDHistoWorkspace & b)
+  {
+    checkWorkspaceSize(b, "+=");
+    for (size_t i=0; i<m_length; ++i)
+    {
+      m_signals[i] += b.m_signals[i];
+      m_errorsSquared[i] += b.m_errorsSquared[i];
+    }
+    return *this;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Perform the += operation with a scalar as the RHS argument
+   *
+   * @param b :: WorkspaceSingleValue (signal and error) as the RHS argument
+   * @return *this after operation */
+  MDHistoWorkspace & MDHistoWorkspace::operator+=(const Mantid::DataObjects::WorkspaceSingleValue & b)
+  {
+    signal_t signal = b.dataY(0)[0];
+    signal_t errorSquared = b.dataE(0)[0];
+    errorSquared *= errorSquared;
+    for (size_t i=0; i<m_length; ++i)
+    {
+      m_signals[i] += signal;
+      m_errorsSquared[i] += errorSquared;
+    }
+    return *this;
+  }
+
+
 } // namespace Mantid
 } // namespace MDEvents
 
diff --git a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h
index d1388b4fb419288ebeeba7617b61f5b43df700c6..ffbba22b13423c16c3114a61bb63bd88cb7413f2 100644
--- a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h
+++ b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h
@@ -24,6 +24,23 @@ using namespace Mantid;
 class MDHistoWorkspaceTest : public CxxTest::TestSuite
 {
 public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static MDHistoWorkspaceTest *createSuite() { return new MDHistoWorkspaceTest(); }
+  static void destroySuite( MDHistoWorkspaceTest *suite ) { delete suite; }
+
+  MDHistoWorkspace_sptr two;
+  MDHistoWorkspace_sptr three;
+
+  MDHistoWorkspace_sptr ma
+
+  MDHistoWorkspaceTest()
+  {
+    MDEventsTestHelper::makeFakeMDHistoWorkspace(
+    two.
+  }
+
+
 
   void test_constructor()
   {
@@ -347,7 +364,7 @@ public:
   void test_getSignalAtCoord()
   {
     // 2D workspace with signal[i] = i (linear index)
-    MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10);
+    MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1.0, 2, 10);
     for (size_t i=0; i<100; i++)
       ws->setSignalAt(i, double(i));
     IMDWorkspace_sptr iws(ws);