diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h
index b2012724e47fef2fb3e55a07d33404130afdfb30..bd0d1c05f9db5909c349602531b1906c8c231ab2 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h
@@ -121,6 +121,7 @@ public:
   virtual void loadExperimentInfoNexus(::NeXus::File *file, std::string &parameterStr);
   /// Load the instrument from an open NeXus file.
   virtual void loadInstrumentInfoNexus(::NeXus::File *file, std::string &parameterStr);
+
   /// Load the sample and log info from an open NeXus file.
   virtual void loadSampleAndLogInfoNexus(::NeXus::File *file);
   /// Populate the parameter map given a string
@@ -164,6 +165,8 @@ private:
                              const Geometry::XMLInstrumentParameter &paramInfo,
                              const Run &runData);
 
+  //Loads the xml from an instrument file with some basic error handling
+  std::string loadInstrumentXML(const std::string& filename);
   /// Detector grouping information
   det2group_map m_detgroups;
   /// Mutex to protect against cow_ptr copying
diff --git a/Code/Mantid/Framework/API/src/ExperimentInfo.cpp b/Code/Mantid/Framework/API/src/ExperimentInfo.cpp
index d7a43ffc2ec12ac64fd742f54c9642c8365e49bb..a2d400489c0e36fff4d403caa67e890700b75ce1 100644
--- a/Code/Mantid/Framework/API/src/ExperimentInfo.cpp
+++ b/Code/Mantid/Framework/API/src/ExperimentInfo.cpp
@@ -1006,32 +1006,27 @@ void ExperimentInfo::loadInstrumentInfoNexus(::NeXus::File *file,
   instrumentFilename = Strings::strip(instrumentFilename);
   instrumentXml = Strings::strip(instrumentXml);
   instrumentName = Strings::strip(instrumentName);
-  if (instrumentXml.empty() && !instrumentName.empty()) {
-    // XML was not included or was empty.
-    // Use the instrument name to find the file
-    try {
-      std::string filename =
-          getInstrumentFilename(instrumentName, getWorkspaceStartDate());
-      // And now load the contents
-      instrumentFilename = filename;
-      instrumentXml = Strings::loadFile(filename);
-    } catch (std::exception &e) {
-      g_log.error() << "Error loading instrument IDF file for '"
-                    << instrumentName << "'.\n";
-      g_log.debug() << e.what() << std::endl;
-      throw;
-    }
-  } else {
-    if (!instrumentFilename.empty())
-      instrumentFilename = ConfigService::Instance().getInstrumentDirectory() +
-                           "/" + instrumentFilename;
+  if (!instrumentXml.empty()) {
+    // instrument xml is being loaded from the nxs file, set the instrumentFilename
+    // to identify the Nexus file as the source of the data
+    instrumentFilename = instrumentFilename;
     g_log.debug() << "Using instrument IDF XML text contained in nexus file.\n";
   }
+  else
+  {
+    // XML was not included or was empty
+    // Use the instrument name to find the file
+    std::string filename =
+        getInstrumentFilename(instrumentName, getWorkspaceStartDate());
+    // And now load the contents
+    instrumentFilename = filename;
+    instrumentXml = loadInstrumentXML(instrumentFilename);
+  }
 
   // ---------- Now parse that XML to make the instrument -------------------
   if (!instrumentXml.empty() && !instrumentName.empty()) {
-    InstrumentDefinitionParser parser;
-    parser.initialize(instrumentFilename, instrumentName, instrumentXml);
+    InstrumentDefinitionParser parser(instrumentFilename, instrumentName, instrumentXml);
+
     std::string instrumentNameMangled = parser.getMangledName();
     Instrument_sptr instr;
     // Check whether the instrument is already in the InstrumentDataService
@@ -1049,6 +1044,24 @@ void ExperimentInfo::loadInstrumentInfoNexus(::NeXus::File *file,
   }
 }
 
+//-------------------------------------------------------------------------------------------------
+/** Loads the contents of a file and returns the string
+ *  The file is assumed to be an IDF, and already checked that 
+ *  the path is correct.
+ *
+ * @param filename :: the path to the file
+ */
+std::string ExperimentInfo::loadInstrumentXML(const std::string &filename) {
+  try {
+    return Strings::loadFile(filename);
+  } catch (std::exception &e) {
+    g_log.error() << "Error loading instrument IDF file: "
+                  << filename << ".\n";
+    g_log.debug() << e.what() << std::endl;
+    throw;
+  }
+}
+
 //-------------------------------------------------------------------------------------------------
 /** Parse the result of ParameterMap.asString() into the ParameterMap
  * of the current instrument. The instrument needs to have been loaded
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp
index 673586cdad50c2699162bff71e1b55b66b14f010..9a2fcf760b636e7e4c91dfe20a081004da0a6789 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp
@@ -127,7 +127,7 @@ void LoadInstrument::exec() {
     const PropertyWithValue<std::string> *xml =
       dynamic_cast<const PropertyWithValue<std::string> *>(InstrumentXML);
     if (xml) {
-      parser.initialize(m_filename, m_instName, *xml);
+      parser = InstrumentDefinitionParser(m_filename, m_instName, *xml);
     } else {
       throw std::invalid_argument("The instrument XML passed cannot be "
                                   "casted to a standard string.");
@@ -165,7 +165,7 @@ void LoadInstrument::exec() {
     m_instName = instrumentFile.substr(0, instrumentFile.find("_Def"));
 
     // Initialize the parser with the the XML text loaded from the IDF file
-    parser.initialize(m_filename, m_instName, Strings::loadFile(m_filename));
+    parser = InstrumentDefinitionParser(m_filename, m_instName, Strings::loadFile(m_filename));
   }
 
   // Find the mangled instrument name that includes the modified date
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp
index 26c18005d8804a3aaa9ca2e9827f32ed5f407d01..57a7a2146c5d4d872b0b040ea65bcc139260f7ab 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp
@@ -187,9 +187,8 @@ void LoadMcStas::readEventData(
 
     progInitial.report("Loading instrument");
 
-    Geometry::InstrumentDefinitionParser parser;
     std::string instrumentName = "McStas";
-    parser.initialize(filename, instrumentName, instrumentXML);
+    Geometry::InstrumentDefinitionParser parser(filename, instrumentName, instrumentXML);
     std::string instrumentNameMangled = parser.getMangledName();
 
     // Check whether the instrument is already in the InstrumentDataService
diff --git a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h
index c2b5c23bab104197643cb04a67f4b2669f9b40c1..7b24673a12691d207b5059a3fd875ce6b9168891 100644
--- a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h
+++ b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h
@@ -829,8 +829,7 @@ public:
     // Loading a peaks workspace without a instrument from an IDF doesn't work ...
     const std::string filename = FileFinder::Instance().getFullPath(
           "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
-    InstrumentDefinitionParser parser;
-    parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
+    InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename));
     auto instrument = parser.parseXML(NULL);
     peaksTestWS->populateInstrumentParameters();
     peaksTestWS->setInstrument(instrument);
@@ -872,8 +871,7 @@ public:
     // Loading a peaks workspace without a instrument from an IDF doesn't work ...
     const std::string filename = FileFinder::Instance().getFullPath(
           "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
-    InstrumentDefinitionParser parser;
-    parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
+    InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename));
     auto instrument = parser.parseXML(NULL);
     peaksTestWS->populateInstrumentParameters();
     peaksTestWS->setInstrument(instrument);
diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h
index c50fb3e9503501167682b49b329dae77a954ba1d..e44f6b07c75fbc5af71835ccb37c790fa85cbb6c 100644
--- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h
+++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h
@@ -5,7 +5,6 @@
 #ifndef Q_MOC_RUN
 #include <boost/shared_ptr.hpp>
 #endif
-#include <Poco/Timestamp.h>
 #include <Poco/File.h>
 #include <Poco/Path.h>
 #include <stdexcept>
@@ -49,13 +48,11 @@ class DLLExport AbstractIDFObject {
 public:
   AbstractIDFObject() {}
   static const std::string expectedExtension();
-  virtual const Poco::Path &getParentDirectory() const = 0;
+  virtual const Poco::Path getParentDirectory() const = 0;
   virtual const Poco::Path &getFileFullPath() const = 0;
   virtual const std::string &getFileFullPathStr() const = 0;
   virtual std::string getFileNameOnly() const = 0;
   virtual std::string getExtension() const = 0;
-  virtual Poco::Timestamp getLastModified() const = 0;
-  virtual std::string getFormattedLastModified() const = 0;
   virtual std::string getMangledName() const = 0;
   virtual bool exists() const = 0;
   virtual ~AbstractIDFObject(){};
@@ -71,13 +68,11 @@ private:
 class DLLExport IDFObject : public AbstractIDFObject {
 public:
   IDFObject(const std::string &fileName);
-  virtual const Poco::Path &getParentDirectory() const;
+  virtual const Poco::Path getParentDirectory() const;
   virtual const Poco::Path &getFileFullPath() const;
   virtual const std::string &getFileFullPathStr() const;
   virtual std::string getFileNameOnly() const;
   virtual std::string getExtension() const;
-  virtual Poco::Timestamp getLastModified() const;
-  virtual std::string getFormattedLastModified() const;
   virtual std::string getMangledName() const;
   virtual bool exists() const;
   virtual ~IDFObject();
@@ -101,7 +96,7 @@ private:
 
 public:
   NullIDFObject() : m_emptyResponse("") {}
-  virtual const Poco::Path &getParentDirectory() const {
+  virtual const Poco::Path getParentDirectory() const {
     throw std::runtime_error("Not implemented on NullIDFObject");
   }
   virtual const Poco::Path &getFileFullPath() const {
@@ -112,12 +107,6 @@ public:
   }
   virtual std::string getFileNameOnly() const { return m_emptyResponse; }
   virtual std::string getExtension() const { return m_emptyResponse; }
-  virtual Poco::Timestamp getLastModified() const {
-    throw std::runtime_error("Not implemented on NullIDFObject");
-  }
-  virtual std::string getFormattedLastModified() const {
-    throw std::runtime_error("Not implemented on NullIDFObject");
-  }
   virtual std::string getMangledName() const {
     throw std::runtime_error("Not implemented on NullIDFObject");
   }
diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h
index 3a6a4edb1445cdd5d654caafbdd1e64b405580c4..1ee83c18075cb8d9f33d213464007668856131bc 100644
--- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h
+++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h
@@ -58,26 +58,22 @@ class Object;
 class DLLExport InstrumentDefinitionParser {
 public:
   InstrumentDefinitionParser();
+  InstrumentDefinitionParser(const std::string &filename, const std::string &instName,
+                  const std::string &xmlText);
+  InstrumentDefinitionParser(const IDFObject_const_sptr xmlFile, 
+                  const IDFObject_const_sptr expectedCacheFile, 
+                  const std::string& instName, const std::string& xmlText);
   ~InstrumentDefinitionParser();
 
   /// Caching
   enum CachingOption {
     NoneApplied,
-    ReadAdjacent,
+    ReadGeomCache,
     ReadFallBack,
-    WroteCacheAdjacent,
+    WroteGeomCache,
     WroteCacheTemp
   };
 
-  /// Set up parser
-  void initialize(const std::string &filename, const std::string &instName,
-                  const std::string &xmlText);
-
-  /// Set up parser.
-  void initialize(IDFObject_const_sptr xmlFile,
-                  IDFObject_const_sptr expectedCacheFile,
-                  const std::string &instName, const std::string &xmlText);
-
   /// Parse XML contents
   boost::shared_ptr<Instrument> parseXML(Kernel::ProgressBase *prog);
 
@@ -104,7 +100,19 @@ public:
   /// Getter the the applied caching option.
   CachingOption getAppliedCachingOption() const;
 
+  ///creates a vtp filename from a given xml filename
+  const std::string createVTPFileName();
+
 private:
+  ///shared Constructor logic
+  void initialise(const std::string &filename, 
+                  const std::string &instName,
+                  const std::string &xmlText,
+                  const std::string &vtpFilename);
+
+  ///lazy loads the document and returns a pointer
+  Poco::AutoPtr<Poco::XML::Document> getDocument();
+
   /// Set location (position) of comp as specified in XML location element
   void setLocation(Geometry::IComponent *comp, const Poco::XML::Element *pElem,
                    const double angleConvertConst,
@@ -210,7 +218,7 @@ private:
   /// notation for a sequence of \<location\> elements.
   /// This method return this sequence as a xml string
   std::string convertLocationsElement(const Poco::XML::Element *pElem);
-
+  
 public: // for testing
   /// return absolute position of point which is set relative to the
   /// coordinate system of the input component
@@ -218,14 +226,12 @@ public: // for testing
                                               Kernel::V3D);
 
 private:
-  /// Checks if the proposed cache file can be read from.
-  bool canUseProposedCacheFile(IDFObject_const_sptr cache) const;
-
   /// Reads from a cache file.
   void applyCache(IDFObject_const_sptr cacheToApply);
 
   /// Write out a cache file.
-  CachingOption writeAndApplyCache(IDFObject_const_sptr usedCache);
+  CachingOption writeAndApplyCache(IDFObject_const_sptr firstChoiceCache,
+    IDFObject_const_sptr usedCache);
 
   /// This method returns the parent appended which its child components and
   /// also name of type of the last child component
@@ -259,10 +265,8 @@ private:
   /// Name of the instrument
   std::string m_instName;
 
-  /// XML document loaded
-  Poco::AutoPtr<Poco::XML::Document> pDoc;
-  /// Root element of the parsed XML
-  Poco::XML::Element *pRootElem;
+  /// XML document is lazy loaded
+  Poco::AutoPtr<Poco::XML::Document> m_pDoc;
 
   /** Holds all the xml elements that have a \<parameter\> child element.
    *  Added purely for the purpose of computing speed and is used in
diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/IDFObject.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/IDFObject.cpp
index 35e8dd10d470dd820076b929ce8337965b9bd00f..150a84be6b9cecddb2c8a9c671aa27360b417506 100644
--- a/Code/Mantid/Framework/Geometry/src/Instrument/IDFObject.cpp
+++ b/Code/Mantid/Framework/Geometry/src/Instrument/IDFObject.cpp
@@ -33,7 +33,7 @@ IDFObject::~IDFObject() {}
 Gets the parent directory of the file.
 @return Parent directory path.
 */
-const Poco::Path &IDFObject::getParentDirectory() const {
+const Poco::Path IDFObject::getParentDirectory() const {
   return m_cacheParentDirectory;
 }
 
@@ -67,23 +67,6 @@ std::string IDFObject::getExtension() const {
     return "." + ext;
 }
 
-/**
-Gets the last modified timestamp of the file.
-@return last modified timestamp.
-*/
-Poco::Timestamp IDFObject::getLastModified() const {
-  return m_defFile.getLastModified();
-}
-
-/**
-Gets a formatted string of the last modified timestamp.
-@return timestamp as a formatted string.
-*/
-std::string IDFObject::getFormattedLastModified() const {
-  return Poco::DateTimeFormatter::format(this->getLastModified(),
-                                         "%Y-%d-%mT%H:%M:%S");
-}
-
 /**
 Gets the idf file as a mangled name.
 @return the idf file as a mangled name.
diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
index 7a1242493c94d906691087439cdae7bab1560d4b..2f96e19d3986c006c2de1e50651dfdd2f10dcf1f 100644
--- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
+++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
@@ -17,6 +17,7 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/Strings.h"
 
+#include <Poco/Path.h>
 #include <Poco/String.h>
 #include <Poco/DOM/Document.h>
 #include <Poco/DOM/DOMParser.h>
@@ -29,7 +30,6 @@
 
 #include <boost/make_shared.hpp>
 #include <boost/assign/list_of.hpp>
-#include <MantidKernel/ChecksumHelper.h>
 
 using namespace Mantid;
 using namespace Mantid::Kernel;
@@ -47,126 +47,162 @@ namespace {
 // initialize the static logger
 Kernel::Logger g_log("InstrumentDefinitionParser");
 }
-
-//----------------------------------------------------------------------------------------------
-/** Constructor
+  //----------------------------------------------------------------------------------------------
+/** Default Constructor - not very functional in this state
  */
-InstrumentDefinitionParser::InstrumentDefinitionParser()
-    : m_xmlFile(boost::make_shared<NullIDFObject>()),
-      m_cacheFile(boost::make_shared<NullIDFObject>()), pDoc(NULL),
-      pRootElem(NULL), m_hasParameterElement_beenSet(false),
+  InstrumentDefinitionParser::InstrumentDefinitionParser():
+      m_xmlFile(boost::make_shared<NullIDFObject>()),
+      m_cacheFile(boost::make_shared<NullIDFObject>()), m_pDoc(NULL),
+      m_hasParameterElement_beenSet(false),
       m_haveDefaultFacing(false), m_deltaOffsets(false),
       m_angleConvertConst(1.0), m_indirectPositions(false),
-      m_cachingOption(NoneApplied) {}
-
-//----------------------------------------------------------------------------------------------
-/** Destructor
- */
-InstrumentDefinitionParser::~InstrumentDefinitionParser() {}
-
+      m_cachingOption(NoneApplied)
+  {
+    initialise("","","","");
+  }
 //----------------------------------------------------------------------------------------------
-/** Initialize the XML parser based on an IDF xml file path.
- *
- *  Note that this convenience initialize method actually translates the inputs
- *into the other initialize method.
- *
+/** Constructor
  * @param filename :: IDF .xml path (full). This is needed mostly to find the
  *instrument geometry cache.
  * @param instName :: name of the instrument
  * @param xmlText :: XML contents of IDF
  */
-void InstrumentDefinitionParser::initialize(const std::string &filename,
-                                            const std::string &instName,
-                                            const std::string &xmlText) {
-  IDFObject_const_sptr xmlFile = boost::make_shared<const IDFObject>(filename);
-  // Use the filename to construct the cachefile name so that there is a 1:1 map
-  // between a definition file & cache
-  std::string idfExt = xmlFile->getExtension();
-  std::string vtpFilename = filename;
-  static const char *vtpExt = ".vtp";
-  if (idfExt.empty()) {
-    vtpFilename += vtpExt;
-  } else {
-    boost::replace_last(vtpFilename, idfExt, vtpExt);
-  }
-  IDFObject_const_sptr vtpFile =
-      boost::make_shared<const IDFObject>(vtpFilename);
-
-  this->initialize(xmlFile, vtpFile, instName, xmlText);
+InstrumentDefinitionParser::InstrumentDefinitionParser(const std::string &filename, 
+                                                       const std::string &instName,
+                                                       const std::string &xmlText)
+    : m_xmlFile(boost::make_shared<NullIDFObject>()),
+      m_cacheFile(boost::make_shared<NullIDFObject>()), m_pDoc(NULL),
+      m_hasParameterElement_beenSet(false),
+      m_haveDefaultFacing(false), m_deltaOffsets(false),
+      m_angleConvertConst(1.0), m_indirectPositions(false),
+      m_cachingOption(NoneApplied)
+{
+  initialise(filename,instName,xmlText,"");
 }
 
 //----------------------------------------------------------------------------------------------
-/** Initialize the XML parser based on an IDF xml and cached vtp file objects.
+/** Construct the XML parser based on an IDF xml and cached vtp file objects.
  *
  * @param xmlFile :: The xml file, here wrapped in a IDFObject
  * @param expectedCacheFile :: Expected vtp cache file
  * @param instName :: Instrument name
  * @param xmlText :: XML contents of IDF
  */
-void InstrumentDefinitionParser::initialize(
+InstrumentDefinitionParser::InstrumentDefinitionParser (
     const IDFObject_const_sptr xmlFile,
-    const IDFObject_const_sptr expectedCacheFile, const std::string &instName,
-    const std::string &xmlText) {
+    const IDFObject_const_sptr expectedCacheFile, 
+    const std::string &instName,
+    const std::string &xmlText) 
+    : m_xmlFile(boost::make_shared<NullIDFObject>()),
+      m_cacheFile(boost::make_shared<NullIDFObject>()), m_pDoc(NULL),
+      m_hasParameterElement_beenSet(false),
+      m_haveDefaultFacing(false), m_deltaOffsets(false),
+      m_angleConvertConst(1.0), m_indirectPositions(false),
+      m_cachingOption(NoneApplied) 
+{
+  initialise(xmlFile->getFileFullPathStr(),instName,xmlText,expectedCacheFile->getFileFullPathStr());
 
+  m_cacheFile = expectedCacheFile;
+}
+
+  //----------------------------------------------------------------------------------------------
+/** Initialise method used in Constructor
+ * @param filename :: IDF .xml path (full). This is needed mostly to find the
+ *instrument geometry cache.
+ * @param instName :: name of the instrument
+ * @param xmlText :: XML contents of IDF
+ * @param vtpFilename :: the path to the vtp file if you want to override the default
+ */
+void InstrumentDefinitionParser::initialise(const std::string &filename, 
+                                                       const std::string &instName,
+                                                       const std::string &xmlText,
+                                                       const std::string &vtpFilename) 
+{
+  
+  IDFObject_const_sptr xmlFile = boost::make_shared<const IDFObject>(filename);
+  
   // Handle the parameters
-  const std::string filename = xmlFile->getFileFullPathStr();
   m_instName = instName;
   m_xmlFile = xmlFile;
-  m_cacheFile = expectedCacheFile;
-
-  // Set up the DOM parser and parse xml file
-  DOMParser pParser;
-  try {
-    pDoc = pParser.parseString(xmlText);
-  } catch (Poco::Exception &exc) {
-    throw Kernel::Exception::FileError(
-        exc.displayText() + ". Unable to parse XML", filename);
-  } catch (...) {
-    throw Kernel::Exception::FileError("Unable to parse XML", filename);
-  }
-  // Get pointer to root element
-  pRootElem = pDoc->documentElement();
-  if (!pRootElem->hasChildNodes()) {
-    g_log.error("XML file: " + filename + "contains no root element.");
-    throw Kernel::Exception::InstrumentDefinitionError(
-        "No root element in XML instrument file", filename);
-  }
-
+  
   // Create our new instrument
   // We don't want the instrument name taken out of the XML file itself, it
   // should come from the filename (or the property)
   m_instrument = boost::make_shared<Instrument>(m_instName);
-
+  
   // Save the XML file path and contents
   m_instrument->setFilename(filename);
   m_instrument->setXmlText(xmlText);
+
+  // Use the filename to construct the cachefile name so that there is a 1:1 map
+  // between a definition file & cache
+  if (vtpFilename.empty()) {
+    m_cacheFile = boost::make_shared<const IDFObject>(createVTPFileName());
+  }
+  else
+  {
+    m_cacheFile = boost::make_shared<const IDFObject>(vtpFilename);
+  }
+
 }
+//----------------------------------------------------------------------------------------------
+/** Destructor
+ */
+InstrumentDefinitionParser::~InstrumentDefinitionParser() {}
 
 //----------------------------------------------------------------------------------------------
 /**
  * Handle used in the singleton constructor for instrument file should append
  *the value
- * of the last-modified tag inside the file to determine if it is already in
+ * file sha-1 checksum to determine if it is already in
  *memory so that
  * changes to the instrument file will cause file to be reloaded.
  *
- * @return a mangled name combining the filename and the "last-modified"
+ * @return a mangled name combining the filename and the checksum
  *attribute of the XML contents
  * */
 std::string InstrumentDefinitionParser::getMangledName() {
   
-  // Use the file in preference if possible.
-  if (this->m_xmlFile->exists()) {
-    return m_xmlFile->getMangledName();
-  } 
+  std::string retVal = "";
+  //use the xml in preference if available
   auto xml = Poco::trim(m_instrument->getXmlText());
   if (!(xml.empty())) {
     std::string checksum = Kernel::ChecksumHelper::sha1FromString(xml);
-    return m_instName + checksum;
-  } else  {
-    throw std::runtime_error(
-        "Call InstrumentDefinitionParser::initialize() before getMangledName.");
+    retVal = m_instName + checksum; 
+  } 
+  else if (this->m_xmlFile->exists()) {// Use the file
+    retVal =  m_xmlFile->getMangledName();
+  } 
+
+  return retVal;
+
+}
+
+//----------------------------------------------------------------------------------------------
+/** Lazy loads the document and returns a autopointer
+ *
+ * @return an autopointer to the xml document
+ */
+Poco::AutoPtr<Poco::XML::Document> InstrumentDefinitionParser::getDocument()
+{
+  if (!m_pDoc) {
+    //instantiate if not created
+    if (m_instrument->getXmlText().empty())
+    {
+      throw std::invalid_argument("Instrument XML string is empty");
+    }
+    // Set up the DOM parser and parse xml file
+    DOMParser pParser;
+    try {
+      m_pDoc = pParser.parseString(m_instrument->getXmlText());
+    } catch (Poco::Exception &exc) {
+      throw std::invalid_argument(
+          exc.displayText() + ". Unable to parse XML");
+    } catch (...) {
+      throw std::invalid_argument("Unable to parse XML");
+    }
   }
+  return m_pDoc;
 }
 
 //----------------------------------------------------------------------------------------------
@@ -178,9 +214,16 @@ std::string InstrumentDefinitionParser::getMangledName() {
  */
 Instrument_sptr
 InstrumentDefinitionParser::parseXML(Kernel::ProgressBase *prog) {
-  if (!pDoc)
-    throw std::runtime_error(
-        "Call InstrumentDefinitionParser::initialize() before parseXML.");
+  auto pDoc = getDocument();
+
+  // Get pointer to root element
+  Poco::XML::Element * pRootElem = pDoc->documentElement();
+  
+  if (!pRootElem->hasChildNodes()) {
+    g_log.error("Instrument XML contains no root element.");
+    throw Kernel::Exception::InstrumentDefinitionError(
+        "No root element in XML instrument");
+  }
 
   setValidityRange(pRootElem);
   readDefaults(pRootElem->getChildElement("defaults"));
@@ -508,7 +551,8 @@ void InstrumentDefinitionParser::saveDOM_Tree(std::string &outFilename) {
   Poco::XML::DOMWriter writer;
   writer.setNewLine("\n");
   writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);
-
+  
+  auto pDoc = getDocument();
   std::ofstream outFile(outFilename.c_str());
   writer.writeNode(outFile, pDoc);
   outFile.close();
@@ -951,8 +995,7 @@ void InstrumentDefinitionParser::readDefaults(Poco::XML::Element *defaults) {
     Handedness handedness = s_handedness.compare("right") == 0 ? Right : Left;
 
     // Overwrite the default reference frame.
-    m_instrument->setReferenceFrame(boost::shared_ptr<ReferenceFrame>(
-        new ReferenceFrame(pointingUp, alongBeam, handedness, s_origin)));
+    m_instrument->setReferenceFrame(boost::make_shared<ReferenceFrame>(pointingUp, alongBeam, handedness, s_origin));
   }
 }
 
@@ -1294,7 +1337,7 @@ void InstrumentDefinitionParser::appendLeaf(Geometry::ICompAssembly *parent,
               boost::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[y]);
           if (detector) {
             // Make default facing for the pixel
-            Geometry::IComponent *comp = (Geometry::IComponent *)detector.get();
+            Geometry::IComponent *comp = static_cast<IComponent *>(detector.get());
             if (m_haveDefaultFacing)
               makeXYplaneFaceComponent(comp, m_defaultFacing);
             // Mark it as a detector (add to the instrument cache)
@@ -2069,7 +2112,7 @@ void InstrumentDefinitionParser::setComponentLinks(
   unsigned long numberLinks = pNL_link->length();
 
   if (progress)
-    progress->resetNumSteps((int64_t)numberLinks, 0.0, 0.95);
+    progress->resetNumSteps(static_cast<int64_t>(numberLinks), 0.0, 0.95);
 
   Node *curNode = pRootElem->firstChild();
   while (curNode) {
@@ -2092,7 +2135,7 @@ void InstrumentDefinitionParser::setComponentLinks(
         int detid;
         std::stringstream(id) >> detid;
         boost::shared_ptr<const Geometry::IComponent> detector =
-            instrument->getDetector((detid_t)detid);
+            instrument->getDetector(static_cast<detid_t>(detid));
 
         // If we didn't find anything with the detector id, explain why to the
         // user, and throw an exception.
@@ -2160,17 +2203,6 @@ void InstrumentDefinitionParser::setComponentLinks(
   }
 }
 
-/**
-Check that the cache file does actually exist and that it was modified last
-after the last modification to the xml def file. i.e. the vtp file contains the
-most recent set of changes.
-@param cacheCandiate : candiate cache file object to use the the geometries.
-*/
-bool InstrumentDefinitionParser::canUseProposedCacheFile(
-    IDFObject_const_sptr cacheCandiate) const {
-  return m_xmlFile->exists() && cacheCandiate->exists() &&
-         (m_xmlFile->getLastModified() < cacheCandiate->getLastModified());
-}
 
 /**
 Apply the cache.
@@ -2194,19 +2226,18 @@ Write the cache file from the IDF file and apply it.
 @param fallBackCache : File location for a fallback cache if required.
 */
 InstrumentDefinitionParser::CachingOption
-InstrumentDefinitionParser::writeAndApplyCache(
+InstrumentDefinitionParser::writeAndApplyCache(IDFObject_const_sptr firstChoiceCache,
     IDFObject_const_sptr fallBackCache) {
-  IDFObject_const_sptr usedCache = m_cacheFile;
-  InstrumentDefinitionParser::CachingOption cachingOption = WroteCacheAdjacent;
+  IDFObject_const_sptr usedCache = firstChoiceCache;
+  auto cachingOption = WroteGeomCache;
 
   g_log.information("Geometry cache is not available");
   try {
-    Poco::File dir = m_xmlFile->getParentDirectory();
-    if (!m_xmlFile->exists() || dir.path().empty() || !dir.exists() ||
-        !dir.canWrite()) {
+    Poco::File dir = usedCache->getParentDirectory();
+    if (dir.path().empty() || !dir.exists() || !dir.canWrite()) {
       usedCache = fallBackCache;
       cachingOption = WroteCacheTemp;
-      g_log.information() << "Instrument directory is read only, writing cache "
+      g_log.information() << "Geometrycache directory is read only, writing cache "
                              "to system temp.\n";
     }
   } catch (Poco::FileNotFoundException &) {
@@ -2239,17 +2270,17 @@ InstrumentDefinitionParser::setupGeometryCache() {
   // directory.
   IDFObject_const_sptr fallBackCache = boost::make_shared<const IDFObject>(
       Poco::Path(ConfigService::Instance().getTempDir())
-          .append(m_instName + ".vtp")
+          .append(this->getMangledName()+".vtp")
           .toString());
   CachingOption cachingOption = NoneApplied;
-  if (canUseProposedCacheFile(m_cacheFile)) {
+  if (m_cacheFile->exists()) {
     applyCache(m_cacheFile);
-    cachingOption = ReadAdjacent;
-  } else if (canUseProposedCacheFile(fallBackCache)) {
+    cachingOption = ReadGeomCache;
+  } else if (fallBackCache->exists()) {
     applyCache(fallBackCache);
     cachingOption = ReadFallBack;
   } else {
-    cachingOption = writeAndApplyCache(fallBackCache);
+    cachingOption = writeAndApplyCache(m_cacheFile,fallBackCache);
   }
   return cachingOption;
 }
@@ -2668,6 +2699,24 @@ std::string InstrumentDefinitionParser::convertLocationsElement(
   return xml.str();
 }
 
+ /** Generates a vtp filename from a xml filename
+ *
+ *  @return The vtp filename
+ *
+ */
+const std::string InstrumentDefinitionParser::createVTPFileName()
+{
+  std::string retVal;
+  std::string filename = getMangledName();
+  if (!filename.empty())  {
+    Poco::Path path(ConfigService::Instance().getVTPFileDirectory());
+    path.makeDirectory();
+    path.append(filename + ".vtp");
+    retVal = path.toString();
+  }
+  return retVal;
+}
+
 /** Return a subelement of an XML element, but also checks that there exist
  *exactly one entry
  *  of this subelement.
diff --git a/Code/Mantid/Framework/Geometry/test/IDFObjectTest.h b/Code/Mantid/Framework/Geometry/test/IDFObjectTest.h
index ff93226299f6413ec5d612071c4cf47a78e99a79..2070ba2183c0bb01bf798ed3fd009acb8821bcd5 100644
--- a/Code/Mantid/Framework/Geometry/test/IDFObjectTest.h
+++ b/Code/Mantid/Framework/Geometry/test/IDFObjectTest.h
@@ -80,24 +80,6 @@ public:
     TS_ASSERT_EQUALS(filenameonly, obj.getFileNameOnly());
   }
 
-  void testGetModifiedTimestamp()
-  {
-    const std::string filename = ConfigService::Instance().getInstrumentDirectory() + "/IDFs_for_UNIT_TESTING/IDF_for_UNIT_TESTING.xml";
-    Poco::File file(filename);
-
-    IDFObject obj(filename);
-    TS_ASSERT_EQUALS(file.getLastModified(), obj.getLastModified());
-  }
-
-  void testGetFormattedModifiedTimestamp()
-  {
-    const std::string filename = ConfigService::Instance().getInstrumentDirectory() + "/IDFs_for_UNIT_TESTING/IDF_for_UNIT_TESTING.xml";
-    Poco::File file(filename);
-
-    IDFObject obj(filename);
-    TS_ASSERT_EQUALS(Poco::DateTimeFormatter::format(file.getLastModified(), "%Y-%d-%mT%H:%M:%S"), obj.getFormattedLastModified());
-  }
-
   void testGetMangledName()
   {
     const std::string filename = ConfigService::Instance().getInstrumentDirectory() + "/IDFs_for_UNIT_TESTING/IDF_for_UNIT_TESTING.xml";
diff --git a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h
index e938bf680146b7b9baaf2c7d0fcf77c565850941..3499e9919cc8f5bed3f6f30bb2d0614a94cf8f0c 100644
--- a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h
+++ b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
+#include "MantidKernel/ChecksumHelper.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Strings.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
@@ -10,7 +11,6 @@
 #include "MantidTestHelpers/ScopedFileHelper.h"
 
 #include <gmock/gmock.h>
-#include <boost/tuple/tuple.hpp>
 #include <boost/algorithm/string/replace.hpp>
 
 using namespace Mantid;
@@ -29,12 +29,20 @@ private:
   {
   public:
     MockIDFObject(const std::string fileName) : Mantid::Geometry::IDFObject(fileName){}
-    MOCK_CONST_METHOD0(getLastModified, Poco::Timestamp());
     MOCK_CONST_METHOD0(exists, bool());
   };
 
+  /// Mock Type to act as IDF files.
+  class MockIDFObjectWithParentDirectory : public Mantid::Geometry::IDFObject
+  {
+  public:
+    MockIDFObjectWithParentDirectory(const std::string fileName) : Mantid::Geometry::IDFObject(fileName){}
+    MOCK_CONST_METHOD0(exists, bool());
+    MOCK_CONST_METHOD0(getParentDirectory, const Poco::Path());
+  };
+
   /**
-  Helper type to pass around related IDF enviroment information in a collection.
+  Helper type to pass around related IDF environment information in a collection.
   */
   struct IDFEnvironment
   {
@@ -56,7 +64,6 @@ private:
   {
     const std::string instrument_name = "MinimalForTesting";
     const std::string idf_filename = instrument_name + "_Definition.xml";
-    const std::string vtp_filename= instrument_name + ".vtp";
     const std::string idf_file_contents = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
     "<instrument name=\"MinimalForTesting\" valid-from   =\"1900-01-31 23:59:59\" valid-to=\"2100-01-31 23:59:59\" last-modified=\"2012-10-05 11:00:00\">"
     "<defaults/>"
@@ -76,17 +83,17 @@ private:
      "</idlist>"
     "</instrument>";
 
+    //expected name
+    const std::string vtp_filename = instrument_name + ChecksumHelper::sha1FromString(Strings::strip(idf_file_contents)) + ".vtp";
     const std::string vtp_file_contents="<VTKFile byte_order=\"LittleEndian\" type=\"PolyData\" version=\"1.0\"><PolyData/></VTKFile>";
-
+    
     const std::string instrument_dir = ConfigService::Instance().getInstrumentDirectory() + "/IDFs_for_UNIT_TESTING/";
-
-    ScopedFile idf(idf_file_contents, idf_filename, instrument_dir);
-    ScopedFile vtp(vtp_file_contents, vtp_filename, instrument_dir); // Put the vtp file adjacent to the idf.
-
-    if(!put_vtp_next_to_IDF)
-    {
-      vtp = ScopedFile(vtp_file_contents, vtp_filename); // Overwrite to put vtp file in the temp dir
+    std::string vtp_dir = ConfigService::Instance().getVTPFileDirectory();
+    if (!put_vtp_next_to_IDF) {
+      vtp_dir= ConfigService::Instance().getTempDir();
     }
+    ScopedFile idf(idf_file_contents, idf_filename, instrument_dir);
+    ScopedFile vtp(vtp_file_contents, vtp_filename, vtp_dir); 
 
     return IDFEnvironment(idf, vtp, idf_file_contents, instrument_name); 
 
@@ -114,8 +121,7 @@ public:
     boost::shared_ptr<const Instrument> i;
 
     // Parse the XML
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(filename, "For Unit Testing", xmlText); );
+    InstrumentDefinitionParser parser(filename, "For Unit Testing", xmlText);
     TS_ASSERT_THROWS_NOTHING( i = parser.parseXML(NULL); );
 
     // Extract the reference frame object
@@ -136,8 +142,10 @@ public:
     std::string xmlText = Strings::loadFile(filename);
     boost::shared_ptr<const Instrument> i;
 
+    InstrumentDefinitionParser parser(filename, "For Unit Testing", xmlText); 
+    
     // Parse the XML (remove old vtp file if it exists)
-    std::string vtpFilename = filenameNoExt + ".vtp";
+    std::string vtpFilename = parser.createVTPFileName();
     try
     {
       Poco::File vtpFile(vtpFilename);
@@ -145,10 +153,7 @@ public:
     }
     catch(Poco::FileNotFoundException&) {}
 
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(filename, "For Unit Testing", xmlText); );
     TS_ASSERT_THROWS_NOTHING( i = parser.parseXML(NULL); );
-
     try
     {
       Poco::File vtpFile(vtpFilename);
@@ -433,8 +438,7 @@ public:
     boost::shared_ptr<const Instrument> i;
 
     // Parse the XML
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(filename, "For Unit Testing2", xmlText); );
+    InstrumentDefinitionParser parser(filename, "For Unit Testing2", xmlText); 
     TS_ASSERT_THROWS_NOTHING( i = parser.parseXML(NULL); );
 
     boost::shared_ptr<const IDetector> ptrDetShape = i->getDetector(1100);
@@ -478,8 +482,7 @@ public:
     boost::shared_ptr<const Instrument> i;
 
     // Parse the XML
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(filename, "RectangularUnitTest", xmlText); );
+    InstrumentDefinitionParser parser(filename, "RectangularUnitTest", xmlText);
     TS_ASSERT_THROWS_NOTHING( i = parser.parseXML(NULL); );
 
     // Now the XY detector in bank1
@@ -533,8 +536,7 @@ public:
     boost::shared_ptr<const Instrument> i;
 
     // Parse the XML
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(filename, "AdjustTest", xmlText); );
+    InstrumentDefinitionParser parser(filename, "AdjustTest", xmlText);
     TS_ASSERT_THROWS_NOTHING( i = parser.parseXML(NULL); );
 
     // None rotated cuboid
@@ -614,73 +616,19 @@ public:
     TS_ASSERT_EQUALS(InstrumentDefinitionParser::NoneApplied, parser.getAppliedCachingOption());
   }
 
-  void testUseAdjacentCacheFile()
+  void testCreateVTPFilename()
   {
     IDFEnvironment instrumentEnv = create_idf_and_vtp_pair();
-    
     const std::string idfFileName = instrumentEnv._idf.getFileName();
-    const std::string cacheFileName = instrumentEnv._vtp.getFileName();
-
-    MockIDFObject* mockIDF = new MockIDFObject(idfFileName);
-    MockIDFObject* mockCache = new MockIDFObject(cacheFileName);
-
-    EXPECT_CALL(*mockIDF, exists()).WillRepeatedly(Return(true));
-    EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(true));
-
-    const Poco::Timestamp smallerTime = 0;
-    const Poco::Timestamp largerTime = smallerTime + 1;
-
-    EXPECT_CALL(*mockIDF, getLastModified()).WillOnce(Return(smallerTime)); 
-    EXPECT_CALL(*mockCache, getLastModified()).WillOnce(Return(largerTime)); // Mock expectation set such that Cache file modified created most recently, so SHOULD be used.
-
-    IDFObject_const_sptr idf(mockIDF);
-    IDFObject_const_sptr cache(mockCache);
-
-    InstrumentDefinitionParser parser;
+    const std::string instrumentName = instrumentEnv._instName;
     const std::string xmlText = Strings::loadFile(idfFileName);
-    const std::string instrumentName = "UseAjacentCache";
-    parser.initialize(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
-    TS_ASSERT_THROWS_NOTHING(parser.parseXML(NULL));
-
-    TS_ASSERT_EQUALS(InstrumentDefinitionParser::ReadAdjacent, parser.getAppliedCachingOption()); // Check that the adjacent cache file was used.
-    TS_ASSERT(Mock::VerifyAndClearExpectations(mockIDF));
-    TS_ASSERT(Mock::VerifyAndClearExpectations(mockCache));
-  }
+    InstrumentDefinitionParser parser(idfFileName,instrumentName,xmlText);
 
-  void testWriteAdjacentCacheFileIfCacheIsOutOfDate()
-  {
-    IDFEnvironment instrumentEnv = create_idf_and_vtp_pair();
-    
-    const std::string idfFileName = instrumentEnv._idf.getFileName();
-    const std::string cacheFileName = instrumentEnv._vtp.getFileName();
-
-    MockIDFObject* mockIDF = new MockIDFObject(idfFileName);
-    MockIDFObject* mockCache = new MockIDFObject(cacheFileName);
-
-    EXPECT_CALL(*mockIDF, exists()).WillRepeatedly(Return(true));
-    EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(true));
-
-    const Poco::Timestamp smallerTime = 0;
-    const Poco::Timestamp largerTime = smallerTime + 1;
-
-    EXPECT_CALL(*mockIDF, getLastModified()).WillRepeatedly(Return(largerTime)); // Mock expectation set up so that IDF will appear newer than cache file.
-    EXPECT_CALL(*mockCache, getLastModified()).WillRepeatedly(Return(smallerTime)); 
-
-    IDFObject_const_sptr idf(mockIDF);
-    IDFObject_const_sptr cache(mockCache);
-
-    InstrumentDefinitionParser parser;
-    parser.initialize(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
-    TS_ASSERT_THROWS_NOTHING(parser.parseXML(NULL));
-
-    TS_ASSERT_EQUALS(InstrumentDefinitionParser::WroteCacheAdjacent, parser.getAppliedCachingOption()); // Check that the adjacent cache file was used.
-    TS_ASSERT(Mock::VerifyAndClearExpectations(mockIDF));
-    TS_ASSERT(Mock::VerifyAndClearExpectations(mockCache));
+    TS_ASSERT_EQUALS(instrumentEnv._vtp.getFileName(), parser.createVTPFileName());
   }
-
+  
   void testReadFromCacheInTempDirectory()
   {
-    const time_t tAtStart = 0; // create an early timestamp for use later.
     const bool put_vtp_in_instrument_directory = false;
     IDFEnvironment instrumentEnv = create_idf_and_vtp_pair(put_vtp_in_instrument_directory);
     
@@ -691,24 +639,35 @@ public:
     MockIDFObject* mockCache = new MockIDFObject(cacheFileName); 
 
     EXPECT_CALL(*mockIDF, exists()).WillRepeatedly(Return(true));
-    EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(false)); // Mock expectation set such that adjacent Cache file does not exist, so should not be used.
+    EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(false)); // Mock expectation set such that geometry Cache file does not exist, so should not be used.
 
-    EXPECT_CALL(*mockIDF, getLastModified()).WillOnce(Return(tAtStart)); 
 
     IDFObject_const_sptr idf(mockIDF);
     IDFObject_const_sptr cache(mockCache);
 
-    InstrumentDefinitionParser parser;
+    InstrumentDefinitionParser parser(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
 
-    parser.initialize(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
     TS_ASSERT_THROWS_NOTHING(parser.parseXML(NULL));
 
-    TS_ASSERT_EQUALS(InstrumentDefinitionParser::ReadFallBack, parser.getAppliedCachingOption()); // Check that the adjacent cache file was used.
+    TS_ASSERT_EQUALS(InstrumentDefinitionParser::ReadFallBack, parser.getAppliedCachingOption()); // Check that the geometry cache file was used.
     TS_ASSERT(Mock::VerifyAndClearExpectations(mockIDF));
     TS_ASSERT(Mock::VerifyAndClearExpectations(mockCache));
   }
 
-  void testWriteAdjacentCacheFileIfCacheDoestExist()
+  void RemoveFallbackVTPFile(InstrumentDefinitionParser& parser)
+  {
+    Poco::Path vtpPath(parser.createVTPFileName());
+    Poco::Path fallbackPath(ConfigService::Instance().getTempDir());
+    fallbackPath.makeDirectory();
+    fallbackPath.setFileName(vtpPath.getFileName());
+    std::string fp = fallbackPath.toString();
+    Poco::File fallbackFile(fallbackPath.toString());
+    if (fallbackFile.exists()) {
+      fallbackFile.remove();
+    }
+  }
+
+  void testWriteCacheFileIfCacheDoestExist()
   {
     IDFEnvironment instrumentEnv = create_idf_and_vtp_pair();
     
@@ -718,18 +677,22 @@ public:
     MockIDFObject* mockIDF = new MockIDFObject(idfFileName);
     MockIDFObject* mockCache = new MockIDFObject(cacheFileName); 
 
+    //make sure the fallback location for the geometry file is deleted
+
+
     EXPECT_CALL(*mockIDF, exists()).WillRepeatedly(Return(true));
     EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(false)); // Mock expectation set such that Cache file does not exist, so should not be used.
 
     IDFObject_const_sptr idf(mockIDF);
     IDFObject_const_sptr cache(mockCache);
 
-    InstrumentDefinitionParser parser;
-    
-    parser.initialize(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
-    TS_ASSERT_THROWS_NOTHING(parser.parseXML(NULL));
+    //remove the fallback file if it exists
+    InstrumentDefinitionParser parser(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
+    RemoveFallbackVTPFile(parser);
 
-    TS_ASSERT_EQUALS(InstrumentDefinitionParser::WroteCacheAdjacent, parser.getAppliedCachingOption()); // Check that the adjacent cache file was used.
+    TS_ASSERT_THROWS_NOTHING(parser.parseXML(NULL));
+   
+    TS_ASSERT_EQUALS(InstrumentDefinitionParser::WroteGeomCache, parser.getAppliedCachingOption()); // Check that the geometry cache file was used.
     TS_ASSERT(Mock::VerifyAndClearExpectations(mockIDF));
     TS_ASSERT(Mock::VerifyAndClearExpectations(mockCache));
   }
@@ -746,16 +709,17 @@ public:
     const std::string cacheFileName = instrumentEnv._vtp.getFileName(); // We do provide a cache file, but this shouldn't be used.
 
     MockIDFObject* mockIDF = new MockIDFObject(idfFileName);
-    MockIDFObject* mockCache = new MockIDFObject(cacheFileName); 
+    MockIDFObjectWithParentDirectory* mockCache = new MockIDFObjectWithParentDirectory(cacheFileName); 
 
     EXPECT_CALL(*mockIDF, exists()).WillRepeatedly(Return(false)); // IDF set not to exist.
-    EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(true)); // Mock expectation set such that Cache file does exist, but should not be used..
+    EXPECT_CALL(*mockCache, exists()).WillRepeatedly(Return(false)); // Mock expectation set such that Cache file does not exist, and location is inaccessible.
+    EXPECT_CALL(*mockCache, getParentDirectory()).WillRepeatedly(Return(Poco::Path("this does not exist")));
 
     IDFObject_const_sptr idf(mockIDF);
     IDFObject_const_sptr cache(mockCache);
 
-    InstrumentDefinitionParser parser;
-    parser.initialize(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
+    InstrumentDefinitionParser parser(idf, cache, instrumentEnv._instName, instrumentEnv._xmlText);
+
     TS_ASSERT_THROWS_NOTHING(parser.parseXML(NULL));
 
     TS_ASSERT_EQUALS(InstrumentDefinitionParser::WroteCacheTemp, parser.getAppliedCachingOption()); // Check that the TEMP cache file was used.
@@ -797,8 +761,7 @@ public:
 
     ScopedFile idfFile = createIDFFileObject(idfFilename, idfFileContents);
 
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(idfFilename, "For Unit Testing", idfFileContents); );
+    InstrumentDefinitionParser parser(idfFilename, "For Unit Testing", idfFileContents);
 
     std::string errorMsg("");
     try
@@ -827,8 +790,7 @@ public:
     boost::replace_first(contents, "%LOCATIONS%", locations);
     boost::replace_first(contents, "%NUM_DETECTORS%", boost::lexical_cast<std::string>(numDetectors));
 
-    InstrumentDefinitionParser parser;
-    parser.initialize(filename, "LocationsTestInstrument", contents);
+    InstrumentDefinitionParser parser(filename, "LocationsTestInstrument", contents);
 
     Instrument_sptr instr;
 
@@ -996,8 +958,7 @@ void testLoadingAndParsing()
     }
     catch(Poco::FileNotFoundException&) {}
 
-    InstrumentDefinitionParser parser;
-    TS_ASSERT_THROWS_NOTHING( parser.initialize(filename, "For Unit Testing", xmlText); );
+    InstrumentDefinitionParser parser(filename, "For Unit Testing", xmlText);
     TS_ASSERT_THROWS_NOTHING( i = parser.parseXML(NULL); );
 
     // Remove it for clean test
@@ -1017,3 +978,4 @@ void testLoadingAndParsing()
 
 #endif /* MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSERTEST_H_ */
 
+
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h
index 5f218e2a1dc0f05d15bc93628702cdcf0c663a6a..ed1da6ad340e716a05e0f9283c051bf8c5e19f31 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h
@@ -206,6 +206,8 @@ public:
   const std::vector<std::string> &getInstrumentDirectories() const;
   /// Get instrument search directory
   const std::string getInstrumentDirectory() const;
+  ///get the vtp file directory
+  const std::string getVTPFileDirectory();
   //@}
 
   /// Load facility information from instrumentDir/Facilities.xml file
diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
index 4ff60619ab8f8ecd239f2466b9d06f6e745357f0..e309fbd9c54fd1fdd5e51e9174bfb40e7687f1c5 100644
--- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
+++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
@@ -187,14 +187,6 @@ ConfigServiceImpl::ConfigServiceImpl()
     }
   }
 
-  // Assert that the appdata and the instrument subdirectory exists
-  std::string appDataDir = getAppDataDir();
-  Poco::Path path(appDataDir);
-  path.pushDirectory("instrument");
-  Poco::File file(path);
-  // createdirectories will fail gracefully if it is already present
-  file.createDirectories();
-
   // Fill the list of possible relative path keys that may require conversion to
   // absolute paths
   m_ConfigPaths.insert(
@@ -203,6 +195,7 @@ ConfigServiceImpl::ConfigServiceImpl()
   m_ConfigPaths.insert(std::make_pair("pvplugins.directory", true));
   m_ConfigPaths.insert(std::make_pair("mantidqt.plugins.directory", true));
   m_ConfigPaths.insert(std::make_pair("instrumentDefinition.directory", true));
+  m_ConfigPaths.insert(std::make_pair("instrumentDefinition.vtpDirectory", true));
   m_ConfigPaths.insert(std::make_pair("groupingFiles.directory", true));
   m_ConfigPaths.insert(std::make_pair("maskFiles.directory", true));
   m_ConfigPaths.insert(std::make_pair("colormaps.directory", true));
@@ -253,6 +246,16 @@ ConfigServiceImpl::ConfigServiceImpl()
 #ifndef MPI_BUILD // There is no logging to file by default in MPI build
   g_log.information() << "Logging to: " << m_logFilePath << std::endl;
 #endif
+
+  // Assert that the appdata and the instrument subdirectory exists
+  std::string appDataDir = getAppDataDir();
+  Poco::Path path(appDataDir);
+  path.pushDirectory("instrument");
+  Poco::File file(path);
+  // createdirectories will fail gracefully if it is already present
+  file.createDirectories();
+  Poco::File vtpDir(getVTPFileDirectory());
+  vtpDir.createDirectories();
 }
 
 /** Private Destructor
@@ -1669,7 +1672,24 @@ ConfigServiceImpl::getInstrumentDirectories() const {
 const std::string ConfigServiceImpl::getInstrumentDirectory() const {
   return m_InstrumentDirs[m_InstrumentDirs.size() - 1];
 }
-
+/**
+ * Return the search directory for vtp files
+ * @returns a path
+ */
+const std::string ConfigServiceImpl::getVTPFileDirectory() {
+  // Determine the search directory for XML instrument definition files (IDFs)
+  std::string directoryName = getString("instrumentDefinition.vtpDirectory");
+  
+  if (directoryName.empty())
+  {
+    Poco::Path path(getAppDataDir());
+    path.makeDirectory();
+    path.pushDirectory("instrument");
+    path.pushDirectory("geometryCache");
+    directoryName = path.toString();
+  }
+  return directoryName;
+}
 /**
  * Fills the internal cache of instrument definition directories
  */
diff --git a/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp
index 9a8941ae9d41b443a90a7e5521cf62d2c481c308..ac738ae22134feb2fa14fc27100fffd7e2c2a39c 100644
--- a/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp
+++ b/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp
@@ -69,8 +69,7 @@ createDiffractionEventWorkspace(int numEvents, int numPixels, int numBins) {
   // --------- Load the instrument -----------
   const std::string filename = FileFinder::Instance().getFullPath(
       "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
-  InstrumentDefinitionParser parser;
-  parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
+  InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename));
   auto instrument = parser.parseXML(NULL);
   retVal->populateInstrumentParameters();
   retVal->setInstrument(instrument);