diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt
index b05af4d8b211ade97f9e24d7012b2be2e325cfec..51b57165e7ed6c8731ee2b58a0c9064cc48e7bdc 100644
--- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt
+++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt
@@ -175,6 +175,7 @@ set ( SRC_FILES
 	src/Rebin.cpp
 	src/Rebin2D.cpp
 	src/RebinByPulseTimes.cpp
+	src/RebinByTimeAtSample.cpp
 	src/RebinToWorkspace.cpp
 	src/Rebunch.cpp
 	src/RecordPythonScript.cpp
@@ -416,6 +417,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/Rebin.h
 	inc/MantidAlgorithms/Rebin2D.h
 	inc/MantidAlgorithms/RebinByPulseTimes.h
+	inc/MantidAlgorithms/RebinByTimeAtSample.h
 	inc/MantidAlgorithms/RebinToWorkspace.h
 	inc/MantidAlgorithms/Rebunch.h
 	inc/MantidAlgorithms/RecordPythonScript.h
@@ -556,8 +558,8 @@ set ( TEST_FILES
 	CreatePeaksWorkspaceTest.h
 	CreateSampleWorkspaceTest.h
 	CreateSingleValuedWorkspaceTest.h
-	CreateTransmissionWorkspaceTest.h
 	CreateTransmissionWorkspaceAutoTest.h
+	CreateTransmissionWorkspaceTest.h
 	CreateWorkspaceTest.h
 	CropWorkspaceTest.h
 	CuboidGaugeVolumeAbsorptionTest.h
@@ -652,6 +654,7 @@ set ( TEST_FILES
 	RealFFTTest.h
 	Rebin2DTest.h
 	RebinByPulseTimesTest.h
+	RebinByTimeAtSampleTest.h
 	RebinTest.h
 	RebinToWorkspaceTest.h
 	RebunchTest.h
diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1a2ec8f6c31ee30d81fc163a18db5dab645f6b0
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h
@@ -0,0 +1,56 @@
+#ifndef MANTID_ALGORITHMS_REBINBYTIMEATSAMPLE_H_
+#define MANTID_ALGORITHMS_REBINBYTIMEATSAMPLE_H_
+
+#include "MantidKernel/System.h"
+#include "MantidAPI/Algorithm.h"
+
+namespace Mantid
+{
+namespace Algorithms
+{
+
+  /** RebinByTimeAtSample : Rebins an event workspace to a histogram workspace with time at sample along the x-axis.
+    
+    Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+
+    This file is part of Mantid.
+
+    Mantid is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    Mantid is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+    File change history is stored at: <https://github.com/mantidproject/mantid>
+    Code Documentation is available at: <http://doxygen.mantidproject.org>
+  */
+  class DLLExport RebinByTimeAtSample  : public API::Algorithm
+  {
+  public:
+    RebinByTimeAtSample();
+    virtual ~RebinByTimeAtSample();
+    
+    virtual const std::string name() const;
+    virtual int version() const;
+    virtual const std::string category() const;
+    virtual const std::string summary() const;
+
+  private:
+    void init();
+    void exec();
+
+
+  };
+
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif  /* MANTID_ALGORITHMS_REBINBYTIMEATSAMPLE_H_ */
diff --git a/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp b/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp
index 3720ed4230ac85d450f623b42fb42aa6d73cb341..0fab219230bb75d095c33485cd20eb4e0e73ba34 100644
--- a/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp
@@ -70,7 +70,7 @@ namespace Algorithms
     declareProperty(
       new ArrayProperty<double>("Params", boost::make_shared<RebinParamsValidator>()),
       "A comma separated list of first bin boundary, width, last bin boundary. Optionally\n"
-      "this can be followed by a comma and more widths and last boundary pairs.");
+      "this can be followed by a comma and more widths and last boundary pairs. Values are in seconds since run start.");
     declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace","",Direction::Output), "An output workspace.");
   }
 
@@ -86,7 +86,7 @@ namespace Algorithms
       throw std::invalid_argument("RebinByPulseTimes requires an EventWorkspace as an input.");
     }
 
-    MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // TODO: MUST BE A HISTOGRAM WORKSPACE!
+    MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
 
     // retrieve the properties
     const std::vector<double> inParams =getProperty("Params");
diff --git a/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp b/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cc3bfb093b6cc6fd400436be073809bac3e23f0a
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp
@@ -0,0 +1,230 @@
+#include "MantidAlgorithms/RebinByTimeAtSample.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/RebinParamsValidator.h"
+#include "MantidKernel/VectorHelper.h"
+#include "MantidKernel/Unit.h"
+#include <boost/make_shared.hpp>
+#include <boost/assign/list_of.hpp>
+#include <algorithm>
+
+namespace Mantid
+{
+  namespace Algorithms
+  {
+    using namespace Mantid::Kernel;
+    using namespace Mantid::API;
+
+    /**
+     Helper method to transform a MantidVector containing absolute times in nanoseconds to relative times in seconds given an offset.
+     */
+    class ConvertToRelativeTime: public std::unary_function<const MantidVec::value_type&,
+        MantidVec::value_type>
+    {
+    private:
+      double m_offSet;
+    public:
+      ConvertToRelativeTime(const DateAndTime& offSet) :
+          m_offSet(static_cast<double>(offSet.totalNanoseconds()) * 1e-9)
+      {
+      }
+      MantidVec::value_type operator()(const MantidVec::value_type& absTNanoSec)
+      {
+        return (absTNanoSec * 1e-9) - m_offSet;
+      }
+    };
+
+
+
+    // Register the algorithm into the AlgorithmFactory
+    DECLARE_ALGORITHM(RebinByTimeAtSample)
+
+    //----------------------------------------------------------------------------------------------
+    /** Constructor
+     */
+    RebinByTimeAtSample::RebinByTimeAtSample()
+    {
+    }
+
+    //----------------------------------------------------------------------------------------------
+    /** Destructor
+     */
+    RebinByTimeAtSample::~RebinByTimeAtSample()
+    {
+    }
+
+    //----------------------------------------------------------------------------------------------
+
+    /// Algorithm's version for identification. @see Algorithm::version
+    int RebinByTimeAtSample::version() const
+    {
+      return 1;
+    }
+    ;
+
+    /// Algorithm's category for identification. @see Algorithm::category
+    const std::string RebinByTimeAtSample::category() const
+    {
+      return "Transforms\\Rebin;Events\\EventFiltering";
+    }
+
+    /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
+    const std::string RebinByTimeAtSample::summary() const
+    {
+      return "Rebins with an x-axis of absolute time at sample for comparing event arrival time at the sample environment.";
+    }
+
+    const std::string RebinByTimeAtSample::name() const
+    {
+      return "RebinByTimeAtSample";
+    }
+
+    //----------------------------------------------------------------------------------------------
+    /** Initialize the algorithm's properties.
+     */
+    void RebinByTimeAtSample::init()
+    {
+      declareProperty(
+          new API::WorkspaceProperty<API::IEventWorkspace>("InputWorkspace", "", Direction::Input),
+          "An input workspace containing TOF events.");
+
+      declareProperty(new ArrayProperty<double>("Params", boost::make_shared<RebinParamsValidator>()),
+          "A comma separated list of first bin boundary, width, last bin boundary. Optionally\n"
+              "this can be followed by a comma and more widths and last boundary pairs. Values are in seconds since run start.");
+
+      declareProperty(
+          new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace", "", Direction::Output),
+          "An output workspace.");
+    }
+
+    //----------------------------------------------------------------------------------------------
+    /** Execute the algorithm.
+     */
+    void RebinByTimeAtSample::exec()
+    {
+      using Mantid::DataObjects::EventWorkspace;
+      IEventWorkspace_sptr inWS = getProperty("InputWorkspace");
+      if (!boost::dynamic_pointer_cast<EventWorkspace>(inWS))
+      {
+        throw std::invalid_argument("RebinByPulseTimes requires an EventWorkspace as an input.");
+      }
+
+      MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
+
+      // retrieve the properties
+      const std::vector<double> inParams = getProperty("Params");
+      std::vector<double> rebinningParams;
+
+      // workspace independent determination of length
+      const int histnumber = static_cast<int>(inWS->getNumberHistograms());
+
+      const uint64_t nanoSecondsInASecond = static_cast<uint64_t>(1e9);
+      const DateAndTime runStartTime = inWS->run().startTime();
+      // The validator only passes parameters with size 1, or 3xn.
+
+      double tStep = 0;
+      if (inParams.size() >= 3)
+      {
+        // Use the start of the run to offset the times provided by the user. pulse time of the events are absolute.
+        const DateAndTime startTime = runStartTime + inParams[0];
+        const DateAndTime endTime = runStartTime + inParams[2];
+        // Rebinning params in nanoseconds.
+        rebinningParams.push_back(static_cast<double>(startTime.totalNanoseconds()));
+        tStep = inParams[1] * nanoSecondsInASecond;
+        rebinningParams.push_back(tStep);
+        rebinningParams.push_back(static_cast<double>(endTime.totalNanoseconds()));
+      }
+      else if (inParams.size() == 1)
+      {
+        const uint64_t xmin = inWS->getTimeAtSampleMin().totalNanoseconds();
+        const uint64_t xmax = inWS->getTimeAtSampleMax().totalNanoseconds();
+
+        rebinningParams.push_back(static_cast<double>(xmin));
+        tStep = inParams[0] * nanoSecondsInASecond;
+        rebinningParams.push_back(tStep);
+        rebinningParams.push_back(static_cast<double>(xmax));
+      }
+
+      // Validate the timestep.
+      if (tStep <= 0)
+      {
+        throw std::invalid_argument("Cannot have a timestep less than or equal to zero.");
+      }
+
+      //Initialize progress reporting.
+      Progress prog(this, 0.0, 1.0, histnumber);
+
+      MantidVecPtr XValues_new;
+      // create new X axis, with absolute times in seconds.
+      const int ntcnew = VectorHelper::createAxisFromRebinParams(rebinningParams, XValues_new.access());
+
+      ConvertToRelativeTime transformToRelativeT(runStartTime);
+
+      // Transform the output into relative times in seconds.
+      MantidVec OutXValues_scaled(XValues_new->size());
+      std::transform(XValues_new->begin(), XValues_new->end(), OutXValues_scaled.begin(),
+          transformToRelativeT);
+
+      outputWS = WorkspaceFactory::Instance().create("Workspace2D", histnumber, ntcnew, ntcnew - 1);
+      WorkspaceFactory::Instance().initializeFromParent(inWS, outputWS, true);
+
+
+      const double tofOffset = 0;
+      auto instrument = inWS->getInstrument();
+      auto source = instrument->getSource();
+      auto sample = instrument->getSample();
+      const double L1 = source->getDistance(*sample);
+
+      //Go through all the histograms and set the data
+      PARALLEL_FOR2(inWS, outputWS)
+      for (int i = 0; i < histnumber; ++i)
+      {
+        PARALLEL_START_INTERUPT_REGION
+
+        const double L2 = inWS->getDetector(i)->getDistance(*sample);
+        const double tofFactor = L1 / (L1 + L2);
+
+        const IEventList* el = inWS->getEventListPtr(i);
+        MantidVec y_data, e_data;
+        // The EventList takes care of histogramming.
+        el->generateHistogramTimeAtSample(*XValues_new, y_data, e_data, tofFactor, tofOffset);
+
+        //Set the X axis for each output histogram
+        outputWS->setX(i, OutXValues_scaled);
+
+        //Copy the data over.
+        outputWS->dataY(i).assign(y_data.begin(), y_data.end());
+        outputWS->dataE(i).assign(e_data.begin(), e_data.end());
+
+        //Report progress
+        prog.report(name());
+      PARALLEL_END_INTERUPT_REGION
+    }
+    PARALLEL_CHECK_INTERUPT_REGION
+
+    //Copy all the axes
+    for (int i = 1; i < inWS->axes(); i++)
+    {
+      outputWS->replaceAxis(i, inWS->getAxis(i)->clone(outputWS.get()));
+      outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit();
+    }
+
+    // X-unit is relative time since the start of the run.
+    outputWS->getAxis(0)->unit() = boost::make_shared<Units::Time>();
+
+    //Copy the units over too.
+    for (int i = 1; i < outputWS->axes(); ++i)
+    {
+      outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit();
+    }
+    outputWS->setYUnit(inWS->YUnit());
+    outputWS->setYUnitLabel(inWS->YUnitLabel());
+
+    // Assign it to the output workspace property
+    setProperty("OutputWorkspace", outputWS);
+
+    return;
+  }
+
+} // namespace Algorithms
+} // namespace Mantid
diff --git a/Code/Mantid/Framework/Algorithms/test/RebinByPulseTimesTest.h b/Code/Mantid/Framework/Algorithms/test/RebinByPulseTimesTest.h
index 7466cdb84cddb05dab4e10368475214f13629166..631f86e7e5d644e36ba8326cbfe9ad2e25b186bc 100644
--- a/Code/Mantid/Framework/Algorithms/test/RebinByPulseTimesTest.h
+++ b/Code/Mantid/Framework/Algorithms/test/RebinByPulseTimesTest.h
@@ -17,6 +17,8 @@ using namespace Mantid::Kernel;
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 
+namespace
+{
 /**
 Helper method to create an event workspace with a set number of distributed events between pulseTimeMax and pulseTimeMin.
 */
@@ -60,6 +62,8 @@ public:
   MOCK_CONST_METHOD0(getTofMax, double());
   MOCK_CONST_METHOD0(getPulseTimeMin, DateAndTime());
   MOCK_CONST_METHOD0(getPulseTimeMax, DateAndTime());
+  MOCK_CONST_METHOD1(getTimeAtSampleMax, DateAndTime(double));
+    MOCK_CONST_METHOD1(getTimeAtSampleMin, DateAndTime(double));
   MOCK_CONST_METHOD0(getEventType, EventType());
   MOCK_METHOD1(getEventListPtr, IEventList*(const std::size_t));
   MOCK_CONST_METHOD5(generateHistogram, void(const std::size_t, const Mantid::MantidVec&,  Mantid::MantidVec&,  Mantid::MantidVec&, bool));
@@ -74,6 +78,7 @@ public:
   MOCK_CONST_METHOD0(getSpecialCoordinateSystem, Mantid::API::SpecialCoordinateSystem()); 
   virtual ~MockIEventWorkspace(){}
 };
+}
 
 //=====================================================================================
 // Functional Tests
diff --git a/Code/Mantid/Framework/Algorithms/test/RebinByTimeAtSampleTest.h b/Code/Mantid/Framework/Algorithms/test/RebinByTimeAtSampleTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8fae01986c9ff5c967c4bdc3810c38ec7cfd643
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/test/RebinByTimeAtSampleTest.h
@@ -0,0 +1,463 @@
+#ifndef MANTID_ALGORITHMS_REBINBYTIMEATSAMPLETEST_H_
+#define MANTID_ALGORITHMS_REBINBYTIMEATSAMPLETEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidKernel/DateAndTime.h"
+#include "MantidAlgorithms/RebinByTimeAtSample.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/Events.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include <boost/make_shared.hpp>
+#include <boost/assign/list_of.hpp>
+#include <gmock/gmock.h>
+
+using Mantid::Algorithms::RebinByTimeAtSample;
+using namespace Mantid::Kernel;
+using namespace Mantid::API;
+using namespace Mantid::DataObjects;
+
+namespace
+{
+/**
+Helper method to create an event workspace with a set number of distributed events between pulseTimeMax and pulseTimeMin.
+*/
+IEventWorkspace_sptr createEventWorkspace(const int numberspectra, const int nDistrubutedEvents, const int pulseTimeMinSecs, const int pulseTimeMaxSecs, const DateAndTime runStart=DateAndTime(int(1)))
+{
+  uint64_t pulseTimeMin = uint64_t(1e9) * pulseTimeMinSecs;
+  uint64_t pulseTimeMax = uint64_t(1e9) * pulseTimeMaxSecs;
+
+  EventWorkspace_sptr retVal(new EventWorkspace);
+  retVal->initialize(numberspectra,1,1);
+  double binWidth = std::abs(double(pulseTimeMax - pulseTimeMin)/nDistrubutedEvents);
+
+  //Make fake events
+  for (int pix=0; pix<numberspectra; pix++)
+  {
+    for (int i=0; i<nDistrubutedEvents; i++)
+    {
+      double tof = 0;
+      uint64_t pulseTime = uint64_t(((double)i+0.5)*binWidth); // Stick an event with a pulse_time in the middle of each pulse_time bin.
+      retVal->getEventList(pix) += TofEvent(tof, pulseTime);
+    }
+  }
+
+  // Add the required start time.
+  PropertyWithValue<std::string>* testProperty = new PropertyWithValue<std::string>("start_time", runStart.toSimpleString(), Direction::Input);
+  retVal->mutableRun().addLogData(testProperty);
+
+  V3D samplePosition(10,0,0);
+  V3D sourcePosition(0,0,0);
+  std::vector<V3D> detectorPositions(numberspectra, V3D(20, 0, 0));
+
+  WorkspaceCreationHelper::createInstrumentForWorkspaceWithDistances(retVal, samplePosition, sourcePosition, detectorPositions );
+
+  return retVal;
+}
+
+/*
+This type is an IEventWorkspace, but not an EventWorkspace.
+*/
+class MockIEventWorkspace : public Mantid::API::IEventWorkspace
+{
+public:
+  MOCK_CONST_METHOD0(getNumberEvents, std::size_t());
+  MOCK_CONST_METHOD0(getTofMin, double());
+  MOCK_CONST_METHOD0(getTofMax, double());
+  MOCK_CONST_METHOD0(getPulseTimeMin, DateAndTime());
+  MOCK_CONST_METHOD0(getPulseTimeMax, DateAndTime());
+  MOCK_CONST_METHOD1(getTimeAtSampleMax, DateAndTime(double));
+    MOCK_CONST_METHOD1(getTimeAtSampleMin, DateAndTime(double));
+  MOCK_CONST_METHOD0(getEventType, EventType());
+  MOCK_METHOD1(getEventListPtr, IEventList*(const std::size_t));
+  MOCK_CONST_METHOD5(generateHistogram, void(const std::size_t, const Mantid::MantidVec&,  Mantid::MantidVec&,  Mantid::MantidVec&, bool));
+  MOCK_METHOD0(clearMRU, void());
+  MOCK_CONST_METHOD0(clearMRU, void());
+  MOCK_CONST_METHOD0(blocksize, std::size_t());
+  MOCK_CONST_METHOD0(size, std::size_t());
+  MOCK_CONST_METHOD0(getNumberHistograms, std::size_t());
+  MOCK_METHOD1(getSpectrum, Mantid::API::ISpectrum*(const std::size_t));
+  MOCK_CONST_METHOD1(getSpectrum, const Mantid::API::ISpectrum*(const std::size_t));
+  MOCK_METHOD3(init, void(const size_t&, const size_t&, const size_t&));
+  MOCK_CONST_METHOD0(getSpecialCoordinateSystem, Mantid::API::SpecialCoordinateSystem());
+  virtual ~MockIEventWorkspace(){}
+};
+}
+//=====================================================================================
+// Functional Tests
+//=====================================================================================
+class RebinByTimeAtSampleTest : public CxxTest::TestSuite
+{
+
+private:
+
+  /**
+  Test execution method.
+
+  Sets up the algorithm for rebinning and executes it. Also verifies the results.
+  */
+  void do_execute_and_check_binning(const int nSpectra, const int pulseTimeMin, const int pulseTimeMax, const int nUniformDistributedEvents, const int nBinsToBinTo)
+  {
+    IEventWorkspace_sptr inWS = createEventWorkspace(nSpectra, nUniformDistributedEvents, pulseTimeMin, pulseTimeMax);
+
+    // Rebin pameters require the step.
+    const int step = (pulseTimeMax - pulseTimeMin)/(nBinsToBinTo);
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", inWS);
+    Mantid::MantidVec rebinArgs = boost::assign::list_of<double>(pulseTimeMin)(step)(pulseTimeMax); // Provide rebin arguments.
+    alg.setProperty("Params", rebinArgs);
+    alg.setPropertyValue("OutputWorkspace", "outWS");
+    alg.execute();
+
+
+    MatrixWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS<Workspace2D>("outWS");
+
+    // Check the units of the output workspace.
+    Unit_const_sptr expectedUnit(new Units::Time());
+    TSM_ASSERT_EQUALS("X unit should be Time/s", expectedUnit->unitID(), outWS->getAxis(0)->unit()->unitID());
+    for (int i=1; i < outWS->axes(); ++i)
+    {
+      TSM_ASSERT_EQUALS("Axis units do not match.", inWS->getAxis(i)->unit()->unitID(), outWS->getAxis(i)->unit()->unitID());
+    }
+
+    //Validate each spectra
+    for(int i = 0; i < nSpectra; ++i)
+    {
+      // Check that the x-axis has been set-up properly. It should mirror the original rebin parameters.
+      const Mantid::MantidVec& X = outWS->readX(i);
+      TS_ASSERT_EQUALS(nBinsToBinTo + 1, X.size());
+      for(uint64_t j = 0; j < X.size(); ++j)
+      {
+        TS_ASSERT_EQUALS(static_cast<int>(step*j), static_cast<int>(X[j]));
+      }
+
+      // Check that the y-axis has been set-up properly.
+
+      const Mantid::MantidVec& Y = outWS->readY(i);
+      TS_ASSERT_EQUALS(nBinsToBinTo, Y.size());
+      for(uint64_t j = 0; j < Y.size(); ++j)
+      {
+        TS_ASSERT_EQUALS(nUniformDistributedEvents/nBinsToBinTo, Y[j]); // Should have 1 event per bin, because that's what the createEventWorkspace() provides and our rebinning params are based on our original creation parameters.
+      }
+    }
+  }
+
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static RebinByTimeAtSampleTest *createSuite() { return new RebinByTimeAtSampleTest(); }
+  static void destroySuite( RebinByTimeAtSampleTest *suite ) { delete suite; }
+
+
+  void test_Init()
+  {
+    RebinByTimeAtSample alg;
+    TS_ASSERT_THROWS_NOTHING( alg.initialize() )
+    TS_ASSERT( alg.isInitialized() )
+  }
+
+  void test_not_a_event_workspace_throws()
+  {
+    IEventWorkspace_sptr ws(new MockIEventWorkspace);
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", ws);
+    Mantid::MantidVec rebinArgs = boost::assign::list_of<double>(1);
+    alg.setProperty("Params", rebinArgs);
+    alg.setPropertyValue("OutputWorkspace", "outWS");
+    TS_ASSERT_THROWS( alg.execute(), std::invalid_argument);
+  }
+
+  void do_test_bad_step_throws(const double& badStep)
+  {
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 4;
+    const int nUniformDistributedEvents = 4;
+    const int nSpectra = 1;
+
+    IEventWorkspace_sptr ws = createEventWorkspace(nSpectra, nUniformDistributedEvents, pulseTimeMin, pulseTimeMax); // Create an otherwise valid input workspace.
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", ws);
+    Mantid::MantidVec rebinArgs1 = boost::assign::list_of<double>(badStep);  // Step is zero!.
+    alg.setProperty("Params", rebinArgs1);
+    alg.setPropertyValue("OutputWorkspace", "outWS");
+    TS_ASSERT_THROWS( alg.execute(), std::invalid_argument);
+  }
+
+  void test_zero_step_throws()
+  {
+    do_test_bad_step_throws(0);
+  }
+
+  void test_less_than_zero_step_throws()
+  {
+    do_test_bad_step_throws(-1);
+  }
+
+  /*
+  Test that the input workspace must be an event workspace, other types of matrix workspace will not do.
+  */
+  void test_input_workspace2D_throws()
+  {
+    using Mantid::DataObjects::Workspace2D;
+    Workspace_sptr workspace2D = boost::make_shared<Workspace2D>();
+
+    RebinByTimeAtSample alg;
+    alg.initialize();
+    TS_ASSERT_THROWS(alg.setProperty("InputWorkspace", workspace2D), std::invalid_argument);
+  }
+
+    /**
+    Test setup description.
+
+    Bins set up with no offset and a spacing of 1e9 according to the rebin parameters.
+    The events in the workspace are created such that they sit in the middle of each bin. They are uniformly distributed from 0.5e9 to 19.5e9, so binning should occur as follows:
+
+      0      1e9   2e9   3e9   4e9   5e9 .... 20e9
+      |     |     |     |     |                 X array
+        ^      ^      ^     ^
+        |      |      |     |                   TOF pulse times
+        0.5e9  1.5e9  2.5e9 3.5e9 ... 19e9
+
+        so Y array should work out to be [1, 1, 1, ...] counts.
+    */
+  void test_execute_with_original_binning()
+  {
+    const int nSpectra = 1;
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 20;
+    const int nUninformDistributedEvents = 20;
+
+    const int numberOfBinsToBinTo = 20; // Gives the expected occupancy of each bin, given that the original setup is 1 event per bin.
+    do_execute_and_check_binning(nSpectra, pulseTimeMin, pulseTimeMax, nUninformDistributedEvents, numberOfBinsToBinTo);
+  }
+
+    /**
+    Test setup description.
+
+    Bins set up with no offset and a spacing of 2*e9 according to the rebin parameters.
+    The events in the workspace are created such that they sit in the middle of each bin. They are uniformly distributed from 0.5e9 to 19.5e9, so binning should occur as follows:
+
+      0          2e9            4e9   .... 20e9
+      |           |              |                 X array
+        ^      ^      ^     ^
+        |      |      |     |                      TOF pulse times
+        0.5e9  1.5e9  2.5e9 3.5e9 ... 19e9
+
+        so Y array should work out to be [2, 2, 2, ...] counts.
+    */
+  void test_execute_with_double_sized_bins_binning()
+  {
+    const int nSpectra = 1;
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 20;
+    const int nUninformDistributedEvents = 20;
+
+    const int numberOfBinsToBinTo = 10; // The bins are now twice as big!
+    do_execute_and_check_binning(nSpectra, pulseTimeMin, pulseTimeMax, nUninformDistributedEvents, numberOfBinsToBinTo);
+  }
+
+    /**
+    Test setup description.
+
+    Bins set up with no offset and a spacing of 4*e9 according to the rebin parameters.
+    The events in the workspace are created such that they sit in the middle of each bin. They are uniformly distributed from 0.5e9 to 19.5e9, so binning should occur as follows:
+
+      0                     4e9   .... 20e9
+      |                        |                 X array
+        ^      ^      ^     ^
+        |      |      |     |                      TOF pulse times
+        0.5e9  1.5e9  2.5e9 3.5e9 ... 19e9
+
+        so Y array should work out to be [4, 4, 4, ...] counts.
+    */
+  void test_execute_with_quadruple_sized_bins_binning()
+  {
+    const int nSpectra = 1;
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 20;
+    const int nUninformDistributedEvents = 20;
+    
+    const int numberOfBinsToBinTo = 5; // The bins are now four times as big.
+    do_execute_and_check_binning(nSpectra, pulseTimeMin, pulseTimeMax, nUninformDistributedEvents, numberOfBinsToBinTo);
+  }
+
+  void test_execute_with_multiple_spectra()
+  {
+    const int nSpectra = 10; // multipe spectra created in input workspace.
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 20;
+    const int nUninformDistributedEvents = 20;
+    
+    const int numberOfBinsToBinTo = 5;
+    do_execute_and_check_binning(nSpectra, pulseTimeMin, pulseTimeMax, nUninformDistributedEvents, numberOfBinsToBinTo);
+  }
+
+  void test_execute_with_xmin_larger_than_xmax_throws()
+  {
+    // Rebin pameters require the step.
+    const int step = 1;
+    const double pulseTimeMin = 10;
+    const double pulseTimeMax = 0;
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    Mantid::MantidVec rebinArgs = boost::assign::list_of<double>(pulseTimeMin)(step)(pulseTimeMax); // Provide rebin arguments.
+    TSM_ASSERT_THROWS("Shouldnt be able to have xmin > xmax", alg.setProperty("Params", rebinArgs), std::invalid_argument);
+  }
+
+  void test_calculate_xmin_xmax()
+  {
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 10;
+    const int nUniformDistributedEvents = 10;
+    const int nSpectra = 1;
+    const int nBinsToBinTo = 10;
+
+    IEventWorkspace_sptr ws = createEventWorkspace(nSpectra, nUniformDistributedEvents, pulseTimeMin, pulseTimeMax);
+
+    // Rebin pameters require the step.
+    const int step = static_cast<int>((pulseTimeMax - pulseTimeMin)/(nBinsToBinTo));
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", ws);
+    Mantid::MantidVec rebinArgs = boost::assign::list_of<double>(step); // Provide rebin arguments. Note we are only providing the step, xmin and xmax are calculated internally!
+    alg.setProperty("Params", rebinArgs);
+    alg.setPropertyValue("OutputWorkspace", "outWS");
+    alg.execute();
+
+    MatrixWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS<Workspace2D>("outWS");
+    const Mantid::MantidVec& X = outWS->readX(0);
+
+    // Check that xmin and xmax have been caclulated correctly.
+    TS_ASSERT_EQUALS(nBinsToBinTo, X.size());
+    // Added 1 nanosecond to start time
+    TS_ASSERT_EQUALS(pulseTimeMin + double(step)/2 - 1.e-9, X.front());
+    TS_ASSERT_EQUALS(pulseTimeMax - double(step)/2 - 1.e-9, X.back());
+  }
+
+
+  /*
+    Test setup description.
+    
+    Bins set up with 1e9 offset according to the rebin parameters.
+    But the events in the workspace are created without the offset, they have uniformly distributed pulse times from 0.5e9 to 3.5e9, so binning should occur as follows:
+
+            1e9   2e9   3e9   4e9   5e9
+            |     |     |     |     |         X array
+        ^      ^      ^     ^
+        |      |      |     |           TOF pulse times
+        0.5e9  1.5e9  2.5e9 3.5e9
+
+        so Y array should work out to be [1, 1, 1, 0] counts.
+    */
+  void test_calculate_non_zero_offset()
+  {
+    const int pulseTimeMin = 0;
+    const int pulseTimeMax = 4;
+    const int nUniformDistributedEvents = 4;
+    const int nSpectra = 1;
+    const int nBinsToBinTo = 4;
+    DateAndTime offSet(size_t(1e9)); // Offset (start_time).
+
+    IEventWorkspace_sptr ws = createEventWorkspace(nSpectra, nUniformDistributedEvents, pulseTimeMin, pulseTimeMax, offSet);
+
+    // Rebin pameters require the step.
+    const int step = static_cast<int>((pulseTimeMax - pulseTimeMin)/(nBinsToBinTo));
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", ws);
+    Mantid::MantidVec rebinArgs = boost::assign::list_of<double>(pulseTimeMin)(step)(pulseTimeMax); // Provide rebin arguments.
+    alg.setProperty("Params", rebinArgs);
+    alg.setPropertyValue("OutputWorkspace", "outWS");
+    alg.execute();
+
+    MatrixWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS<Workspace2D>("outWS");
+    const Mantid::MantidVec& X = outWS->readX(0);
+
+    // Check that xmin and xmax have been caclulated correctly.
+    TS_ASSERT_EQUALS(nBinsToBinTo + 1, X.size());
+    TS_ASSERT_EQUALS(pulseTimeMin, X.front());
+    TS_ASSERT_EQUALS(pulseTimeMax, X.back());
+
+    const Mantid::MantidVec& Y = outWS->readY(0);
+    TS_ASSERT_EQUALS(nBinsToBinTo, Y.size());
+
+    TS_ASSERT_EQUALS(nUniformDistributedEvents/nBinsToBinTo, Y[0]);
+    TS_ASSERT_EQUALS(nUniformDistributedEvents/nBinsToBinTo, Y[1]);
+    TS_ASSERT_EQUALS(nUniformDistributedEvents/nBinsToBinTo, Y[2]);
+    TS_ASSERT_EQUALS(0, Y[3]);
+
+  }
+};
+
+//=====================================================================================
+// Performance Tests
+//=====================================================================================
+class RebinByTimeAtSampleTestPerformance : public CxxTest::TestSuite
+{
+private:
+
+  IEventWorkspace_sptr m_ws;
+  const int pulseTimeMin;
+  const int pulseTimeMax;
+  const int nUniformDistributedEvents;
+  const int nSpectra;
+  const int nBinsToBinTo;
+
+public:
+  static RebinByTimeAtSampleTestPerformance *createSuite() { return new RebinByTimeAtSampleTestPerformance(); }
+  static void destroySuite( RebinByTimeAtSampleTestPerformance *suite ) { delete suite; }
+
+  RebinByTimeAtSampleTestPerformance() :
+    pulseTimeMin(0),
+    pulseTimeMax(4),
+    nUniformDistributedEvents(10000),
+    nSpectra(1000),
+    nBinsToBinTo(100)
+  {
+  }
+
+  void setUp()
+  {
+    // Make a reasonably sized workspace to rebin.
+    m_ws = createEventWorkspace(nSpectra, nUniformDistributedEvents, pulseTimeMin, pulseTimeMax);
+  }
+
+  void testExecution()
+  {
+    const double dPulseTimeMax = pulseTimeMax;
+    const double dPulseTimeMin = pulseTimeMin;
+    const double step = (dPulseTimeMax - dPulseTimeMin)/(nBinsToBinTo);
+
+    RebinByTimeAtSample alg;
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", m_ws);
+    Mantid::MantidVec rebinArgs = boost::assign::list_of<double>(dPulseTimeMin)(step)(dPulseTimeMax); // Provide rebin arguments.
+    alg.setProperty("Params", rebinArgs);
+    alg.setPropertyValue("OutputWorkspace", "outWS");
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+
+    // Simple tests. Functionality tests cover this much better.
+    MatrixWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS<Workspace2D>("outWS");
+    TS_ASSERT(outWS != NULL);
+  }
+};
+
+
+#endif /* MANTID_ALGORITHMS_REBINBYTIMEATSAMPLETEST_H_ */
diff --git a/Code/Mantid/docs/source/algorithms/RebinByTimeAtSample-v1.rst b/Code/Mantid/docs/source/algorithms/RebinByTimeAtSample-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4eec4397fc53746055218d110853f4d1f5dd1375
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/RebinByTimeAtSample-v1.rst
@@ -0,0 +1,44 @@
+
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+TODO: Enter a full rst-markup description of your algorithm here. 
+
+
+Usage
+-----
+..  Try not to use files in your examples, 
+    but if you cannot avoid it then the (small) files must be added to 
+    autotestdata\UsageData and the following tag unindented
+    .. include:: ../usagedata-note.txt
+
+**Example - RebinByTimeAtSample**
+
+.. testcode:: RebinByTimeAtSampleExample
+
+   # Create a host workspace
+   ws = CreateWorkspace(DataX=range(0,3), DataY=(0,2))
+   or
+   ws = CreateSampleWorkspace()
+
+   wsOut = RebinByTimeAtSample()
+
+   # Print the result
+   print "The output workspace has %i spectra" % wsOut.getNumberHistograms()
+
+Output:
+
+.. testoutput:: RebinByTimeAtSampleExample 
+
+  The output workspace has ?? spectra
+
+.. categories::
+