diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
index 9377027226e6eeb8ce4a2879b76a77dd72a66904..3fb7b0b087b41bd8f0f7ad1f52f261f34f946adf 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
@@ -414,7 +414,7 @@ public:
   /// to point-like)
   virtual bool isHistogramData() const;
 
-  /// Returns true if the workspace contains has common X bins
+  /// Returns true if the workspace contains common X bins
   virtual bool isCommonBins() const;
 
   std::string YUnit() const;
diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt
index 6514e828c709ee4ed3f41a3a853f1362a53525d9..d513840a134f95c5ba095507bba5e1b684539c14 100644
--- a/Framework/Algorithms/CMakeLists.txt
+++ b/Framework/Algorithms/CMakeLists.txt
@@ -182,6 +182,7 @@ set ( SRC_FILES
 	src/MaskBinsIf.cpp
 	src/MaskDetectorsIf.cpp
 	src/MaskInstrument.cpp
+	src/MaskNonOverlappingBins.cpp
 	src/MatrixWorkspaceAccess.cpp
 	src/Max.cpp
 	src/MaxEnt.cpp
@@ -517,6 +518,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/MaskBinsIf.h
 	inc/MantidAlgorithms/MaskDetectorsIf.h
 	inc/MantidAlgorithms/MaskInstrument.h
+	inc/MantidAlgorithms/MaskNonOverlappingBins.h
 	inc/MantidAlgorithms/MatrixWorkspaceAccess.h
 	inc/MantidAlgorithms/Max.h
 	inc/MantidAlgorithms/MaxEnt.h
@@ -862,6 +864,7 @@ set ( TEST_FILES
 	MaskBinsTest.h
 	MaskDetectorsIfTest.h
 	MaskInstrumentTest.h
+	MaskNonOverlappingBinsTest.h
 	MaxEnt/MaxentCalculatorTest.h
 	MaxEnt/MaxentEntropyNegativeValuesTest.h
 	MaxEnt/MaxentEntropyPositiveValuesTest.h
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h
index 0fac7baa6c67c836c169310ce588ebd682c714c8..67ad013469b1b174c24e474a5791dfbb54bdd414 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h
@@ -50,7 +50,7 @@ public:
   /// Algorithm's version
   int version() const override { return (1); }
   const std::vector<std::string> seeAlso() const override {
-    return {"MaskBinsFromTable"};
+    return {"MaskBinsIf, MaskBinsFromTable, MaskNonOverlappingBins"};
   }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Masking"; }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskNonOverlappingBins.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskNonOverlappingBins.h
new file mode 100644
index 0000000000000000000000000000000000000000..f53383a50d4011a90aba82974cd5a82c688ccb8e
--- /dev/null
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskNonOverlappingBins.h
@@ -0,0 +1,46 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_ALGORITHMS_MASKNONOVERLAPPINGBINS_H_
+#define MANTID_ALGORITHMS_MASKNONOVERLAPPINGBINS_H_
+
+#include "MantidAPI/Algorithm.h"
+#include "MantidAlgorithms/DllConfig.h"
+
+namespace Mantid {
+namespace Algorithms {
+
+/** MaskNonOverlappingBins : Compares the X ranges of two workspace and
+ * masks the non-overlapping bins in the first workspace.
+ */
+class MANTID_ALGORITHMS_DLL MaskNonOverlappingBins : public API::Algorithm {
+public:
+  std::string const name() const override;
+  int version() const override;
+  std::string const category() const override;
+  std::string const summary() const override;
+  std::vector<std::string> const seeAlso() const override;
+
+private:
+  void init() override;
+  void exec() override;
+  std::map<std::string, std::string> validateInputs() override;
+  void checkXSorting(API::MatrixWorkspace const &inputWS,
+                     API::MatrixWorkspace const &comparisonWS);
+  bool isCommonBins(API::MatrixWorkspace const &inputWS,
+                    API::MatrixWorkspace const &comparisonWS);
+  void processRagged(API::MatrixWorkspace const &inputWS,
+                     API::MatrixWorkspace const &comparisonWS,
+                     API::MatrixWorkspace &outputWS);
+  void processNonRagged(API::MatrixWorkspace const &inputWS,
+                        API::MatrixWorkspace const &comparisonWS,
+                        API::MatrixWorkspace &outputWS);
+};
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif /* MANTID_ALGORITHMS_MASKNONOVERLAPPINGBINS_H_ */
diff --git a/Framework/Algorithms/src/MaskNonOverlappingBins.cpp b/Framework/Algorithms/src/MaskNonOverlappingBins.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d16050832f195ee10aff7c525054974f9249dbf1
--- /dev/null
+++ b/Framework/Algorithms/src/MaskNonOverlappingBins.cpp
@@ -0,0 +1,256 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#include "MantidAlgorithms/MaskNonOverlappingBins.h"
+
+#include "MantidAPI/Axis.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidKernel/ListValidator.h"
+#include "MantidKernel/MultiThreaded.h"
+#include "MantidKernel/Unit.h"
+
+namespace {
+/// Constants for the algorithm's property names.
+namespace Prop {
+std::string const CHECK_SORTING{"CheckSortedX"};
+std::string const COMPARISON_WS{"ComparisonWorkspace"};
+std::string const INPUT_WS{"InputWorkspace"};
+std::string const MASK_PARTIAL{"MaskPartiallyOverlapping"};
+std::string const OUTPUT_WS{"OutputWorkspace"};
+std::string const RAGGEDNESS{"RaggedInputs"};
+} // namespace Prop
+/// Constants for the RaggedInputs property.
+namespace Raggedness {
+std::string const CHECK{"Check"};
+std::string const RAGGED{"Ragged"};
+std::string const NONRAGGED{"Common Bins"};
+} // namespace Raggedness
+
+/// Return true if X data is sorted in ascending order.
+bool isXSorted(Mantid::API::MatrixWorkspace const &ws) {
+  int unsorted{0};
+  PARALLEL_FOR_IF(Mantid::Kernel::threadSafe(ws))
+  for (int64_t i = 0; static_cast<size_t>(i) < ws.getNumberHistograms(); ++i) {
+    auto const &Xs = ws.x(static_cast<size_t>(i));
+    if (!std::is_sorted(Xs.cbegin(), Xs.cend())) {
+      PARALLEL_ATOMIC
+      ++unsorted;
+    }
+  }
+  return unsorted == 0;
+}
+
+/// Holds limiting bin indices for masking
+struct BinIndices {
+  size_t frontEndIndex;  ///< Mask from 0 to this index.
+  size_t backBeginIndex; ///< Mask from this index to size.
+};
+
+/// Return the proper masking limits for non-overlapping bins.
+BinIndices maskingLimits(Mantid::API::MatrixWorkspace const &ws,
+                         Mantid::API::MatrixWorkspace const &comparisonWS,
+                         bool const maskPartial, size_t const histogramIndex) {
+  auto const &Xs = ws.x(histogramIndex);
+  auto const &comparisonXs = comparisonWS.x(histogramIndex);
+  // At the moment we only support increasing X.
+  auto const startX = comparisonXs.front();
+  auto const endX = comparisonXs.back();
+  // There is no Y corresponding to the last bin edge,
+  // therefore iterate only to cend() - 1.
+  auto frontEnd = std::lower_bound(Xs.cbegin(), Xs.cend() - 1, startX);
+  if (!maskPartial && frontEnd != Xs.cbegin() && *frontEnd != startX) {
+    --frontEnd;
+  }
+  auto backBegin = std::lower_bound(frontEnd, Xs.cend() - 1, endX);
+  if (maskPartial && backBegin != Xs.cbegin() && *backBegin > endX) {
+    --backBegin;
+  }
+  BinIndices limits;
+  limits.frontEndIndex =
+      static_cast<size_t>(std::distance(Xs.cbegin(), frontEnd));
+  limits.backBeginIndex =
+      static_cast<size_t>(std::distance(Xs.cbegin(), backBegin));
+  return limits;
+}
+
+/// Mask the start and end of histogram at histogram index.
+void maskBinsWithinLimits(Mantid::API::MatrixWorkspace &ws,
+                          size_t const histogramIndex,
+                          BinIndices const &limits) {
+  auto const xSize = ws.x(histogramIndex).size();
+  for (size_t binIndex = 0; binIndex < limits.frontEndIndex; ++binIndex) {
+    ws.flagMasked(histogramIndex, binIndex);
+  }
+  for (size_t binIndex = limits.backBeginIndex; binIndex < xSize - 1;
+       ++binIndex) {
+    ws.flagMasked(histogramIndex, binIndex);
+  }
+}
+} // namespace
+
+namespace Mantid {
+namespace Algorithms {
+DECLARE_ALGORITHM(MaskNonOverlappingBins)
+
+/// Algorithms name for identification. @see Algorithm::name
+std::string const MaskNonOverlappingBins::name() const {
+  return "MaskNonOverlappingBins";
+}
+
+/// Algorithm's version for identification. @see Algorithm::version
+int MaskNonOverlappingBins::version() const { return 1; }
+
+/// Algorithm's category for identification. @see Algorithm::category
+std::string const MaskNonOverlappingBins::category() const {
+  return "Transforms\\Masking";
+}
+
+/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
+std::string const MaskNonOverlappingBins::summary() const {
+  return "Marks bins in InputWorkspace which are out of the X range of the "
+         "second workspace.";
+}
+
+/// Return a list of the names of related algorithms.
+std::vector<std::string> const MaskNonOverlappingBins::seeAlso() const {
+  return {"MaskBins", "MaskBinsIf"};
+}
+
+/** Initialize the algorithm's properties.
+ */
+void MaskNonOverlappingBins::init() {
+  declareProperty(Kernel::make_unique<API::WorkspaceProperty<>>(
+                      Prop::INPUT_WS, "", Kernel::Direction::Input),
+                  "A workspace to mask.");
+  declareProperty(Kernel::make_unique<API::WorkspaceProperty<>>(
+                      Prop::OUTPUT_WS, "", Kernel::Direction::Output),
+                  "The masked workspace.");
+  declareProperty(Kernel::make_unique<API::WorkspaceProperty<>>(
+                      Prop::COMPARISON_WS, "", Kernel::Direction::Input),
+                  "A workspace to compare the InputWorkspace's binning to.");
+  declareProperty(Prop::MASK_PARTIAL, false,
+                  "If true, mask also bins that overlap only partially.");
+  std::vector<std::string> const options{Raggedness::CHECK, Raggedness::RAGGED,
+                                         Raggedness::NONRAGGED};
+  auto raggednessOptions =
+      boost::make_shared<Kernel::ListValidator<std::string>>(options);
+  declareProperty(Prop::RAGGEDNESS, Raggedness::CHECK, raggednessOptions,
+                  "Choose whether the input workspaces have common bins, are "
+                  "ragged, or if the algorithm should check.");
+  declareProperty(
+      Prop::CHECK_SORTING, true,
+      "If true, the algorithm ensures that both workspaces have X sorted in "
+      "ascending order.");
+}
+
+/// Returns a map from property name to message in case of invalid values.
+std::map<std::string, std::string> MaskNonOverlappingBins::validateInputs() {
+  std::map<std::string, std::string> issues;
+  API::MatrixWorkspace_const_sptr inputWS = getProperty(Prop::INPUT_WS);
+  API::MatrixWorkspace_const_sptr comparisonWS =
+      getProperty(Prop::COMPARISON_WS);
+  if (inputWS->getNumberHistograms() != comparisonWS->getNumberHistograms()) {
+    issues[Prop::COMPARISON_WS] =
+        "The number of histogams mismatches with " + Prop::INPUT_WS;
+  }
+  if (!inputWS->isHistogramData()) {
+    issues[Prop::INPUT_WS] =
+        "The workspace contains point data, not histograms.";
+  }
+  if (!comparisonWS->isHistogramData()) {
+    issues[Prop::COMPARISON_WS] =
+        "The workspace contains point data, not histograms.";
+  }
+  auto const inputAxis = inputWS->getAxis(0);
+  auto const comparisonAxis = comparisonWS->getAxis(0);
+  if (inputAxis && comparisonAxis) {
+    if (*(inputAxis->unit()) != *(comparisonAxis->unit())) {
+      issues[Prop::COMPARISON_WS] =
+          "X units do not match with " + Prop::INPUT_WS;
+    }
+  }
+  return issues;
+}
+
+/** Execute the algorithm.
+ */
+void MaskNonOverlappingBins::exec() {
+  API::MatrixWorkspace_sptr inputWS = getProperty(Prop::INPUT_WS);
+  API::MatrixWorkspace_sptr outputWS = getProperty(Prop::OUTPUT_WS);
+  if (inputWS != outputWS) {
+    outputWS = inputWS->clone();
+  }
+  API::MatrixWorkspace_const_sptr comparisonWS =
+      getProperty(Prop::COMPARISON_WS);
+  checkXSorting(*inputWS, *comparisonWS);
+  if (isCommonBins(*inputWS, *comparisonWS)) {
+    processNonRagged(*inputWS, *comparisonWS, *outputWS);
+  } else {
+    processRagged(*inputWS, *comparisonWS, *outputWS);
+  }
+  setProperty(Prop::OUTPUT_WS, outputWS);
+}
+
+/// Throw if the workspaces don't have sorted X.
+void MaskNonOverlappingBins::checkXSorting(
+    API::MatrixWorkspace const &inputWS,
+    API::MatrixWorkspace const &comparisonWS) {
+  bool const checkSorting = getProperty(Prop::CHECK_SORTING);
+  if (checkSorting) {
+    if (!isXSorted(inputWS)) {
+      throw std::invalid_argument(Prop::INPUT_WS + " has unsorted X.");
+    }
+    if (!isXSorted(comparisonWS)) {
+      throw std::invalid_argument(Prop::COMPARISON_WS + " has unsorted X.");
+    }
+  }
+}
+
+/// Return true if the workspaces should be considered as having common bins.
+bool MaskNonOverlappingBins::isCommonBins(
+    API::MatrixWorkspace const &inputWS,
+    API::MatrixWorkspace const &comparisonWS) {
+  std::string const choice = getProperty(Prop::RAGGEDNESS);
+  if (choice == Raggedness::CHECK) {
+    return inputWS.isCommonBins() && comparisonWS.isCommonBins();
+  } else {
+    return choice == Raggedness::NONRAGGED;
+  }
+}
+
+/// Mask all types of workspaces, ragged or nonragged.
+void MaskNonOverlappingBins::processRagged(
+    API::MatrixWorkspace const &inputWS,
+    API::MatrixWorkspace const &comparisonWS, API::MatrixWorkspace &outputWS) {
+  bool const maskPartial = getProperty(Prop::MASK_PARTIAL);
+  auto const nHist = inputWS.getNumberHistograms();
+  API::Progress progress(this, 0., 1., nHist);
+  // Tried to parallelize this loop but the performance test showed
+  // regression. Hence no PARALLEL_FOR_IF.
+  for (size_t histogramIndex = 0; histogramIndex < nHist; ++histogramIndex) {
+    auto const limits =
+        maskingLimits(inputWS, comparisonWS, maskPartial, histogramIndex);
+    maskBinsWithinLimits(outputWS, histogramIndex, limits);
+    progress.report("Masking nonoverlapping bins");
+  }
+}
+
+/// Mask only workspace with same X in all histograms.
+void MaskNonOverlappingBins::processNonRagged(
+    API::MatrixWorkspace const &inputWS,
+    API::MatrixWorkspace const &comparisonWS, API::MatrixWorkspace &outputWS) {
+  bool const maskPartial = getProperty(Prop::MASK_PARTIAL);
+  auto const nHist = inputWS.getNumberHistograms();
+  API::Progress progress(this, 0., 1., nHist);
+  auto const limits = maskingLimits(inputWS, comparisonWS, maskPartial, 0);
+  for (size_t histogramIndex = 0; histogramIndex < nHist; ++histogramIndex) {
+    maskBinsWithinLimits(outputWS, histogramIndex, limits);
+    progress.report("Masking nonoverlapping bins");
+  }
+}
+
+} // namespace Algorithms
+} // namespace Mantid
diff --git a/Framework/Algorithms/test/MaskNonOverlappingBinsTest.h b/Framework/Algorithms/test/MaskNonOverlappingBinsTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed8ec214c3cf6dea099d3b2220eaafc992522fee
--- /dev/null
+++ b/Framework/Algorithms/test/MaskNonOverlappingBinsTest.h
@@ -0,0 +1,208 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_ALGORITHMS_MaskNonOverlappingBinsTEST_H_
+#define MANTID_ALGORITHMS_MaskNonOverlappingBinsTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/MaskNonOverlappingBins.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidDataObjects/WorkspaceCreation.h"
+#include "MantidHistogramData/BinEdges.h"
+#include "MantidHistogramData/Counts.h"
+#include "MantidHistogramData/LinearGenerator.h"
+
+#include <array>
+
+using namespace Mantid;
+
+class MaskNonOverlappingBinsTest : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static MaskNonOverlappingBinsTest *createSuite() {
+    return new MaskNonOverlappingBinsTest();
+  }
+  static void destroySuite(MaskNonOverlappingBinsTest *suite) { delete suite; }
+
+  void test_init() {
+    Algorithms::MaskNonOverlappingBins alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+  }
+
+  void test_maskBegin() {
+    HistogramData::BinEdges comparison{-1.1, -0.1};
+    auto const expected = API::MatrixWorkspace::MaskList{{1, 1.}, {2, 1.}};
+    runTestWithAlwaysSameExpectedOutcome(std::move(comparison), expected);
+  }
+
+  void test_maskCentre() {
+    HistogramData::BinEdges comparison{-0.1, 0.9};
+    auto const expected = API::MatrixWorkspace::MaskList{{0, 1.}, {2, 1.}};
+    runTestWithAlwaysSameExpectedOutcome(std::move(comparison), expected);
+  }
+
+  void test_maskEnd() {
+    HistogramData::BinEdges comparison{0.9, 1.8};
+    auto const expected = API::MatrixWorkspace::MaskList{{0, 1.}, {1, 1.}};
+    runTestWithAlwaysSameExpectedOutcome(std::move(comparison), expected);
+  }
+
+  void test_maskAll() {
+    HistogramData::BinEdges comparison{-13., -1.1};
+    auto const expected =
+        API::MatrixWorkspace::MaskList{{0, 1.}, {1, 1.}, {2, 1.}};
+    runTestWithAlwaysSameExpectedOutcome(std::move(comparison), expected);
+    comparison = {1.8, 13.};
+    runTestWithAlwaysSameExpectedOutcome(std::move(comparison), expected);
+  }
+
+  void test_partialOverlapMasking() {
+    HistogramData::BinEdges const comparison{0., 0.1};
+    auto expected = API::MatrixWorkspace::MaskList{{0, 1.}, {1, 1.}, {2, 1.}};
+    runTestWithMatchingBins(comparison, expected, true);
+    expected = {{0, 1.}, {2, 1.}};
+    runTestWithMatchingBins(comparison, expected, false);
+  }
+
+  void test_maskNone() {
+    HistogramData::BinEdges const comparison{-13., 13.};
+    auto const expected = API::MatrixWorkspace::MaskList();
+    runTestWithAlwaysSameExpectedOutcome(comparison, expected);
+  }
+
+  void test_unsortedXThrows() {
+    API::MatrixWorkspace_sptr inputWS =
+        makeWorkspace(HistogramData::BinEdges{-1.1, -0.1, 0.2, 1.8});
+    inputWS->mutableX(0)[2] = -0.9;
+    API::MatrixWorkspace_sptr comparisonWS =
+        makeWorkspace(HistogramData::BinEdges{-1.1, 1.8});
+    Algorithms::MaskNonOverlappingBins alg;
+    alg.setChild(true);
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inputWS))
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", "_unused_for_child"))
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setProperty("ComparisonWorkspace", comparisonWS))
+    TS_ASSERT_THROWS_EQUALS(alg.execute(), std::invalid_argument const &e,
+                            e.what(),
+                            std::string("InputWorkspace has unsorted X."))
+    TS_ASSERT(!alg.isExecuted())
+  }
+
+private:
+  template <typename BinEdges>
+  static API::MatrixWorkspace_sptr makeWorkspace(BinEdges &&binEdges) {
+    HistogramData::BinEdges edges(std::forward<BinEdges>(binEdges));
+    HistogramData::Counts counts(edges.size() - 1, 2);
+    return DataObjects::create<DataObjects::Workspace2D>(
+        1, HistogramData::Histogram(edges, counts));
+  }
+
+  static void runTestWithAlwaysSameExpectedOutcome(
+      HistogramData::BinEdges comparisonBinEdges,
+      API::MatrixWorkspace::MaskList const &expected) {
+    runTestWithMatchingBins(comparisonBinEdges, expected, true);
+    runTestWithMatchingBins(std::move(comparisonBinEdges), expected, false);
+  }
+
+  template <typename BinEdges>
+  static void
+  runTestWithMatchingBins(BinEdges &&comparisonBinEdges,
+                          API::MatrixWorkspace::MaskList const &expected,
+                          bool const maskPartial) {
+    API::MatrixWorkspace_sptr inputWS =
+        makeWorkspace(HistogramData::BinEdges{-1.1, -0.1, 0.9, 1.8});
+    API::MatrixWorkspace_sptr comparisonWS =
+        makeWorkspace(std::forward<BinEdges>(comparisonBinEdges));
+    std::array<std::string, 3> raggedOptions{
+        {"Check", "Ragged", "Common Bins"}};
+    for (auto const &raggedness : raggedOptions) {
+      Algorithms::MaskNonOverlappingBins alg;
+      alg.setChild(true);
+      alg.setRethrows(true);
+      TS_ASSERT_THROWS_NOTHING(alg.initialize())
+      TS_ASSERT(alg.isInitialized())
+      TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inputWS))
+      TS_ASSERT_THROWS_NOTHING(
+          alg.setPropertyValue("OutputWorkspace", "_unused_for_child"))
+      TS_ASSERT_THROWS_NOTHING(
+          alg.setProperty("ComparisonWorkspace", comparisonWS))
+      TS_ASSERT_THROWS_NOTHING(
+          alg.setProperty("MaskPartiallyOverlapping", maskPartial))
+      TS_ASSERT_THROWS_NOTHING(alg.setProperty("RaggedInputs", raggedness))
+      TS_ASSERT_THROWS_NOTHING(alg.execute())
+      TS_ASSERT(alg.isExecuted())
+      API::MatrixWorkspace_sptr outputWS = alg.getProperty("OutputWorkspace");
+      TS_ASSERT(outputWS);
+      TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1)
+      if (!expected.empty()) {
+        auto const mask = outputWS->maskedBins(0);
+        TS_ASSERT_EQUALS(mask, expected)
+      } else {
+        TS_ASSERT(!outputWS->hasMaskedBins(0))
+      }
+    }
+  }
+};
+
+class MaskNonOverlappingBinsTestPerformance : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static MaskNonOverlappingBinsTestPerformance *createSuite() {
+    return new MaskNonOverlappingBinsTestPerformance();
+  }
+  static void destroySuite(MaskNonOverlappingBinsTestPerformance *suite) {
+    delete suite;
+  }
+
+  void setUp() override {
+    HistogramData::BinEdges edges(1000,
+                                  HistogramData::LinearGenerator(-100., 23.));
+    HistogramData::Counts counts(edges.size() - 1, 2);
+    m_ws = DataObjects::create<DataObjects::Workspace2D>(
+        10000, HistogramData::Histogram(edges, counts));
+    edges =
+        HistogramData::BinEdges(200, HistogramData::LinearGenerator(-10., 2.3));
+    counts = HistogramData::Counts(edges.size() - 1, 2);
+    m_compWS = DataObjects::create<DataObjects::Workspace2D>(
+        10000, HistogramData::Histogram(edges, counts));
+    m_alg.initialize();
+    m_alg.setChild(true);
+    m_alg.setRethrows(true);
+    m_alg.setProperty("InputWorkspace", m_ws);
+    m_alg.setPropertyValue("OutputWorkspace", "_unused_for_child");
+    m_alg.setProperty("ComparisonWorkspace", m_compWS);
+    m_alg.setProperty("MaskPartiallyOverlapping", true);
+  }
+
+  void test_default() { TS_ASSERT_THROWS_NOTHING(m_alg.execute()) }
+
+  void test_nonragged() {
+    m_alg.setProperty("CheckSortedX", false);
+    m_alg.setProperty("RaggedInputs", "Common Bins");
+    TS_ASSERT_THROWS_NOTHING(m_alg.execute())
+  }
+
+  void test_ragged() {
+    m_alg.setProperty("CheckSortedX", false);
+    m_alg.setProperty("RaggedInputs", "Ragged");
+    TS_ASSERT_THROWS_NOTHING(m_alg.execute())
+  }
+
+private:
+  API::MatrixWorkspace_sptr m_ws;
+  API::MatrixWorkspace_sptr m_compWS;
+  Algorithms::MaskNonOverlappingBins m_alg;
+};
+
+#endif /* MANTID_ALGORITHMS_MaskNonOverlappingBinsTEST_H_ */
diff --git a/docs/source/algorithms/MaskNonOverlappingBins-v1.rst b/docs/source/algorithms/MaskNonOverlappingBins-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..28337edfd11d6627558e95988975aad18fb0c26d
--- /dev/null
+++ b/docs/source/algorithms/MaskNonOverlappingBins-v1.rst
@@ -0,0 +1,48 @@
+
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm masks the bins in ``InputWorkspace`` which lie in :math:`X` range that is not covered by ``ComparisonWorkspace``. The ``MaskPartiallyOverlapping`` flag affect the behavior with regards to bins which are partially covered by ``ComparisonWorkspace``. The algorithm works only with the X data sorted in ascending order.
+
+The algorithm currently applies the default masking weight to the bins which does not clear the data.
+
+Optimizations
+#############
+
+Some small optimizations are possible via ``CheckSortedX`` and ``RaggedInputs``. Make sure the input workspaces fill the expectations before using these properties!
+
+- If there is no doubt that X data in ``InputWorkspace`` and ``ComparisonWorkspace`` is sorted, the checking for ascending X can be skipped by setting ``CheckSortedX`` to ``False``.
+- If ``RaggedInputs`` is set to ``'Check'`` (the default), the algorithm will check if both ``InputWorkspace`` and ``ComparisonWorkspace`` are :ref:`ragged workspaces <Ragged_Workspace>` and choose the processing method accordingly. The test can be skipped by setting ``RaggedInputs`` to ``'Ragged'`` or ``'Common Bins'`` which forces a specific processing method.
+
+Usage
+-----
+
+**Example - MaskNonOverlappingBins**
+
+.. testcode:: MaskNonOverlappingBinsExample
+
+   bigWS = CreateSampleWorkspace(XMin=0, XMax=20000)
+   smallWS = CreateSampleWorkspace(XMin=9000, XMax=11000)
+   masked = MaskNonOverlappingBins(bigWS, smallWS)
+   print('It is not (yet) possible to access the bin masking information in Python.')
+   print('Please check that the correct bins are grayed out in the data view.')
+
+Output:
+
+.. testoutput:: MaskNonOverlappingBinsExample
+
+   It is not (yet) possible to access the bin masking information in Python.
+   Please check that the correct bins are grayed out in the data view.
+
+.. categories::
+
+.. sourcelink::
+
diff --git a/docs/source/release/v3.14.0/framework.rst b/docs/source/release/v3.14.0/framework.rst
index 31971ef23f9b1ddc24980dba41f1b95425e1038b..be679ff13a52f091ce2e44d8210e656c564fb51c 100644
--- a/docs/source/release/v3.14.0/framework.rst
+++ b/docs/source/release/v3.14.0/framework.rst
@@ -42,6 +42,7 @@ New Algorithms
 - :ref:`CalculateDynamicRange <algm-CalculateDynamicRange>` will calculate the Q range of a SANS workspace.
 - :ref:`MatchSpectra <algm-MatchSpectra>` is an algorithm that calculates factors to match all spectra to a reference spectrum.
 - :ref:`MaskBinsIf <algm-MaskBinsIf>` is an algorithm to mask bins according to criteria specified as a muparser expression.
+- :ref:`MaskNonOverlappingBins <algm-MaskNonOverlappingBins>` masks the bins that do not overlap with another workspace.
 
 Improvements
 ############