diff --git a/Framework/MDAlgorithms/src/MDNormalization.cpp b/Framework/MDAlgorithms/src/MDNormalization.cpp
index ee72199739f6b8b8c32ed14640fe7d47420ba9a3..1ead538f64046fc27e2f31d9bd21ca572b16082e 100644
--- a/Framework/MDAlgorithms/src/MDNormalization.cpp
+++ b/Framework/MDAlgorithms/src/MDNormalization.cpp
@@ -14,6 +14,9 @@
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/VisibleWhenProperty.h"
 #include "MantidKernel/Strings.h"
+#include "MantidKernel/CompositeValidator.h"
+#include "MantidAPI/CommonBinsValidator.h"
+#include "MantidAPI/InstrumentValidator.h"
 
 namespace Mantid {
 namespace MDAlgorithms {
@@ -50,7 +53,7 @@ void MDNormalization::init() {
                        "InputWorkspace", "", Kernel::Direction::Input),
                   "An input MDEventWorkspace. Must be in Q_sample frame.");
 
-  //RLU and settings
+  // RLU and settings
   declareProperty("RLU", true, "Use reciprocal lattice units. If false, use Q_sample");
   setPropertyGroup("RLU","Q projections RLU");
 
@@ -75,7 +78,26 @@ void MDNormalization::init() {
   setPropertySettings("QDimension3", make_unique<Kernel::VisibleWhenProperty>("RLU", IS_EQUAL_TO, "1"));
   setPropertyGroup("QDimension3","Q projections RLU");
 
-  //Define slicing
+  // vanadium
+  auto fluxValidator = boost::make_shared<CompositeValidator>();
+  fluxValidator->add<InstrumentValidator>();
+  fluxValidator->add<CommonBinsValidator>();
+  auto solidAngleValidator = fluxValidator->clone();
+  declareProperty(make_unique<WorkspaceProperty<>>("SolidAngleWorkspace", "",
+                                                   Direction::Input, API::PropertyMode::Optional,
+                                                   solidAngleValidator),
+                  "An input workspace containing integrated vanadium "
+                  "(a measure of the solid angle).\n"
+                  "Mandatory for diffraction, optional for direct geometry inelastic");
+  declareProperty(make_unique<WorkspaceProperty<>>(
+                      "FluxWorkspace", "", Direction::Input, API::PropertyMode::Optional,
+                      fluxValidator),
+                  "An input workspace containing momentum dependent flux.\n"
+                  "Mandatory for diffraction. No effect on direct geometry inelastic");
+  setPropertyGroup("SolidAngleWorkspace","Vanadium normalization");
+  setPropertyGroup("FluxWorkspace","Vanadium normalization");
+
+  // Define slicing
   for(std::size_t i=0;i<6;i++) {
     std::string propName = "Dimension"+Strings::toString(i)+"Name";
     std::string propBinning = "Dimension"+Strings::toString(i)+"Binning";
@@ -91,9 +113,33 @@ void MDNormalization::init() {
     setPropertyGroup(propBinning, "Binning");
   }
 
+  // symmetry operations
+  declareProperty(Kernel::make_unique<PropertyWithValue<std::string>>("SymmetryOps", "", Direction::Input),
+                  "If specified the symmetry will be applied, "
+                  "can be space group name or number, or list individual symmetries.");
+
+  // temporary workspaces
+  declareProperty(make_unique<WorkspaceProperty<IMDHistoWorkspace>>(
+                      "TemporaryDataWorkspace", "", Direction::Input,
+                      PropertyMode::Optional),
+                  "An input MDHistoWorkspace used to accumulate data from "
+                  "multiple MDEventWorkspaces. If unspecified a blank "
+                  "MDHistoWorkspace will be created.");
+  declareProperty(make_unique<WorkspaceProperty<IMDHistoWorkspace>>(
+                      "TemporaryNormalizationWorkspace", "", Direction::Input,
+                      PropertyMode::Optional),
+                  "An input MDHistoWorkspace used to accumulate normalization "
+                  "from multiple MDEventWorkspaces. If unspecified a blank "
+                  "MDHistoWorkspace will be created.");
+  setPropertyGroup("TemporaryDataWorkspace", "Temporary workspaces");
+  setPropertyGroup("TemporaryNormalizationWorkspace", "Temporary workspaces");
+
   declareProperty(make_unique<WorkspaceProperty<API::Workspace>>(
                       "OutputWorkspace", "", Kernel::Direction::Output),
                   "A name for the output data MDHistoWorkspace.");
+  declareProperty(make_unique<WorkspaceProperty<Workspace>>(
+                      "OutputNormalizationWorkspace", "", Direction::Output),
+                  "A name for the output normalization MDHistoWorkspace.");
 }
 
 //----------------------------------------------------------------------------------------------
@@ -117,6 +163,21 @@ MDNormalization::validateInputs() {
       }
     }
   }
+  // Check if the vanadium is available for diffraction
+  bool diffraction=true;
+  if ((inputWS->getNumDims() >3) && (inputWS->getDimension(3)->getMDFrame().name()=="DeltaE")) {
+    diffraction = false;
+  }
+  if (diffraction) {
+    API::MatrixWorkspace_const_sptr solidAngleWS = getProperty("SolidAngleWorkspace");
+    API::MatrixWorkspace_const_sptr fluxWS = getProperty("FluxWorkspace");
+    if (solidAngleWS == nullptr) {
+      errorMessage.emplace("SolidAngleWorkspace","SolidAngleWorkspace is required for diffraction");
+    }
+    if (fluxWS == nullptr) {
+      errorMessage.emplace("FluxWorkspace","FluxWorkspace is required for diffraction");
+    }
+  }
   // Check for property MDNorm_low and MDNorm_high
   size_t nExperimentInfos = inputWS->getNumExperimentInfo();
   if (nExperimentInfos == 0) {
@@ -138,6 +199,37 @@ MDNormalization::validateInputs() {
       }
     }
   }
+  // check projections
+  if (getProperty("RLU")) {
+    DblMatrix W = DblMatrix(3, 3);
+    std::vector<double> Q1Basis = getProperty("QDimension1");
+    std::vector<double> Q2Basis = getProperty("QDimension2");
+    std::vector<double> Q3Basis = getProperty("QDimension3");
+    W.setColumn(0, Q1Basis);
+    W.setColumn(1, Q2Basis);
+    W.setColumn(2, Q3Basis);
+    if (fabs(W.determinant()) < 1e-5) {
+      errorMessage.emplace("QDimension1",
+                           "The projection dimensions are coplanar or zero");
+      errorMessage.emplace("QDimension2",
+                           "The projection dimensions are coplanar or zero");
+      errorMessage.emplace("QDimension3",
+                           "The projection dimensions are coplanar or zero");
+    }
+  }
+  // check dimensions
+  std::vector<std::string> originalDimensionNames;
+  for (size_t i=3; i<inputWS->getNumDims(); i++) {
+    originalDimensionNames.push_back(inputWS->getDimension(i)->getName());
+  }
+  originalDimensionNames.push_back("QDimension1");
+  originalDimensionNames.push_back("QDimension2");
+  originalDimensionNames.push_back("QDimension3");
+  for(std::size_t i=0;i<6;i++) {
+    std::string propName = "Dimension"+Strings::toString(i)+"Name";
+    std::string dimName = getProperty(propName);
+    //auto it = std::find();
+  }
   return errorMessage;
 }
 //----------------------------------------------------------------------------------------------