diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h
index 5b5e6087eeb9be7d8805931edec4649881c027e9..2b0c7e6c99e43e70379e3d418b1d9989db1d1d46 100644
--- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h
+++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h
@@ -101,6 +101,8 @@ namespace Mantid
       API::IAlgorithm_sptr m_loader;
       /// The name of the property that will be passed the property from our Filename
       std::string m_filenamePropName;
+      /// Indicate whether a collection of files should be loaded into a single workspace.
+      bool m_loadMultipleAsOne;
       /// Mutex for temporary fix for #5963
       static Poco::Mutex m_mutex;
     };
diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h
index 06ee83f0b034eccfdaf95040cef4fec99f38ee74..9c54ea0a5408e8629334237e20091352c15f3d25 100644
--- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h
+++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h
@@ -2,7 +2,26 @@
 #define MANTID_DATAHANDLING_LOADFITS_H_
 
 #include "MantidAPI/IFileLoader.h"
-
+#include <string>
+#include <sstream>
+#include <map>
+#include <vector>
+
+using namespace std;
+
+struct FITSInfo {  
+  vector<string> headerItems;
+  map<string, string> headerKeys;
+  int bitsPerPixel;
+  int numberOfAxis;
+  vector<int> axisPixelLengths;
+  double tof;
+  double timeBin;
+  long int countsInImage;
+  long int numberOfTriggers;
+  string extension;
+  string filePath;
+}; 
 
 namespace Mantid
 {
@@ -58,6 +77,14 @@ namespace DataHandling
     /// Execution code
     void exec();
     
+    /// Parses the header values for the FITS file
+    bool parseHeader(FITSInfo &headerInfo);
+    void loadSingleBinFromFile(Mantid::API::MatrixWorkspace_sptr &workspace, FITSInfo &fitsInfo, MantidVecPtr &x, long spetraCount, long binIndex);
+
+    API::MatrixWorkspace_sptr initAndPopulateHistogramWorkspace();
+
+    vector<FITSInfo> m_allHeaderInfo;
+
     ///// Implement abstract Algorithm methods
     //void init();
     ///// Implement abstract Algorithm methods
@@ -86,9 +113,7 @@ namespace DataHandling
 
 
   };
-
-
-
+  
 
 } // namespace DataHandling
 } // namespace Mantid
diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp
index 3e9be99234919b47dbbe9671a253d7d65d5961e4..ec4e7d39b898d8bf9b67e23f37cbe292c3978635 100644
--- a/Code/Mantid/Framework/DataHandling/src/Load.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp
@@ -225,11 +225,18 @@ namespace Mantid
       const auto & props = loader->getProperties();
       for(auto it = props.begin(); it != props.end(); ++it)
       {
-        if(auto *fp = dynamic_cast<API::FileProperty*>(*it))
+        auto *fp = dynamic_cast<API::MultipleFileProperty*>(*it); 
+        auto *fp2 = dynamic_cast<API::FileProperty*>(*it);
+        if(fp)
         {
           m_filenamePropName = fp->name();
           break;
         }
+        if(fp2)
+        {
+          m_filenamePropName = fp2->name();
+          break;
+        }
       }
       if(m_filenamePropName.empty())
       {
@@ -296,6 +303,7 @@ namespace Mantid
       exts.push_back(".h5");
       exts.push_back(".hd5");
       exts.push_back(".sqw");
+      exts.push_back(".fits");
 
       declareProperty(new MultipleFileProperty("Filename", exts),
         "The name of the file(s) to read, including the full or relative "
@@ -323,11 +331,15 @@ namespace Mantid
      * Executes the algorithm.
      */
     void Load::exec()
-    {
+    { 
       std::vector<std::vector<std::string> > fileNames = getProperty("Filename");
       
-      if(isSingleFile(fileNames))
-      {
+      // Test for loading as a single file      
+      IAlgorithm_sptr loader = getFileLoader(fileNames[0][0]);
+      m_loadMultipleAsOne = dynamic_cast<MultipleFileProperty*>(loader->getPointerToProperty("Filename")) != NULL;
+
+      if(isSingleFile(fileNames) || m_loadMultipleAsOne)
+      {        
         // This is essentially just the same code that was called before multiple files were supported.
         loadSingleFile();
       }
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp
index 2275a68b8699b835b46b44082a262f2d24c1c724..7c2717abc86dcad78c67337ebb950f5a7cb6e153 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp
@@ -2,7 +2,21 @@
 
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidAPI/FileProperty.h"
+#include "MantidAPI/MultipleFileProperty.h"
 #include "MantidAPI/RegisterFileLoader.h"
+
+#include "MantidAPI/SpectraAxis.h"
+#include "MantidAPI/NumericAxis.h"
+#include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidGeometry/Instrument/RectangularDetector.h"
+#include "MantidKernel/UnitFactory.h"
+#include "MantidDataObjects/Workspace2D.h"
+
+#include <Poco/BinaryReader.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+
 //#include "MantidAPI/WorkspaceValidators.h"
 //#include "MantidKernel/UnitFactory.h"
 //#include "MantidGeometry/Instrument.h"
@@ -19,276 +33,320 @@
 
 using namespace Mantid::DataHandling;
 using namespace Mantid::API;
+using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
+using namespace std;
+using namespace boost::algorithm;
+using namespace boost;
+using Poco::BinaryReader;
+
+
+using Mantid::MantidVec;
+using Mantid::MantidVecPtr;
+
+
 
 namespace Mantid
 {
 namespace DataHandling
 {
-  // Register the algorithm into the AlgorithmFactory
-  DECLARE_FILELOADER_ALGORITHM(LoadFITS);
-
-  int LoadFITS::confidence(Kernel::FileDescriptor & descriptor) const
-  {
-      return (descriptor.extension() == ".fits" || descriptor.extension() == ".fit") ? 80 : 0; 
-  }
-
-  /**
-  * Execute the algorithm.
-  */
-  void LoadFITS::exec()
-  {
-    // Delete the output workspace name if it existed
-    std::string outName = getPropertyValue("OutputWorkspace");
-    if (AnalysisDataService::Instance().doesExist(outName))
-      AnalysisDataService::Instance().remove(outName);
-
-    // Get the name of the file.
-    std::string filenameBin = getPropertyValue("Filename");
-      
-    size_t nBins  = 1;
-    double tofMinBoundary = 5;
-    double tofMaxBoundary = 5;
-      
-    //// 100 for "loading neutron counts", 100 for "creating neutron event lists", 100 for "loading neutron events"
-    //Progress prog(this, 0.0, 1.0, 100 + 100 + 100);
-    //prog.doReport("creating instrument");
-
-    // Create a workspace
-    DataObjects::EventWorkspace_sptr eventWS(new DataObjects::EventWorkspace());
-
-    eventWS->initialize(
-        nHist,
-        nBins + 1,  // number of TOF bin boundaries
-        nBins);
-
-    // Set the units
-    eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
-    eventWS->setYUnit("Counts");
-
-    // ???
-    //eventWS->setYUnitLabel("Counts");      
-
-    eventWS->setTitle("my title");
-    eventWS->mutableRun().addProperty("Filename", filenameBin);
-    //eventWS->mutableRun().addProperty("run_number", 1);
-    //eventWS->mutableRun().addProperty("run_start", "1991-01-01T00:00:00", true );
-    //eventWS->mutableRun().addProperty("duration", duration[0], units);
-
-    // Build instrument geometry
-
-    // Create a new instrument and set its name
-    std::string instrumentname = "BILBY";
-    Geometry::Instrument_sptr instrument(new Geometry::Instrument(instrumentname));
-    eventWS->setInstrument(instrument);
-
-    // Add dummy source and samplepos to instrument
-
-    // Create an instrument component wich will represent the sample position.
-    Geometry::ObjComponent *samplepos = new Geometry::ObjComponent("Sample",instrument.get());
-    instrument->add(samplepos);
-    instrument->markAsSamplePos(samplepos);
-    // Put the sample in the centre of the coordinate system
-    samplepos->setPos(0.0,0.0,0.0);
-
-    // Create a component to represent the source
-    Geometry::ObjComponent *source = new Geometry::ObjComponent("Source",instrument.get());
-    instrument->add(source);
-    instrument->markAsSource(source);
-
-    // Read in the L1 value and place the source at (0,0,-L1)
-    double l1 = 3949.1824;
-    source->setPos(0.0,0.0,-1.0*l1);
-
-    // Create a component for the detector.
-      
-    size_t xPixelCount = HISTO_BINS_X / 6;
-    size_t yPixelCount = HISTO_BINS_Y;
-    size_t pixelCount = xPixelCount * yPixelCount;
-      
-    // We assumed that these are the dimensions of the detector, and height is in y direction and width is in x direction
-    double width  = 0.4; // meters
-    double height = 1.0;
-
-    // We assumed that individual pixels have the same size and shape of a cuboid with dimensions:
-    double pixel_width  = width  / static_cast<double>(xPixelCount);
-    double pixel_height = height / static_cast<double>(yPixelCount);
-
-    // Create size strings for shape creation
-    std::string pixel_width_str  = boost::lexical_cast<std::string>(pixel_width / 2);
-    std::string pixel_height_str = boost::lexical_cast<std::string>(pixel_height / 2);
-    std::string pixel_depth_str  = "0.00001"; // Set the depth of a pixel to a very small number
-
-    // Define shape of a pixel as an XML string. See http://www.mantidproject.org/HowToDefineGeometricShape for details
-    // on shapes in Mantid.
-    std::string detXML =
-      "<cuboid id=\"pixel\">"
-        "<left-front-bottom-point   x=\"+"+pixel_width_str+"\" y=\"-"+pixel_height_str+"\" z=\"0\"  />"
-        "<left-front-top-point      x=\"+"+pixel_width_str+"\" y=\"-"+pixel_height_str+"\" z=\""+pixel_depth_str+"\"  />"
-        "<left-back-bottom-point    x=\"-"+pixel_width_str+"\" y=\"-"+pixel_height_str+"\" z=\"0\"  />"
-        "<right-front-bottom-point  x=\"+"+pixel_width_str+"\" y=\"+"+pixel_height_str+"\" z=\"0\"  />"
-      "</cuboid>";
-
-    // Create a shape object which will be shared by all pixels.
-    Geometry::Object_sptr shape = Geometry::ShapeFactory().createShape(detXML);
-      
-    double detectorZ =  5;
-    double angle     = 10;
-
-    double curtZOffset = width / 2 * sin(angle * 3.14159265359 / 180);
-
-    if (!filenameHdf.empty()) {
-      NeXus::NXRoot root(filenameHdf);
-      NeXus::NXEntry entry = root.openFirstEntry();
-     
-    }
-
-    // 6 detector banks are available
-
-    // curtain 1
-    AddDetectorBank(
-      instrument,
-      xPixelCount,
-      yPixelCount,
-      0 * pixelCount,
-      shape,
-      width,
-      height,
-      Kernel::V3D(+(width + height) / 2, 0, detectorZ - curtZOffset),
-      Kernel::Quat(  0, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0)));
-      
-    // curtain 2
-    AddDetectorBank(
-      instrument,
-      xPixelCount,
-      yPixelCount,
-      1 * pixelCount,
-      shape,
-      width,
-      height,
-      Kernel::V3D(-(width + height) / 2, 0, detectorZ - curtZOffset),
-      Kernel::Quat(180, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0)));
-      
-    // curtain 3
-    AddDetectorBank(
-      instrument,
-      xPixelCount,
-      yPixelCount,
-      2 * pixelCount,
-      shape,
-      width,
-      height,
-      Kernel::V3D(0, +(width + height) / 2, detectorZ - curtZOffset),
-      Kernel::Quat( 90, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0)));
-      
-    // curtain 4
-    AddDetectorBank(
-      instrument,
-      xPixelCount,
-      yPixelCount,
-      3 * pixelCount,
-      shape,
-      width,
-      height,
-      Kernel::V3D(0, -(width + height) / 2, detectorZ - curtZOffset),
-      Kernel::Quat(-90, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0)));
-      
-    // back 1
-    AddDetectorBank(
-      instrument,
-      xPixelCount,
-      yPixelCount,
-      4 * pixelCount,
-      shape,
-      width,
-      height,
-      Kernel::V3D(-width / 2 - 0.05, 0, detectorZ),
-      Kernel::Quat(180, Kernel::V3D(0, 0, 1)));
-      
-    // back 2
-    AddDetectorBank(
-      instrument,
-      xPixelCount,
-      yPixelCount,
-      5 * pixelCount,
-      shape,
-      width,
-      height,
-      Kernel::V3D(+width / 2 + 0.05, 0, detectorZ),
-      Kernel::Quat(  0, Kernel::V3D(0, 0, 1)));
-
-    // load events
-                  
-    size_t numberHistograms = eventWS->getNumberHistograms();
-
-    std::vector<EventVector_pt> eventVectors(numberHistograms, NULL);
-    std::vector<size_t> eventCounts(numberHistograms, 0);
-		std::vector<detid_t> detIDs = instrument->getDetectorIDs();
-
-    // count total events per pixel to reserve necessary memory
-    LoadFile_Counts(prog, filenameBin, HISTO_BINS_X, HISTO_BINS_Y, tofMinBoundary, tofMaxBoundary, eventCounts);
-      
-    // for progress notifications
-    size_t progCount = 100;
-    size_t progStep  = numberHistograms / progCount;
-    size_t progNext  = progStep;
-      
-    auto progMsg = "creating neutron event lists";
-    prog.doReport(progMsg);
-    for (size_t i = 0; i != numberHistograms; ++i) {
-      DataObjects::EventList& eventList = eventWS->getEventList(i);
-
-      eventList.setSortOrder(DataObjects::PULSETIME_SORT); // why not PULSETIME[TOF]_SORT ?
-      eventList.reserve(eventCounts[i]);
-      eventList.setDetectorID(detIDs[i]);
-			eventList.setSpectrumNo(detIDs[i]);  
-
-      DataObjects::getEventsFrom(eventList, eventVectors[i]);
-
-      if ((progNext <= i) && (progCount != 0)) {
-        prog.report(progMsg);
-        progNext += progStep;
-        progCount--;
-      }
-    }
-    if (progCount != 0)
-      prog.reportIncrement(progCount, progMsg);
-      
-    double shortest_tof(0.0), longest_tof(0.0);
-    LoadFile_Events(prog, filenameBin, HISTO_BINS_X, HISTO_BINS_Y, tofMinBoundary, tofMaxBoundary, eventVectors, shortest_tof, longest_tof);
-
-    cow_ptr<MantidVec> axis;
-    MantidVec& xRef = axis.access();
-    xRef.resize(2, 0.0);
-    if (longest_tof != 0.0) {
-      xRef[0] = std::max(0.0, shortest_tof - 1); // just to make sure the bins hold it all
-      xRef[1] = longest_tof + 1;
-    }
-    eventWS->setAllX(axis);
-
-    setProperty("OutputWorkspace", eventWS);
-  }
-
-  /**
-  * Initialise the algorithm. Declare properties which can be set before execution (input) or 
-  * read from after the execution (output).
-  */
-  void LoadFITS::init()
-  {
-    // Specify file extensions which can be associated with a BBY file.
-    std::vector<std::string> exts;
-
-    // Declare the Filename algorithm property. Mandatory. Sets the path to the file to load.
-    exts.clear();
-    exts.push_back(".fit");  
-    declareProperty(
-    new API::FileProperty("Filename", "", API::FileProperty::Load, exts),
-    "The input filename of the stored data");
-      
-    declareProperty(
-    new API::WorkspaceProperty<API::IEventWorkspace>("OutputWorkspace", "", Kernel::Direction::Output));
-  }
-
+	// Register the algorithm into the AlgorithmFactory
+	DECLARE_FILELOADER_ALGORITHM(LoadFITS);
+
+	int LoadFITS::confidence(Kernel::FileDescriptor & descriptor) const
+	{
+		// TODO should improve this to check the file header (of first file at least) to make sure it contains the fields wanted
+			return (descriptor.extension() == ".fits" || descriptor.extension() == ".fit") ? 80 : 0; 
+	}
+
+	/**
+	* Execute the algorithm.
+	*/
+	void LoadFITS::exec()
+	{
+		// TODO check that each map check actually has the key required when searched for. raise error if not.
+	 
+		// Create FITS file information for each file selected
+		std::vector<std::string> paths;
+		boost::split(paths, getPropertyValue("Filename"), boost::is_any_of(","));
+
+		m_allHeaderInfo.resize(paths.size());
+
+		// Check each header is valid for this loader, - standard (no extension to FITS), and has two axis
+		bool headerValid = true;
+
+		for(int i=0; i<paths.size();++i)
+		{
+			m_allHeaderInfo[i].extension = "";
+			m_allHeaderInfo[i].filePath = paths[i];
+			// Get various pieces of information from the file header which are used to create the workspace
+			if(parseHeader(m_allHeaderInfo[i]))
+			{
+				// Get and convert specific header values which will help when parsing the data
+				// BITPIX, NAXIS, NAXISi (where i = 1..NAXIS, e.g. NAXIS2 for two axis), TOF, TIMEBIN, N_COUNTS, N_TRIGS
+				try
+				{
+					m_allHeaderInfo[i].bitsPerPixel = lexical_cast<int>(m_allHeaderInfo[i].headerKeys["BITPIX"]);
+					m_allHeaderInfo[i].numberOfAxis = lexical_cast<int>(m_allHeaderInfo[i].headerKeys["NAXIS"]);
+			
+					for(int j=0; j<m_allHeaderInfo[i].numberOfAxis; ++j)
+					{
+						string keyName = "NAXIS" + lexical_cast<string>(j+1);
+						m_allHeaderInfo[i].axisPixelLengths.push_back(lexical_cast<int>(m_allHeaderInfo[i].headerKeys[keyName]));
+					}
+
+					m_allHeaderInfo[i].tof = lexical_cast<double>(m_allHeaderInfo[i].headerKeys["TOF"]);
+					m_allHeaderInfo[i].timeBin = lexical_cast<double>(m_allHeaderInfo[i].headerKeys["TIMEBIN"]);
+					m_allHeaderInfo[i].countsInImage = lexical_cast<long int>(m_allHeaderInfo[i].headerKeys["N_COUNTS"]);
+					m_allHeaderInfo[i].numberOfTriggers = lexical_cast<long int>(m_allHeaderInfo[i].headerKeys["N_TRIGS"]);
+					m_allHeaderInfo[i].extension = m_allHeaderInfo[i].headerKeys["XTENSION"]; // Various extensions are available to the FITS format, and must be parsed differently if this is present
+				}
+				catch(bad_lexical_cast &)
+				{
+					//todo write error and fail this load with invalid data in file.
+				}
+
+				if(m_allHeaderInfo[i].extension != "") headerValid = false;
+				if(m_allHeaderInfo[i].numberOfAxis != 2) headerValid = false;
+
+				// Test current item has same axis values as first item.
+				if(m_allHeaderInfo[0].axisPixelLengths[0] != m_allHeaderInfo[i].axisPixelLengths[0]) headerValid = false;
+				if(m_allHeaderInfo[0].axisPixelLengths[1] != m_allHeaderInfo[i].axisPixelLengths[1]) headerValid = false;
+			}
+
+		}
+
+		// Check the format is correct and create the Workspace  
+		if(headerValid)
+		{
+			// No extension is set, therefore it's the standard format which we can parse.
+			
+			// Delete the output workspace name if it existed
+			std::string outName = getPropertyValue("OutputWorkspace");
+			if (AnalysisDataService::Instance().doesExist(outName))   AnalysisDataService::Instance().remove(outName);
+						
+			MatrixWorkspace_sptr ws;
+			
+			ws = initAndPopulateHistogramWorkspace();    
+
+			// Assign it to the output workspace property
+			setProperty("OutputWorkspace",ws);
+		}
+		else
+		{
+			// Invalid files, record error
+			// TODO
+
+		}
+	}
+
+	/**
+	* Initialise the algorithm. Declare properties which can be set before execution (input) or 
+	* read from after the execution (output).
+	*/
+	void LoadFITS::init()
+	{
+		// Specify file extensions which can be associated with a FITS file.
+		std::vector<std::string> exts;
+
+		// Declare the Filename algorithm property. Mandatory. Sets the path to the file to load.
+		exts.clear();
+		exts.push_back(".fits");
+		exts.push_back(".fit");
+		
+		// Specify as a MultipleFileProperty to alert loader we want multiple selected files to be loaded into a single workspace.
+		declareProperty(new MultipleFileProperty("Filename", exts), "The input filename of the stored data");
+		
+		declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace", "", Kernel::Direction::Output));    
+	}
+
+
+	bool LoadFITS::parseHeader(FITSInfo &headerInfo)
+	{
+		// TODO test file exists, test file can be read, make it return false if failed.
+		bool ranSuccessfully = true;
+		ifstream istr(headerInfo.filePath, ios::binary);
+		Poco::BinaryReader reader(istr);
+	
+		// Iterate 80 bytes at a time until header is parsed | 2880 bytes is the fixed header length of FITS
+		// 2880/80 = 36 iterations required
+		for(int i=0; i < 36; ++i)
+		{   
+			// Keep vect of each header item, including comments, and also keep a map of individual keys.
+			string part;
+			reader.readRaw(80,part);  
+			headerInfo.headerItems.push_back(part);
+		
+			// Add key/values - these are separated by the = symbol. 
+			// If it doesn't have an = it's a comment to ignore. All keys should be unique
+			int eqPos = part.find('=');
+			if(eqPos > 0)
+			{        
+				string key = part.substr(0, eqPos);
+				string value = part.substr(eqPos+1);
+				
+				// Comments are added after the value separated by a / symbol. Remove.
+				int slashPos = value.find('/');
+				if(slashPos > 0) value = value.substr(0, slashPos);
+ 
+				boost::trim(key);
+				boost::trim(value);
+				headerInfo.headerKeys[key] = value;
+			}    
+		}
+
+		istr.close();
+
+		return ranSuccessfully;
+	}
+
+		//----------------------------------------------------------------------------------------------
+		/** Create histogram workspace
+	 */
+	MatrixWorkspace_sptr LoadFITS::initAndPopulateHistogramWorkspace()
+	{
+		// TODO will take vector of FITSInfo for multiple files and load all into workspace
+
+		MantidVecPtr x;
+		x.access().resize(m_allHeaderInfo.size() + 1);
+
+		// X = TIMEBIN value
+		x.access()[0] = m_allHeaderInfo[0].timeBin;
+		x.access()[1] = m_allHeaderInfo[0].timeBin + m_allHeaderInfo[0].tof;
+
+		long spectraCount = 0;
+		if(m_allHeaderInfo[0].numberOfAxis > 0) spectraCount += m_allHeaderInfo[0].axisPixelLengths[0];
+
+		// Presumably 2 axis, but futureproofing.
+		for(int i=1;i<m_allHeaderInfo[0].numberOfAxis;++i)
+		{
+			spectraCount *= m_allHeaderInfo[0].axisPixelLengths[i];
+		}
+
+		MatrixWorkspace_sptr retVal(new DataObjects::Workspace2D);
+		retVal->initialize(spectraCount, m_allHeaderInfo.size()+1, m_allHeaderInfo.size());
+
+		IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument");
+
+		try 
+		{
+			std::string directoryName = Kernel::ConfigService::Instance().getInstrumentDirectory();
+			directoryName = directoryName + "/IMAT_Definition.xml";
+			
+			loadInst->setPropertyValue("Filename", directoryName);
+			loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", retVal);
+			loadInst->execute();
+		} 
+		catch (std::exception ex) 
+		{
+			g_log.information("Cannot load the instrument definition. " + string(ex.what()) );
+		}
+
+		for(int i=0; i<m_allHeaderInfo.size();++i)
+		{
+			loadSingleBinFromFile(retVal, m_allHeaderInfo[i], x, spectraCount, i);
+		}
+		
+		retVal->mutableRun().addProperty("Filename", m_allHeaderInfo[0].filePath);
+
+		// Set the Unit of the X Axis
+		try
+		{
+			retVal->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
+		}
+		catch ( Exception::NotFoundError & )
+		{
+			retVal->getAxis(0)->unit() = UnitFactory::Instance().create("Label");
+			Unit_sptr unit = retVal->getAxis(0)->unit();
+			boost::shared_ptr<Units::Label> label = boost::dynamic_pointer_cast<Units::Label>(unit);
+			label->setLabel("TOF", "TOF");
+		}
+
+		retVal->setYUnit("Counts");
+		retVal->setTitle("Test Workspace");
+
+		return retVal;
+	}
+
+ 
+
+	void LoadFITS::loadSingleBinFromFile(MatrixWorkspace_sptr &workspace, FITSInfo &fitsInfo, MantidVecPtr &x, long spectraCount, long binIndex)
+	{
+		// READ DATA
+		ifstream istr(fitsInfo.filePath, ios::binary);
+		Poco::BinaryReader reader(istr);
+		string tmp;
+		reader.readRaw(2880, tmp); // Read header as full block to skip to data
+		// read bitdepth*naxis1 num of bits for first row? repeat naxis2 number of times.
+		int bytesPerRow = (fitsInfo.bitsPerPixel*fitsInfo.axisPixelLengths[0])/8;
+		
+		int allDataSizeBytes = (fitsInfo.bitsPerPixel*fitsInfo.axisPixelLengths[0]*fitsInfo.axisPixelLengths[1])/8 ;
+		string allData;
+		reader >> allData;
+		stringstream ss;
+		ss << allData;
+
+		int currPixel, currRow = 0;
+		int8_t tmp8; 
+		int16_t tmp16; 
+		int32_t tmp32;    
+		
+		for(int i=0;i<fitsInfo.axisPixelLengths[1]; ++i) // loop rows
+		{
+			// Read all columns on this row. As MantidVecPt->setData expects vectors, populate data vectors for y and e.
+			//data.push_back(vector<double>());
+			currRow = i*fitsInfo.axisPixelLengths[0];
+
+			for(int j=0; j<fitsInfo.axisPixelLengths[0];++j)
+			{
+				double val = 0;
+				switch(fitsInfo.bitsPerPixel)
+				{
+				case 8:          
+					ss >> tmp8;         
+					val = static_cast<double>(tmp8);
+				case 16: // 2 bytes uint_16           
+					ss >> tmp16;
+					val = static_cast<double>(tmp16);
+					break;
+				case 32:          
+					ss >> tmp32;
+					val = static_cast<double>(tmp32);
+					break;
+				default:
+					// TODO unhandled, report error.
+					break;
+				}      
+				
+				currPixel = currRow + j;
+				workspace->setX(currPixel,x); 
+			 
+				//workspace->setData(currPixel,y,e);
+				workspace->dataY(currPixel)[binIndex] = val;
+				workspace->dataE(currPixel)[binIndex] = sqrt(val);
+				//workspace->dataX(currPixel)[binIndex] = x[0];
+
+				workspace->getSpectrum(currPixel)->setDetectorID(detid_t(currPixel));
+				workspace->getSpectrum(currPixel)->setSpectrumNo(specid_t(currPixel+1));
+			}
+			
+		}
+
+
+
+	}
 
 }
-}
\ No newline at end of file
+}
+
+// TODO: Correctly populate X values.
+
+// about 12 seconds creating child algorithm
+// about 18 s loading idf
+
+// can probably create a vect for each bin and populate them all at once. faster?
+//
+//		std::clock_t start;
+//		double duration;
+//		start = std::clock();
+//duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
\ No newline at end of file
diff --git a/Code/Mantid/instrument/IMAT_Definition.xml b/Code/Mantid/instrument/IMAT_Definition.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6d3a86471bb3befe35d983648e20fd7759846b20
--- /dev/null
+++ b/Code/Mantid/instrument/IMAT_Definition.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- For help on the notation used to specify an Instrument Definition File
+see http://www.mantidproject.org/IDF -->
+<instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd"
+name="IMAT" valid-from ="1900-01-31 23:59:59"
+valid-to ="2014-08-12 23:59:59"
+last-modified="2014-08-12 00:00:00">
+  <defaults>
+    <length unit="meter"/>
+    <angle unit="degree"/>
+    <reference-frame>
+      <!-- The z-axis is set parallel to and in the direction of the beam. the
+y-axis points up and the coordinate system is right handed. -->
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+    </reference-frame>
+    <default-view axis-view="z-"/>
+  </defaults>
+  <!-- BRIEF DESCRIPTION OF SANS2d INSTRUMENT:
+Data provided by Richard Heenan (and Freddie) for the SANS2D instrument
+12/06/09 this version has X & Y coords detector swapped so orientation
+is correct for temporary wiring table.
+18/06/09 better distances for detectors and both at L2=4m, front at X=-1.1m
+26/06/09 swap front & rear as names wrong, translate front in opposite direction
+21/07/09 remove the 150mm sideways shift (i.e. back to symmetrical detector coords)
+to simplify manipulations in Mantid and help allow for detector mapping not quite
+as expected.
+01/02/10 very small chang eto pixel size 191*5.1=974.2=2*487.05 (was 487.4)
+- note have to swap x= and y= in Anders output list !
+02/04/12 Put in 'no shape monitors' for possible in the future monitors
+with ID 5-8
+-->
+  <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+  <!-- source and sample-position components -->
+  <component type="source">
+    <location />
+  </component>
+  <type name="source" is="Source" />
+  <component type="some-sample-holder">
+    <location z="19.281"/>
+  </component>
+  <type name="some-sample-holder" is="SamplePos" />
+  <!-- detector components (including monitors) -->
+  <component type="monitors" idlist="monitors">
+    <location />
+  </component>
+  <type name="monitors">
+    <component type="monitor-tbd">
+      <!-- better positions and shapes will be defined later -->
+      <location z="7.217" name="monitor1"/>
+      <location z="17.937" name="monitor2"/>
+    </component>
+    <component type="Moderator-Monitor3">
+      <!-- transmisssion detector, either in or out of beam -->
+      <location z="19.497" name="monitor3"/>
+    </component>
+    <component type="monitor-tbd">
+      <!-- better positions and shapes will be defined later -->
+      <location z="30.0" name="monitor4"/>
+    </component>
+    <!-- Putting in monitors, which are defined in raw/neuxs
+files, and have detector IDs, but currently not physically present
+on the instrument. Defined with no geometric shape, as they do not
+physically exist, and with a dummy position -->
+    <component type="no shape monitor">
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>
+    </component>
+  </type>
+  <type name="monitor-tbd" is="monitor">
+    <cylinder id="some-shape">
+      <centre-of-bottom-base r="0.0" t="0.0" p="0.0" />
+      <axis x="0.0" y="0.0" z="1.0" />
+      <radius val="0.01" />
+      <height val="0.03" />
+    </cylinder>
+  </type>
+  <type name="Moderator-Monitor3" is="monitor">
+    <percent-transparency val="99.9" />
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.0125" y="-0.0125" z="0.0" />
+      <left-front-top-point x="0.0125" y="-0.0125" z="0.005" />
+      <left-back-bottom-point x="-0.0125" y="-0.0125" z="0.0" />
+      <right-front-bottom-point x="0.0125" y="0.0125" z="0.0" />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+  <type name="no shape monitor" is="monitor" />
+  <component type="detector-bank" idstart="2000000" idfillbyfirst="y" idstep="1000" idstepbyrow="1">
+    <location x="1.1" z="23.281" name="front-detector"/>
+  </component>
+  <component type="detector-bank" idstart="1000000" idfillbyfirst="y" idstep="1000" idstepbyrow="1">
+    <location z="23.281" name="rear-detector"/>
+  </component>
+  <type name="detector-bank" is="rectangular_detector" type="pixel"
+  xpixels="512" xstart="-0.48705" xstep="+0.0051"
+  ypixels="512" ystart="-0.48705" ystep="+0.0051" >
+  </type>
+  <type name="pixel" is="detector">
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.005104167" y="-0.005104167" z="0.0" />
+      <left-front-top-point x="0.005104167" y="-0.005104167" z="0.000005" />
+      <left-back-bottom-point x="-0.005104167" y="-0.005104167" z="0.0" />
+      <right-front-bottom-point x="0.005104167" y="0.005104167" z="0.0" />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+  <!-- DETECTOR and MONITOR ID LISTS -->
+  <idlist idname="monitors">
+    <id start="1" end="8" />
+  </idlist>
+</instrument>
\ No newline at end of file