diff --git a/Code/Mantid/Framework/MDEvents/CMakeLists.txt b/Code/Mantid/Framework/MDEvents/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a7afb549b0a1e302e3da13340b9a07dccb517af0
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/CMakeLists.txt
@@ -0,0 +1,77 @@
+# Source files
+set (SRC_FILES 
+#	src/MDEventWorkspace.cpp
+	src/MDBox.cpp               
+)
+
+# Header files
+set (INC_FILES
+	inc/MantidMDEvents/MDEvent.h
+	inc/MantidMDEvents/IMDBox.h
+	inc/MantidMDEvents/MDBox.h
+#	inc/MantidMDEvents/MDEventWorkspace.h
+	inc/MantidMDEvents/MDDimensionExtents.h
+)
+
+# Test files. Other source files required.
+set (TEST_FILES 
+)
+
+set ( GMOCK_TEST_FILES
+	test/MDEventTest.h  
+	test/MDBoxTest.h  
+)
+
+# Add the target for this directory
+add_library ( MDEvents ${SRC_FILES} ${INC_FILES})
+# Set the name of the generated library
+set_target_properties ( MDEvents PROPERTIES OUTPUT_NAME MantidMDEventss 
+                                                 COMPILE_DEFINITIONS IN_MANTID_MDEVENT )
+                                                 
+# Add to the 'Framework' group in VS
+set_property ( TARGET MDEvents PROPERTY FOLDER "Framework" )
+
+# Find hdf5 libraries
+if( WIN32 )
+#Exact libraries will need to be refined for windows 64/32 bit as they are different in third_party.
+   # this allows studio using dll-s for hdf5 
+    add_definitions ( -D_HDF5USEDLL_ )
+
+	set ( HDF5_INCLUDE_DIRS ${CMAKE_INCLUDE_PATH}/hdf5 )
+	# separate configuration files h5config.h for hdf5 in 32 and 64 bit versions
+	if ( CMAKE_CL_64 )
+		set ( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS}/win64 )
+	else()
+		set ( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS}/win32 )
+	endif()
+  # release hdf5dll.lib relates to hdf5.1.6 which does not have debug version when hdf5_18dll is release version for hdf5.1.8 and debug
+  # version for hdf5.1.8 is hdf5ddll.lib
+	set ( HDF5_LIBRARIES ${CMAKE_LIBRARY_PATH}/hdf5_18dll.lib ) 
+else()
+# unix build currently works wirh hdf1.6 linked against Nexus.
+# Some preprocessor command should already be defined to distinguish between 5.1.6 and 5.1.8 
+	find_package (HDF5 REQUIRED)
+	add_definitions ( -DHDF_1_6 )
+endif()
+
+include_directories(${HDF5_INCLUDE_DIRS} inc)
+target_link_libraries ( MDEvents ${MANTIDLIBS} ${HDF5_LIBRARIES})
+
+# Create test file projects
+if ( CXXTEST_FOUND )
+  include_directories(${HDF5_INCLUDE_DIRS} inc)
+  if ( GMOCK_FOUND AND GTEST_FOUND )
+    cxxtest_add_test ( MDEventsTest ${TEST_FILES} ${GMOCK_TEST_FILES} )
+    target_link_libraries( MDEventsTest MDEvents ${MANTIDLIBS} ${HDF5_LIBRARIES} ${GMOCK_LIBRARIES} )
+  else ()
+    cxxtest_add_test ( MDEventsTest ${TEST_FILES} )
+    target_link_libraries( MDEventsTest MDEvents ${MANTIDLIBS} ${HDF5_LIBRARIES} )
+  endif ()
+  
+  add_dependencies ( FrameworkTests MDEventsTest )
+  
+  # Add to the 'FrameworkTests' group in VS
+  set_property ( TARGET MDEventsTest PROPERTY FOLDER "FrameworkTests" )
+  
+endif ()
+
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/IMDBox.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/IMDBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..196a884e3eda36eecdf032a912056478b0f80eb2
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/IMDBox.h
@@ -0,0 +1,135 @@
+#ifndef IMDBOX_H_
+#define IMDBOX_H_
+
+#include "MantidKernel/System.h"
+#include "MantidMDEvents/MDPoint.h"
+#include "MantidMDEvents/MDDimensionExtents.h"
+#include "MantidAPI/IMDWorkspace.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  //===============================================================================================
+  /** Abstract Interface for a multi-dimensional event "box".
+   * To be subclassed by MDBox and MDGridBox
+   *
+   * A box is a container of MDPoint's within a certain range of values
+   * within the nd dimensions. This range defines a n-dimensional "box"
+   * or rectangular prism.
+   *
+   * @tparam nd :: the number of dimensions that each MDEvent will be tracking.
+   *                  an int > 0.
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 7, 2010
+   *
+   * */
+  template <size_t nd, size_t nv = 0, typename TE = char>
+  class DLLExport IMDBox
+  {
+  public:
+    IMDBox();
+
+    virtual void addPoint( const MDPoint<nd,nv,TE> & point) = 0;
+
+    virtual void clear() = 0;
+
+    virtual size_t getNPoints() const = 0;
+
+    virtual size_t getNumDims() const = 0;
+
+    virtual std::vector< MDPoint<nd,nv,TE> > * getPointsCopy();
+
+    virtual double getSignal() const;
+
+    virtual double getErrorSquared() const;
+
+  private:
+
+    /** Array of MDDimensionStats giving the extents and
+     * other stats on the box dimensions.
+     */
+    MDDimensionExtents dimExtents[nd];
+
+
+  public:
+    /// Convenience typedef for a shared pointer to a this type of class
+    typedef boost::shared_ptr< IMDBox<nd,nv,TE> > sptr;
+
+  };
+
+
+
+
+
+
+
+
+
+
+  //===============================================================================================
+  /** Simple class which holds the extents (min/max)
+   * of a given dimension in a MD workspace or MDBox
+   */
+  DLLExport class MDDimensionExtents
+  {
+  public:
+
+    /** Empty constructor - reset everything */
+    MDDimensionExtents() :
+      min( std::numeric_limits<CoordType>::max() ),
+      max( -std::numeric_limits<CoordType>::max() )
+    { }
+
+    // ---- Public members ----------
+    /// Extent: minimum value in that dimension
+    CoordType min;
+    /// Extent: maximum value in that dimension
+    CoordType max;
+  };
+
+
+
+
+  //===============================================================================================
+  /** Simple class which holds statistics
+   * about a given dimension in a MD workspace or MDBox
+   */
+  DLLExport class MDDimensionStats : public MDDimensionExtents
+  {
+  public:
+
+    /** Empty constructor - reset everything */
+    MDDimensionStats() :
+      MDDimensionExtents(),
+      total( 0 ),
+      approxVariance( 0 )
+    { }
+
+    // ---- Public members ----------
+
+    /** Sum of the coordinate value of all points contained.
+     * Divide by the number of points to get the mean!
+     */
+    CoordType total;
+
+    /** Approximate variance - used for quick std.deviation estimates.
+     *
+     * A running sum of (X - mean(X))^2, where mean(X) is calculated at the
+     * time of adding the point. This approximation gets better as the number of
+     * points increases.
+     *
+     * Divide by the number of points to get the square of the standard deviation!
+     */
+    CoordType approxVariance;
+  };
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+#endif /* MDBOX_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/IMDEventWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/IMDEventWorkspace.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1ce88657200dd43a3e91d9520821c90a9f48c50
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/IMDEventWorkspace.h
@@ -0,0 +1,45 @@
+#ifndef IMDEVENTWORKSPACE_H_
+#define IMDEVENTWORKSPACE_H_
+
+#include "MantidKernel/System.h"
+#include "MantidMDEvents/MDEvent.h"
+#include "MantidAPI/IMDWorkspace.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  /** Abstract base class for multi-dimension event workspaces (MDEventWorkspace).
+   * This class will handle as much of the common operations as possible;
+   * but since MDEventWorkspace is a templated class, that makes some aspects
+   * impossible.
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 3, 2010
+   *
+   * */
+  DLLExport class IMDEventWorkspace // : public API::IMDWorkspace
+  {
+  public:
+    /** Returns the number of dimensions in this workspace */
+    virtual int getNumDims() const = 0;
+
+    /** Returns the total number of points (events) in this workspace */
+    virtual size_t getNPoints() const = 0;
+
+    /** Returns the number of bytes of memory
+     * used by the workspace. */
+    virtual size_t getMemoryUsed() const = 0;
+
+  };
+
+
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+#endif /* IMDEVENTWORKSPACE_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..362ac36b45b026be9f2787e23b78db97b3190400
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h
@@ -0,0 +1,124 @@
+#ifndef MDBOX_H_
+#define MDBOX_H_
+
+#include "MantidKernel/System.h"
+#include "MantidMDEvents/MDEvent.h"
+#include "MantidMDEvents/MDDimensionExtents.h"
+#include "MantidAPI/IMDWorkspace.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+
+
+
+  //===============================================================================================
+  /** Templated class for a multi-dimensional event "box".
+   *
+   * A box is a container of MDPoint's within a certain range of values
+   * within the nd dimensions. This range defines a n-dimensional "box"
+   * or rectangular prism.
+   *
+   * This class is a simple list of points with no more internal structure.
+   *
+   * @tparam nd :: the number of dimensions that each MDEvent will be tracking.
+   *                  an int > 0.
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 7, 2010
+   *
+   * */
+  template <size_t nd>
+  class DLLExport MDBox
+  {
+  public:
+    MDBox();
+
+    void addEvent( const MDEvent<nd> & point);
+
+    void clear();
+
+    size_t getNPoints() const;
+
+    size_t getNumDims() const;
+
+    std::vector< MDEvent<nd> > & getPoints();
+
+    double getSignal() const;
+    double getErrorSquared() const;
+
+  private:
+
+    /** Vector of MDEvent's, in no particular order.
+     * */
+    std::vector< MDEvent<nd> > data;
+
+    /** Array of MDDimensionExtents giving the extents and
+     * in each dimension.
+     */
+    MDDimensionExtents dims[nd];
+
+    /** Total signal from all points within */
+    double signal;
+
+    /** Total error (squared) from all points within */
+    double errorSquared;
+
+
+  public:
+    /// Typedef for a shared pointer to a MDBox
+    typedef boost::shared_ptr<MDBox<nd> > sptr;
+
+  };
+
+
+
+
+
+
+
+
+
+
+  //===============================================================================================
+  /** Simple class which holds statistics
+   * about a given dimension in a MD workspace or MDBox
+   */
+  DLLExport class MDDimensionStats : public MDDimensionExtents
+  {
+  public:
+
+    /** Empty constructor - reset everything */
+    MDDimensionStats() :
+      MDDimensionExtents(),
+      total( 0 ),
+      approxVariance( 0 )
+    { }
+
+    // ---- Public members ----------
+
+    /** Sum of the coordinate value of all points contained.
+     * Divide by the number of points to get the mean!
+     */
+    CoordType total;
+
+    /** Approximate variance - used for quick std.deviation estimates.
+     *
+     * A running sum of (X - mean(X))^2, where mean(X) is calculated at the
+     * time of adding the point. This approximation gets better as the number of
+     * points increases.
+     *
+     * Divide by the number of points to get the square of the standard deviation!
+     */
+    CoordType approxVariance;
+  };
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+#endif /* MDBOX_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDDimensionExtents.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDDimensionExtents.h
new file mode 100644
index 0000000000000000000000000000000000000000..c3f861eda15022e6b4ab16281adb5ffc00b36c0f
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDDimensionExtents.h
@@ -0,0 +1,48 @@
+#ifndef MDDIMENSIONEXTENTS_H_
+#define MDDIMENSIONEXTENTS_H_
+
+/*
+ * MDDimensionExtents.h
+ *
+ *  Created on: Jan 14, 2011
+ *      Author: Janik Zikovsky
+ */
+#include "MantidKernel/System.h"
+#include "MantidMDEvents/MDPoint.h"
+#include <limits>
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  //===============================================================================================
+  /** Simple class that holds the extents (min/max)
+   * of a given dimension in a MD workspace or MDBox
+   */
+  DLLExport class MDDimensionExtents
+  {
+  public:
+
+    /** Empty constructor - reset everything.
+     *  */
+    MDDimensionExtents() :
+      min( std::numeric_limits<CoordType>::max() ),
+      max( -std::numeric_limits<CoordType>::max() )
+    { }
+
+    // ---- Public members ----------
+    /// Extent: minimum value in that dimension
+    CoordType min;
+    /// Extent: maximum value in that dimension
+    CoordType max;
+  };
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+
+
+#endif /* MDDIMENSIONEXTENTS_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEvent.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..68d8fcd1b68dae03e16cf06ed74af25b00562449
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEvent.h
@@ -0,0 +1,187 @@
+#ifndef MDEVENT_H_
+#define MDEVENT_H_
+
+#include "MantidKernel/System.h"
+#include <numeric>
+#include <math.h>
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  /** Typedef for the data type to use for coordinate axes.
+   * This could be a float or a double, depending on requirements.
+   * We can change this in order to compare
+   * performance/memory/accuracy requirements.
+   */
+  typedef double CoordType;
+
+
+  /** Macro TMDE to make declaring template functions
+   * faster. Put this macro before function declarations.
+   */
+  #define TMDE template <size_t nd>
+
+  /** Templated class holding data about a neutron detection event
+   * in N-dimensions (for example, Qx, Qy, Qz, E).
+   *
+   *   Each neutron has a signal (a float, can be != 1) and an error. This
+   * is the same principle as the WeightedEvent in EventWorkspace's
+   *
+   * This class is meant to be as small in memory as possible, since there
+   * will be (many) billions of it.
+   * No virtual methods! This adds a vtable which uses lots of memory.
+   *
+   * @tparam nd :: the number of dimensions that each MDEvent will be tracking.
+   *               an int > 0.
+   * @tparam ne :: the number of extra (non-float) ints of information to store.
+   *               These could be detector ids, run numbers, etc. and will consist
+   *               of signed 32-bit ints
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 3, 2010
+   *
+   * */
+  template <size_t nd>
+  class DLLExport MDEvent
+  {
+  private:
+    /** The signal (aka weight) from the neutron event.
+     * Will be exactly 1.0 unless modified at some point.
+     */
+    float signal;
+
+    /** The square of the error carried in this event.
+     * Will be 1.0 unless modified by arithmetic.
+     * The square is used for more efficient calculations.
+     */
+    float errorSquared;
+
+    /** The N-dimensional coordinates. A simple
+     * fixed-sized array of (floats or doubles).
+     */
+    CoordType coord[nd];
+
+  public:
+    /* Will be keeping functions inline for (possible?) performance improvements */
+
+    //---------------------------------------------------------------------------------------------
+    /** Empty constructor */
+    MDEvent() :
+      signal(1.0), errorSquared(1.0)
+    {
+    }
+
+
+    //---------------------------------------------------------------------------------------------
+    /** Constructor with signal and error
+     *
+     * @param signal :: signal
+     * @param errorSquared :: errorSquared
+     * */
+    MDEvent(const float signal, const float errorSquared) :
+      signal(signal), errorSquared(errorSquared)
+    {
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Constructor with signal and error and an array of coords
+     *
+     * @param signal :: signal
+     * @param errorSquared :: errorSquared
+     * @param coords :: pointer to a nd-sized array of values to set for all coordinates.
+     * */
+    MDEvent(const float signal, const float errorSquared, const CoordType * coords) :
+      signal(signal), errorSquared(errorSquared)
+    {
+      for (size_t i=0; i<nd; i++)
+        coord[i] = coords[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Copy constructor
+     *
+     * @param rhs :: mdevent to copy
+     * @param errorSquared :: errorSquared
+     * */
+    MDEvent(const MDEvent &rhs) :
+      signal(rhs.signal), errorSquared(rhs.errorSquared)
+    {
+      for (size_t i=0; i<nd; i++)
+        coord[i] = rhs.coord[i];
+    }
+
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the n-th coordinate axis value.
+     * @param n :: index (0-based) of the dimension you want.
+     * */
+    CoordType getCoord(const size_t n) const
+    {
+      return coord[n];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Sets the n-th coordinate axis value.
+     * @param n :: index (0-based) of the dimension you want to set
+     * @param value :: value to set.
+     * */
+    void setCoord(const size_t n, const CoordType value)
+    {
+      coord[n] = value;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Sets all the coordinates.
+     *
+     * @param coords :: pointer to a nd-sized array of the values to set.
+     * */
+    void setCoords(const CoordType * coords)
+    {
+      for (size_t i=0; i<nd; i++)
+        coord[i] = coords[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the number of dimensions in the event.
+     * */
+    size_t getNumDims() const
+    {
+      return nd;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the signal (weight) of this event.
+     * */
+    float getSignal() const
+    {
+      return signal;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the error (squared) of this event.
+     * */
+    float getErrorSquared() const
+    {
+      return errorSquared;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the error (not squared) of this event.
+     * */
+    float getError() const
+    {
+      return sqrt(errorSquared);
+    }
+
+  };
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+
+#endif /* MDEVENT_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h
new file mode 100644
index 0000000000000000000000000000000000000000..df0e47a77927baa0d1e30251290e1337e1dc8dbe
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h
@@ -0,0 +1,77 @@
+#ifndef MDEVENTWORKSPACE_H_
+#define MDEVENTWORKSPACE_H_
+
+#include "MantidKernel/System.h"
+#include "MantidMDEvents/MDEvent.h"
+#include "MantidMDEvents/MDPoint.h"
+#include "MantidMDEvents/IMDEventWorkspace.h"
+#include "MantidAPI/IMDWorkspace.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  /** Templated class for the multi-dimensional event workspace.
+   *
+   * Template parameters are the same as the MDPoint<> template params, and
+   * determine the basic MDPoint type used.
+   *
+   * @tparam nd :: the number of dimensions that each MDPoint will be tracking.
+   *               an usigned int > 0.
+   *
+   * @tparam nv :: number of corner vertices per dimension. If only the
+   *               center of the point is required, this == 0.
+   *               If all corners are needed, this == nd.
+   *               Default value == 0; meaning only the center coordinates are used.
+   *
+   * @tparam TE :: Type for a bit of extra data that can be carried around in each point.
+   *               For example, this could be a single uint32 representing a detector ID.
+   *               Or, if more complex things are required, this could be a struct with
+   *               a few fields (should not be dynamically allocated like a pointer, in general).
+   *               Default value == char[0] (occupying no memory).
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 3, 2010
+   *
+   * */
+  template <size_t nd, size_t nv=0, typename TE=char>
+  class DLLExport MDEventWorkspace  : public IMDEventWorkspace
+  {
+  public:
+    /** Typedef of the basic MDPoint data type used in this MDEventWorkspace.
+     * This is for convenience; an algorithm can declare
+     *  MyWorkspace::Point somePoint;
+     * without having to look up template parameters...
+     */
+    typedef MDPoint<nd,nv,TE> Point;
+
+    /** Returns the number of dimensions in this workspace */
+    virtual int getNumDims() const;
+
+    /** Returns the total number of points (events) in this workspace */
+    virtual size_t getNPoints() const;
+
+    /** Returns the number of bytes of memory
+     * used by the workspace. */
+    virtual size_t getMemoryUsed() const;
+
+    /** Sample function returning the n-th point in the workspace.
+     * This may not be needed.
+     *  */
+    Point getPoint(int n);
+
+  protected:
+
+  };
+
+
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+
+#endif /* MDEVENTWORKSPACE_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..28ac02c09852c8af6ec376f9a2aa7e68550c21e5
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h
@@ -0,0 +1,150 @@
+#ifndef MDGRIDBOX_H_
+#define MDGRIDBOX_H_
+
+#include "MantidKernel/System.h"
+#include "MantidMDEvents/MDPoint.h"
+#include "MantidMDEvents/IMDEventWorkspace.h"
+#include "MantidAPI/IMDWorkspace.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+  // Forward declaration
+  class MDDimensionStats;
+
+
+  //===============================================================================================
+  /** Class for a gridded box that contains other boxes.
+   *
+   * A box is a container of MDPoint's within a certain range of values
+   * within the nd dimensions. This range defines a n-dimensional "box"
+   * or rectangular prism.
+   *
+   * This class is a simple list of points with no more internal structure.
+   *
+   * @tparam nd :: the number of dimensions that each MDEvent will be tracking.
+   *                  an int > 0.
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 7, 2010
+   *
+   * */
+  template <size_t nd, size_t nv = 0, typename TE = char>
+  class DLLExport MDGridBox
+  {
+  public:
+    MDGridBox();
+
+    virtual void addPoint( const MDPoint<nd,nv,TE> & point);
+
+    virtual void clear();
+
+    virtual MDDimensionStats getStats(const size_t dim) const;
+
+    virtual size_t getNPoints() const;
+
+    size_t getNumDims() const;
+
+    std::vector< MDPoint<nd,nv,TE> > & getPoints();
+
+    double getSignal() const;
+    double getErrorSquared() const;
+
+  private:
+
+    /** Vector of MDEvent's, in no particular order.
+     * */
+    std::vector< MDPoint<nd,nv,TE> > data;
+
+    /** Array of MDDimensionStats giving the extents and
+     * other stats on the box dimensions.
+     */
+    MDDimensionStats dimStats[nd];
+
+    /** Total signal from all points within */
+    double signal;
+
+    /** Total error (squared) from all points within */
+    double errorSquared;
+
+
+  public:
+    /// Typedef for a shared pointer to a MDBox
+    typedef boost::shared_ptr<MDBox<nd> > sptr;
+
+  };
+
+
+
+
+
+
+
+
+
+
+  //===============================================================================================
+  /** Simple class which holds the extents (min/max)
+   * of a given dimension in a MD workspace or MDBox
+   */
+  DLLExport class MDDimensionExtents
+  {
+  public:
+
+    /** Empty constructor - reset everything */
+    MDDimensionExtents() :
+      min( std::numeric_limits<CoordType>::max() ),
+      max( -std::numeric_limits<CoordType>::max() )
+    { }
+
+    // ---- Public members ----------
+    /// Extent: minimum value in that dimension
+    CoordType min;
+    /// Extent: maximum value in that dimension
+    CoordType max;
+  };
+
+
+
+
+  //===============================================================================================
+  /** Simple class which holds statistics
+   * about a given dimension in a MD workspace or MDBox
+   */
+  DLLExport class MDDimensionStats : public MDDimensionExtents
+  {
+  public:
+
+    /** Empty constructor - reset everything */
+    MDDimensionStats() :
+      MDDimensionExtents(),
+      total( 0 ),
+      approxVariance( 0 )
+    { }
+
+    // ---- Public members ----------
+
+    /** Sum of the coordinate value of all points contained.
+     * Divide by the number of points to get the mean!
+     */
+    CoordType total;
+
+    /** Approximate variance - used for quick std.deviation estimates.
+     *
+     * A running sum of (X - mean(X))^2, where mean(X) is calculated at the
+     * time of adding the point. This approximation gets better as the number of
+     * points increases.
+     *
+     * Divide by the number of points to get the square of the standard deviation!
+     */
+    CoordType approxVariance;
+  };
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+#endif /* MDBOX_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDPoint.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDPoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..baca4689109af0e658025c15f08be111a219b1a9
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDPoint.h
@@ -0,0 +1,324 @@
+#ifndef MDPOINT_H_
+#define MDPOINT_H_
+
+#include "MantidKernel/System.h"
+#include <numeric>
+#include <math.h>
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  /** Typedef for the data type to use for coordinate axes.
+   * This could be a float or a double, depending on requirements.
+   * We can change this in order to compare
+   * performance/memory/accuracy requirements.
+   */
+  typedef double CoordType;
+
+  /** Macro TMDP to make declaring template functions
+   * faster. Put this macro before function declarations.
+   *
+   */
+  #define TMDP template <size_t nd, size_t nv, typename TE>
+
+
+  /** Templated class holding data about a signal from neutron(s) at a given point
+   * in N-dimensions (for example, Qx, Qy, Qz, E).
+   *
+   * To be more general, the MDPoint class can hold a number of vertices
+   * that define the corners of the volume occupied.
+   *
+   * If MDPoint represents a single neutron event, in which case the corner
+   * vertices are not needed.
+   *
+   * Each point has a signal (a float, can be != 1.0) and an error. This
+   * is the same principle as the WeightedEvent in EventWorkspace's
+   *
+   * This class is meant to be as small in memory as possible, since there
+   * will be (many) billions of it.
+   * No virtual methods! This adds a vtable which uses lots of memory.
+   *
+   * @tparam nd :: the number of dimensions that each MDPoint will be tracking.
+   *               an usigned int > 0.
+   *
+   * @tparam nv :: number of corner vertices per dimension. If only the
+   *               center of the point is required, this == 0.
+   *               If all corners are needed, this == nd.
+   *               Default value == 0; meaning only the center coordinates are used.
+   *
+   * @tparam TE :: Type for a bit of extra data that can be carried around in each point.
+   *               For example, this could be a single uint32 representing a detector ID.
+   *               Or, if more complex things are required, this could be a struct with
+   *               a few fields (should not be dynamically allocated like a pointer, in general).
+   *               Default value == char[0] (occupying no memory).
+   *
+   * @author Janik Zikovsky, SNS
+   * @date Dec 3, 2010
+   *
+   * */
+  template <size_t nd, size_t nv=1, typename TE = char>
+  class DLLExport MDPoint
+  {
+  private:
+    /** The signal (aka weight) from the point.
+     * For a single neutron event, this will be exactly 1.0 unless modified at some point.
+     */
+    float signal;
+
+    /** The square of the error carried in this point.
+     * For events, this will be 1.0 unless modified by arithmetic.
+     * N.B. The square is used for more efficient calculations.
+     */
+    float errorSquared;
+
+    /** The N-dimensional coordinates of the center.
+     * A simple fixed-sized array of (floats or doubles).
+     */
+    CoordType center[nd];
+
+    /** The vertices of each corner of the data point, describing
+     * a n-dimensional parallepiped.
+     *
+     * The vertices are stored as a nv*nd array of coordinate. There are
+     * nv vertices, each with nd dimensions.
+     */
+    CoordType corners[nv*nd];
+
+    /** Template-specified bit of extra data that can be carried around
+     * in each point. For example, this could be a single uint32 representing
+     * a detector ID.
+     * Or, if more complex things are required, this could be a struct with
+     * a few fields (should not be dynamically allocated like a pointer, in general).
+     */
+    TE extra;
+
+  public:
+    /* Will be keeping functions inline for (possible?) performance improvements */
+
+    //---------------------------------------------------------------------------------------------
+    /** Empty constructor */
+    MDPoint() :
+      signal(1.0), errorSquared(1.0)
+    {
+    }
+
+
+    //---------------------------------------------------------------------------------------------
+    /** Constructor with signal and error
+     *
+     * @param signal :: signal
+     * @param errorSquared :: errorSquared
+     * */
+    MDPoint(const float signal, const float errorSquared) :
+      signal(signal), errorSquared(errorSquared)
+    {
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Constructor with signal and error and an array of coords
+     *
+     * @param signal :: signal
+     * @param errorSquared :: errorSquared
+     * @param centers :: pointer to a nd-sized array of values to set for all coordinates.
+     * */
+    MDPoint(const float signal, const float errorSquared, const CoordType * centers) :
+      signal(signal), errorSquared(errorSquared)
+    {
+      for (size_t i=0; i<nd; i++)
+        center[i] = centers[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Copy constructor
+     *
+     * @param rhs :: MDPoint to copy
+     * @param errorSquared :: errorSquared
+     * */
+    MDPoint(const MDPoint &rhs) :
+      signal(rhs.signal), errorSquared(rhs.errorSquared)
+    {
+      for (size_t i=0; i<nd; i++)
+        center[i] = rhs.center[i];
+    }
+
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the n-th center coordinate axis value.
+     * @param n :: index (0-based) of the dimension you want.
+     * */
+    CoordType getCenter(const size_t n) const
+    {
+      return center[n];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns a direct pointer to the center coordinates of this point,
+     * which is a [nd]-sized array.
+     * */
+    CoordType * getCenters()
+    {
+      return &center;
+    }
+
+
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the n-th corner coordinate axis value, one dimension at a time
+     *
+     * @param nvert :: index (0-based) of the corner to set
+     * @param ndim :: index (0-based) of the dimension you want to set. Must be 0 <= ndim <= nd
+     * */
+    CoordType getCorner(const size_t nvert, const size_t ndim) const
+    {
+      return corners[nvert*nd + ndim];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns a pointer to the n-th corner coordinate.
+     *
+     * @param nvert :: index (0-based) of the corner to set
+     * */
+    CoordType * getCorner(const size_t nvert)
+    {
+      return &corners[nvert*nd];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns a pointer to the corner vertices of this point,
+     * which is a [nd][nv] array.
+     * */
+    CoordType * getCorners()
+    {
+      return &corners;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Sets the n-th center coordinate axis value.
+     * @param n :: index (0-based) of the dimension you want to set
+     * @param value :: value to set.
+     * */
+    void setCenter(const size_t n, const CoordType value)
+    {
+      center[n] = value;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Sets all the center coordinates.
+     *
+     * @param coords :: pointer to a nd-sized array of the values to set.
+     * */
+    void setCenters(const CoordType * coords)
+    {
+      for (size_t i=0; i<nd; i++)
+        center[i] = coords[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the n-th center coordinate axis value, one dimension at a time
+     *
+     * @param nvert :: index (0-based) of the corner to set
+     * @param ndim :: index (0-based) of the dimension you want to set. Must be 0 <= ndim <= nd
+     * @param value :: value to set.
+     * */
+    CoordType setCorner(const size_t nvert, const size_t ndim, const CoordType value)
+    {
+      corners[nvert*nd + ndim] = value;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the n-th center coordinate axis value, one vertex at a time
+     *
+     * @param nvert :: index (0-based) of the corner to set
+     * @param coords :: an array, sized (nd), of coordinates to set.
+     * */
+    CoordType setCorner(const size_t nvert, const CoordType * coords)
+    {
+      for (size_t i=0; i<nd; i++)
+        corners[nvert*nd + i] = coords[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Sets all the center coordinates.
+     *
+     * @param coords :: pointer to a [nv*nd]-sized array of the values to set.
+     * */
+    void setCorners(const CoordType * coords)
+    {
+      for (size_t i=0; i<nv*nd; i++)
+        corners[i] = coords[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the number of dimensions in the point (nd template parameter).
+     * */
+    size_t getNumDims() const
+    {
+      return nd;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the signal (weight) of this point.
+     * */
+    float getSignal() const
+    {
+      return signal;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the error (squared) of this point.
+     * */
+    float getErrorSquared() const
+    {
+      return errorSquared;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns the error (not squared) of this point.
+     * */
+    float getError() const
+    {
+      return sqrt(errorSquared);
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns a reference to the extra type.
+     * */
+    TE & getExtra()
+    {
+      return extra;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Returns a const reference to the extra type.
+     * NOTE: For friend classes, you may access the .extra field directly. This will be faster.
+     *
+     * */
+    TE & getExtra() const
+    {
+      return extra;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** Sets the extra data. The extra data is copied into this MDPoint.
+     * Note: It may be advantageous to use getExtra() and modify the
+     * extra field directly, since that function returns a reference.
+     *
+     * @param _extra :: reference to an instance of type TE.
+     * */
+    void setExtra(TE & _extra)
+    {
+      extra = _extra;
+    }
+
+  };
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
+
+#endif /* MDPOINT_H_ */
diff --git a/Code/Mantid/Framework/MDEvents/src/MDBox.cpp b/Code/Mantid/Framework/MDEvents/src/MDBox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f132177493dbb0125e981d91e2818182d63a41ad
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/src/MDBox.cpp
@@ -0,0 +1,99 @@
+#include "MantidMDEvents/MDBox.h"
+#include "MantidMDEvents/MDEvent.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /** Empty constructor */
+  TMDE
+  MDBox<nd>::MDBox() :
+    signal(0.0), errorSquared(0.0)
+  {
+  }
+
+
+  //-----------------------------------------------------------------------------------------------
+  /** Clear any points contained. */
+  TMDE
+  void MDBox<nd>::clear()
+  {
+    signal = 0.0;
+    errorSquared = 0.0;
+    data.clear();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** Returns the number of dimensions in this box */
+  TMDE
+  size_t MDBox<nd>::getNumDims() const
+  {
+    return nd;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** Returns the total number of points (events) in this box */
+  TMDE
+  size_t MDBox<nd>::getNPoints() const
+  {
+    return data.size();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** Returns a reference to the points vector contained within.
+   */
+  TMDE
+  std::vector< MDEvent<nd> > & MDBox<nd>::getPoints()
+  {
+    return data;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** Returns the integrated signal from all points within.
+   */
+  TMDE
+  double MDBox<nd>::getSignal() const
+  {
+    return signal;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** Returns the integrated error squared from all points within.
+   */
+  TMDE
+  double MDBox<nd>::getErrorSquared() const
+  {
+    return errorSquared;
+  }
+
+
+
+
+  //-----------------------------------------------------------------------------------------------
+  /** Add a MDEvent to the box.
+   * @param point :: reference to a MDEvent to add.
+   * */
+  TMDE
+  void MDBox<nd>::addEvent( const MDEvent<nd> & point)
+  {
+    this->data.push_back(point);
+
+    // Keep the running total of signal and error
+    signal += point.getSignal();
+    errorSquared += point.getErrorSquared();
+  }
+
+  // Here we export a bunch of version of MDBox with various dimension sizes.
+  // We need to define one for every possibility.
+  template DLLExport class MDBox<1>;
+  template DLLExport class MDBox<2>;
+  template DLLExport class MDBox<3>;
+  template DLLExport class MDBox<4>;
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
diff --git a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..481eec2fbf7216d44fbeb74278c56d1e5392f14f
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp
@@ -0,0 +1,50 @@
+#include "MantidMDEvents/MDEventWorkspace.h"
+#include "MantidMDEvents/MDEvent.h"
+
+namespace Mantid
+{
+namespace MDEvents
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /** Returns the number of dimensions in this workspace */
+template <size_t nd, size_t nv, typename TE>
+  int MDEventWorkspace<nd,nv,TE>::getNumDims() const
+  {
+    return nd;
+  }
+
+  /** Returns the total number of points (events) in this workspace */
+  template <size_t nd, size_t nv, typename TE>
+  size_t MDEventWorkspace<nd,nv,TE>::getNPoints() const
+  {
+    //return data.size();
+    return 0;
+  }
+
+  /** Returns the number of bytes of memory
+   * used by the workspace. */
+  template <size_t nd, size_t nv, typename TE>
+  size_t MDEventWorkspace<nd,nv,TE>::getMemoryUsed() const
+  {
+    return this->getNPoints() * sizeof(MDEvent<nd>);
+  }
+
+
+
+  //-----------------------------------------------------------------------------------------------
+
+
+  // We export a bunch of version of MDEventWorkspace with various dimension sizes.
+  template DLLExport class MDEventWorkspace<1,0,char>;
+  template DLLExport class MDEventWorkspace<2,0,char>;
+  template DLLExport class MDEventWorkspace<3,0,char>;
+  template DLLExport class MDEventWorkspace<4,0,char>;
+
+
+
+
+}//namespace MDEvents
+
+}//namespace Mantid
+
diff --git a/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h b/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c1fbc750cc41a253c2f8e3716fa8aa87619dd9f
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h
@@ -0,0 +1,76 @@
+#ifndef MDBOXTEST_H
+#define MDBOXTEST_H
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidMDEvents/MDEvent.h"
+#include "MantidMDEvents/MDBox.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <memory>
+#include <map>
+
+using namespace Mantid;
+using namespace Mantid::MDEvents;
+
+class MDBoxTest :    public CxxTest::TestSuite
+{
+
+public:
+  void testConstructor()
+  {
+    MDBox<3> b3;
+    TS_ASSERT_EQUALS( b3.getNumDims(), 3);
+    TS_ASSERT_EQUALS( b3.getNPoints(), 0);
+
+//    std::cout << sizeof(b3) << "\n";
+//    std::cout << sizeof(MDBox<0> ) << "\n";
+//    std::cout << sizeof(MDBox<1> ) << "\n";
+//    std::vector< int > v;
+//    std::cout << sizeof(v) << "\n";
+  }
+
+  void testAddPoint()
+  {
+    MDBox<2> b;
+    MDEvent<2> ev(1.2, 3.4);
+    ev.setCoord(0, 2.0);
+    ev.setCoord(1, 3.0);
+    b.addEvent(ev);
+    TS_ASSERT_EQUALS( b.getNPoints(), 1)
+  }
+
+  void testClear()
+  {
+    MDBox<2> b;
+    MDEvent<2> ev(1.2, 3.4);
+    b.addEvent(ev);
+    b.addEvent(ev);
+    TS_ASSERT_EQUALS( b.getNPoints(), 2)
+    TS_ASSERT_DELTA( b.getSignal(), 2.4, 1e-5)
+    b.clear();
+    TS_ASSERT_EQUALS( b.getNPoints(), 0)
+    TS_ASSERT_DELTA( b.getSignal(), 0.0, 1e-5)
+    TS_ASSERT_DELTA( b.getErrorSquared(), 0.0, 1e-5)
+  }
+
+  void test_getPoints()
+  {
+    MDBox<2> b;
+    MDEvent<2> ev(4.0, 3.4);
+    b.addEvent(ev);
+    b.addEvent(ev);
+    b.addEvent(ev);
+    TS_ASSERT_EQUALS( b.getPoints().size(), 3);
+    TS_ASSERT_EQUALS( b.getPoints()[2].getSignal(), 4.0);
+  }
+
+  void test_sptr()
+  {
+    MDBox<3>::sptr a( new MDBox<3>());
+    //TS_ASSERT_EQUALS( sizeof(a), 16);
+
+  }
+};
+
+#endif
diff --git a/Code/Mantid/Framework/MDEvents/test/MDEventTest.h b/Code/Mantid/Framework/MDEvents/test/MDEventTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ccc4097e15068ce70d021b338a5d9079f602f29c
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/test/MDEventTest.h
@@ -0,0 +1,113 @@
+#ifndef MDEVENTTEST_H
+#define MDEVENTTEST_H
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidMDEvents/MDEvent.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <memory>
+#include <map>
+
+using namespace Mantid;
+using namespace Mantid::MDEvents;
+
+class MDEventTest :    public CxxTest::TestSuite
+{
+
+public:
+  void testConstructors()
+  {
+    MDEvent<3> a;
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+    TS_ASSERT_EQUALS( a.getSignal(), 1.0);
+    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.0);
+
+    MDEvent<4> b(2.5, 1.5);
+    TS_ASSERT_EQUALS( b.getNumDims(), 4);
+    TS_ASSERT_EQUALS( b.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
+
+    TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3+8);
+    TS_ASSERT_EQUALS( sizeof(b), sizeof(CoordType)*4+8);
+  }
+
+  void testConstructorsWithCoords()
+  {
+    // Fixed-size array
+    CoordType coords[3] = {0.123, 1.234, 2.345};
+    MDEvent<3> a(2.5, 1.5, coords );
+    TS_ASSERT_EQUALS( a.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
+    TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
+
+    // Dynamic array
+    CoordType * coords2 = new CoordType[5];
+    coords2[0] = 1.0;
+    coords2[1] = 2.0;
+    coords2[2] = 3.0;
+
+    MDEvent<3> b(2.5, 1.5, coords2 );
+    TS_ASSERT_EQUALS( b.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
+    TS_ASSERT_EQUALS( b.getCoord(0), 1);
+    TS_ASSERT_EQUALS( b.getCoord(1), 2);
+    TS_ASSERT_EQUALS( b.getCoord(2), 3);
+
+  }
+
+
+  void testCooord()
+  {
+    MDEvent<3> a;
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+
+    a.setCoord(0, 0.123);
+    TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
+
+    a.setCoord(1, 1.234);
+    TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
+
+    a.setCoord(2, 2.345);
+    TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
+  }
+
+  void testSetCooords()
+  {
+    MDEvent<3> a;
+    CoordType coords[3] = {0.123, 1.234, 2.345};
+    a.setCoords( coords );
+    TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
+  }
+
+  void testCopyConstructor()
+  {
+    CoordType coords[3] = {0.123, 1.234, 2.345};
+    MDEvent<3> b(2.5, 1.5, coords );
+    MDEvent<3> a(b);
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+    TS_ASSERT_EQUALS( a.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
+    TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
+  }
+
+  void test_getError()
+  {
+    MDEvent<3> a(2.0, 4.0);
+    TS_ASSERT_EQUALS( a.getSignal(), 2.0);
+    TS_ASSERT_EQUALS( a.getError(), 2.0);
+  }
+
+
+};
+
+#endif
diff --git a/Code/Mantid/Framework/MDEvents/test/MDEventWorkspaceTest.h b/Code/Mantid/Framework/MDEvents/test/MDEventWorkspaceTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca0130051d0e56709e993f8fb78ca8ce2b9162c9
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/test/MDEventWorkspaceTest.h
@@ -0,0 +1,30 @@
+#ifndef MDEVENTWORKSPACETEST_H
+#define MDEVENTWORKSPACETEST_H
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidMDEvents/MDEvent.h"
+#include "MantidMDEvents/MDEventWorkspace.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <memory>
+#include <map>
+
+using namespace Mantid;
+using namespace Mantid::MDDataObjects;
+
+class MDEventWorkspaceTest :    public CxxTest::TestSuite
+{
+public:
+
+  void testConstructor()
+  {
+    MDEventWorkspace<3> ew3;
+    TS_ASSERT_EQUALS( ew3.getNumDims(), 3);
+    TS_ASSERT_EQUALS( ew3.getNPoints(), 0);
+  }
+
+
+};
+
+#endif
diff --git a/Code/Mantid/Framework/MDEvents/test/MDPointTest.h b/Code/Mantid/Framework/MDEvents/test/MDPointTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..81f7313b45123fcf858a91a1910e247b71efa5cd
--- /dev/null
+++ b/Code/Mantid/Framework/MDEvents/test/MDPointTest.h
@@ -0,0 +1,241 @@
+#ifndef MDPointTEST_H
+#define MDPointTEST_H
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidMDEvents/MDPoint.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <memory>
+#include <map>
+
+using namespace Mantid;
+using namespace Mantid::MDDataObjects;
+
+class MDPointTest :    public CxxTest::TestSuite
+{
+
+  struct MyExtraData
+  {
+    int detectorID;
+    char instrument;
+  };
+
+public:
+  void testConstructors()
+  {
+    MDPoint<3> a;
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+    TS_ASSERT_EQUALS( a.getSignal(), 1.0);
+    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.0);
+
+    MDPoint<4> b(2.5, 1.5);
+    TS_ASSERT_EQUALS( b.getNumDims(), 4);
+    TS_ASSERT_EQUALS( b.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
+
+    TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3+8);
+    TS_ASSERT_EQUALS( sizeof(b), sizeof(CoordType)*4+8);
+  }
+
+  void testConstructors_MoreTemplateParameters()
+  {
+    MDPoint<3,3> a;
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+    TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3*4+8);
+  }
+
+  void testConstructors_EvenMoreTemplateParameters()
+  {
+    MDPoint<3,3, MyExtraData> a;
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+    TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3*4 + 8 +sizeof(MyExtraData));
+  }
+
+
+  void testConstructorsWithCenters()
+  {
+    // Fixed-size array
+    CoordType coords[3] = {0.123, 1.234, 2.345};
+    MDPoint<3> a(2.5, 1.5, coords );
+    TS_ASSERT_EQUALS( a.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
+    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
+
+    // Dynamic array
+    CoordType * coords2 = new CoordType[5];
+    coords2[0] = 1.0;
+    coords2[1] = 2.0;
+    coords2[2] = 3.0;
+    // The array does not have to be the same size, it is safe if it is bigger (though why would you do that?)
+    MDPoint<3> b(2.5, 1.5, coords2 );
+    TS_ASSERT_EQUALS( b.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
+    TS_ASSERT_EQUALS( b.getCenter(0), 1);
+    TS_ASSERT_EQUALS( b.getCenter(1), 2);
+    TS_ASSERT_EQUALS( b.getCenter(2), 3);
+
+  }
+
+
+  // =============================================================================================
+  // =============================================================================================
+
+  void testCenter()
+  {
+    MDPoint<3> a;
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+
+    a.setCenter(0, 0.123);
+    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+
+    a.setCenter(1, 1.234);
+    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
+
+    a.setCenter(2, 2.345);
+    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
+  }
+
+  void testSetCenters()
+  {
+    MDPoint<3> a;
+    CoordType coords[3] = {0.123, 1.234, 2.345};
+    a.setCenters( coords );
+    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
+  }
+
+  void testCopyConstructor()
+  {
+    CoordType coords[3] = {0.123, 1.234, 2.345};
+    MDPoint<3> b(2.5, 1.5, coords );
+    MDPoint<3> a(b);
+    TS_ASSERT_EQUALS( a.getNumDims(), 3);
+    TS_ASSERT_EQUALS( a.getSignal(), 2.5);
+    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
+    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+    TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
+    TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
+  }
+
+
+
+  void test_getError()
+  {
+    MDPoint<3> a(2.0, 4.0);
+    TS_ASSERT_EQUALS( a.getSignal(), 2.0);
+    TS_ASSERT_EQUALS( a.getError(), 2.0);
+  }
+
+
+  // =============================================================================================
+  // =============================================================================================
+
+  void test_getExtra()
+  {
+    MDPoint<3,0,MyExtraData> a(2.0, 4.0);
+    TS_ASSERT_EQUALS( a.getSignal(), 2.0);
+    TS_ASSERT_EQUALS( a.getError(), 2.0);
+    a.getExtra().detectorID = 12;
+    a.getExtra().instrument = 'C';
+
+    MyExtraData & e = a.getExtra();
+    TS_ASSERT_EQUALS( e.detectorID, 12);
+    TS_ASSERT_EQUALS( e.instrument, 'C');
+
+    const MyExtraData & e2 = a.getExtra();
+    TS_ASSERT_EQUALS( e2.detectorID, 12);
+    TS_ASSERT_EQUALS( e2.instrument, 'C');
+  }
+
+  void test_setExtra()
+  {
+    MDPoint<3,0,MyExtraData> a(2.0, 4.0);
+    MyExtraData e;
+    e.detectorID = 34;
+    e.instrument = 'D';
+    a.setExtra(e);
+
+    TS_ASSERT_EQUALS( a.getExtra().detectorID, 34);
+    TS_ASSERT_EQUALS( a.getExtra().instrument, 'D');
+    // setExtra() made a copy of the extra
+    TS_ASSERT_DIFFERS( &a.getExtra(), &e);
+  }
+
+
+
+  // =============================================================================================
+  // =============================================================================================
+
+  void test_setCorner_individually()
+  {
+    // 2 dimensions, 3 vertices
+    MDPoint<2,3> a;
+    a.setCorner(0, 0, 0.123);
+    TS_ASSERT_EQUALS( a.getCorner(0,0), 0.123);
+
+    a.setCorner(0, 1, 1.234);
+    a.setCorner(1, 0, 2);
+    a.setCorner(1, 1, 3);
+    a.setCorner(2, 0, 4);
+    a.setCorner(2, 1, 5);
+
+    TS_ASSERT_EQUALS( a.getCorner(0,0), 0.123);
+    TS_ASSERT_EQUALS( a.getCorner(0,1), 1.234);
+    TS_ASSERT_EQUALS( a.getCorner(1,0), 2);
+    TS_ASSERT_EQUALS( a.getCorner(1,1), 3);
+  }
+
+
+  void test_setCorner_vertex()
+  {
+    // 2 dimensions, 3 vertices
+    MDPoint<2,3> a;
+    CoordType v0[2] = {1, 2};
+    CoordType v1[2] = {4, 5};
+    CoordType v2[2] = {9, 10};
+    // Set the entire vertex at once
+    a.setCorner(0, v0);
+    a.setCorner(1, v1);
+    a.setCorner(2, v2);
+
+    // They match!
+    for (size_t i=0; i<2; i++)
+    {
+      TS_ASSERT_EQUALS( a.getCorner(0)[i], v0[i]);
+      TS_ASSERT_EQUALS( a.getCorner(1)[i], v1[i]);
+      TS_ASSERT_EQUALS( a.getCorner(2)[i], v2[i]);
+    }
+
+    // But if you change the original, they no longer match
+    v1[1] = 45;
+    TS_ASSERT_DIFFERS( a.getCorner(1)[1], v1[1]);
+  }
+
+  //  void testCopyConstructor_with_Corners()
+  //  {
+  //    CoordType coords[2] = {0.123, 1.234};
+  //    // One corner vertec
+  //    CoordType corners[2][1] = {{5.691}, {7.2}};
+  //    MDPoint<2,1> b(2.5, 1.5, coords );
+  //    b.setCorners( corners);
+  //    // Do the copy
+  //    MDPoint<2,1> a(b);
+  //    TS_ASSERT_EQUALS( a.getNumDims(), 2);
+  //    TS_ASSERT_EQUALS( a.getSignal(), 2.5);
+  //    TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
+  //    TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
+  //    TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
+  //    TS_ASSERT_EQUALS( a.getCorner(0, 0), 5.691);
+  //    TS_ASSERT_EQUALS( a.getCorner(0, 1), 7.2);
+  //  }
+
+};
+
+#endif