diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt
index 1380797cf9153864b405b01c92cef538858b4fdb..1a8ece42503b648102159f60ac84b77ebfd39880 100644
--- a/Code/Mantid/Framework/API/CMakeLists.txt
+++ b/Code/Mantid/Framework/API/CMakeLists.txt
@@ -106,6 +106,7 @@ set ( SRC_FILES
 	src/PropertyManagerDataService.cpp
 	src/PropertyNexus.cpp
 	src/RefAxis.cpp
+	src/RemoteJobManagerFactory.cpp
 	src/Run.cpp
 	src/Sample.cpp
 	src/SampleEnvironment.cpp
@@ -271,6 +272,7 @@ set ( INC_FILES
 	inc/MantidAPI/PropertyManagerDataService.h
 	inc/MantidAPI/PropertyNexus.h
 	inc/MantidAPI/RefAxis.h
+	inc/MantidAPI/RemoteJobManagerFactory.h
 	inc/MantidAPI/Run.h
 	inc/MantidAPI/Sample.h
 	inc/MantidAPI/SampleEnvironment.h
@@ -367,6 +369,7 @@ set ( TEST_FILES
 	ProjectionTest.h
 	PropertyManagerDataServiceTest.h
 	PropertyNexusTest.h
+	RemoteJobManagerFactoryTest.h
 	RunTest.h
 	SampleEnvironmentTest.h
 	SampleShapeValidatorTest.h
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h
index 2035e271f89e416a4a0d1dc6c76fc26cc7da995e..eb6d2ef97bd9dc3a643f69368c4be2be348d5757 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h
@@ -137,7 +137,7 @@ public:
    * @param numNodes number of nodes to use (optional and dependent on
    * implementation and compute resource)
    *
-   * @parm coresPerNode number of cores to use in each node (optional
+   * @param coresPerNode number of cores to use in each node (optional
    * and dependent on implemenation and compute resource)
    *
    * @return jobID string for the job started (if successful).
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..34fa04176d18cd43e191eb4bf346bdbfdb02b66e
--- /dev/null
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h
@@ -0,0 +1,124 @@
+#ifndef MANTID_API_REMOTEJOBMANAGERFACTORY_H_
+#define MANTID_API_REMOTEJOBMANAGERFACTORY_H_
+
+#include "MantidAPI/DllConfig.h"
+#include "MantidAPI/IRemoteJobManager.h"
+#include "MantidKernel/DynamicFactory.h"
+#include "MantidKernel/SingletonHolder.h"
+
+namespace Mantid {
+namespace API {
+/**
+The RemoteJobManagerFactory handles the creation of remote job
+managers specialised for different types of compute resources (for
+different underlying job schedulers, web services, front-ends,
+etc.). Through the create method of this class a shared pointer to a
+remote job manager object can be obtained for a particular compute
+resource.
+
+The remote job managers built by this factory know how to start and
+stop jobs, upload/download files, etc. for the compute resource
+specified when creating the job manager (as long as the compute
+resource is found for the current facility in the facilities
+definition file).
+
+Remote job manager classes must be registered/subscribe using the
+macro DECLARE_REMOTEJOBMANAGER (the same way you use DECLARE_ALGORITHM
+for algorithms and remote algorithms).
+
+As the algorithm, workspace and other factories in Mantid, this
+factory is implemented as a singleton class. Typical usages:
+
+Mantid::API::IRemoteJob|Manager_sptr jobManager =
+    Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi");
+
+Mantid::API::IRemoteJob|Manager_sptr jobManager =
+    Mantid::API::RemoteJobManagerFactory::Instance().create("SCARF@STFC");
+
+
+Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+National Laboratory & European Spallation Source
+
+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 MANTID_API_DLL RemoteJobManagerFactoryImpl
+    : public Kernel::DynamicFactory<IRemoteJobManager> {
+public:
+  /// Create a remote job manager that will know how to use the
+  /// underlying mechanism that suits the compute resource passed
+  IRemoteJobManager_sptr create(const std::string &computeResourceName) const;
+
+  /// alternative (lower level) create where the specific type of
+  /// manager and base URL are directly given
+  IRemoteJobManager_sptr create(const std::string baseURL,
+                                const std::string jobManagerType) const;
+
+private:
+  /// So that the singleton can be created (cons/destructor are private)
+  friend struct Mantid::Kernel::CreateUsingNew<RemoteJobManagerFactoryImpl>;
+
+  /// Private Constructor for singleton class
+  RemoteJobManagerFactoryImpl();
+  /// Disallow copy construction
+  RemoteJobManagerFactoryImpl(const RemoteJobManagerFactoryImpl &);
+  /// Disallow assignment
+  RemoteJobManagerFactoryImpl &operator=(const RemoteJobManagerFactoryImpl &);
+
+  /// Private Destructor
+  virtual ~RemoteJobManagerFactoryImpl();
+
+  // Unhide the inherited create method but make it private
+  using Kernel::DynamicFactory<IRemoteJobManager>::create;
+};
+
+/// Forward declaration of a specialisation of SingletonHolder for
+/// RemoteJobManagerFactoryImpl (needed for dllexport) and a typedef for it.
+#ifdef _WIN32
+// this breaks new namespace declaraion rules; need to find a better fix
+template class MANTID_API_DLL
+    Mantid::Kernel::SingletonHolder<RemoteJobManagerFactoryImpl>;
+#endif /* _WIN32 */
+
+// The factory is just a specialisation of SingletonHolder
+typedef MANTID_API_DLL Mantid::Kernel::SingletonHolder<
+    RemoteJobManagerFactoryImpl> RemoteJobManagerFactory;
+
+} // namespace API
+} // namespace Mantid
+
+/* Macro to register (remote job manager) classes into the factory. As
+ * with the equivalent macros of the workspace factory or the
+ * algorithm factory, this creates a global object in an anonymous
+ * namespace. The object itself does nothing, but the comma operator
+ * is used in the call to its constructor to effect a call to the
+ * factory's subscribe method.
+ *
+ * You need to use this in every remote job manager. For example:
+ * DECLARE_REMOTEJOBMANAGER(MantidWebServiceAPI)
+ * DECLARE_REMOTEJOBMANAGER(SCARFLSFJobManager)
+ */
+#define DECLARE_REMOTEJOBMANAGER(classname)                                    \
+  namespace {                                                                  \
+  Mantid::Kernel::RegistrationHelper register_ws_##classname(                  \
+      ((Mantid::API::RemoteJobManagerFactory::Instance().subscribe<classname>( \
+           #classname)),                                                       \
+       0));                                                                    \
+  }
+
+#endif // MANTID_API_REMOTEJOBMANAGERFACTORY_H_
diff --git a/Code/Mantid/Framework/API/src/RemoteJobManagerFactory.cpp b/Code/Mantid/Framework/API/src/RemoteJobManagerFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..744123627a144265173445af3f7b11cd96c3c40a
--- /dev/null
+++ b/Code/Mantid/Framework/API/src/RemoteJobManagerFactory.cpp
@@ -0,0 +1,88 @@
+#include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
+#include "MantidKernel/FacilityInfo.h"
+#include "MantidKernel/Logger.h"
+
+namespace Mantid {
+namespace API {
+namespace {
+/// static logger object
+Kernel::Logger g_log("RemoteJobManagerFactory");
+}
+
+/// Private constructor, singleton class
+RemoteJobManagerFactoryImpl::RemoteJobManagerFactoryImpl()
+    : Mantid::Kernel::DynamicFactory<IRemoteJobManager>() {
+  g_log.debug() << "RemoteJobManager factory created." << std::endl;
+}
+
+/**
+ * Private destructor, prevent client code from using this.
+ */
+RemoteJobManagerFactoryImpl::~RemoteJobManagerFactoryImpl() {}
+
+/**
+ * Create a remote algorithm with the underlying mechanism that suits
+ * the compute resource passed.
+ *
+ * @param computeResourceName Name of a (remote) compute resource
+ *
+ * @throw std::invalid_argument If no resource is found by the name
+ * given (compute resources are looked up in the facilities definition
+ * (XML) file for the current facility.
+ */
+IRemoteJobManager_sptr RemoteJobManagerFactoryImpl::create(
+    const std::string &computeResourceName) const {
+  IRemoteJobManager_sptr jm;
+
+  if (computeResourceName.empty())
+    return jm;
+
+  Mantid::Kernel::ComputeResourceInfo cr =
+      Mantid::Kernel::ConfigService::Instance().getFacility().computeResource(
+          computeResourceName);
+
+  // this is the default. It could be "MantidWebServiceAPI", "LSF",
+  // "SCARFLSF", "MOAB", etc.
+  std::string type = "MantidWebServiceAPIJobManager";
+  std::string fdfType = cr.remoteJobManagerType();
+  if (!fdfType.empty())
+    type = fdfType;
+  return create(cr.baseURL(), type);
+}
+
+/**
+ * Lower level create method that makes a remote algorithm given a
+ * base URL and the type of remote job manager.
+ *
+ * @param baseURL URL where the resource is accessible
+ *
+ * @param jobManagerType Type/class that can handle this remote
+ * compute resource (string names as used in the facilities definition
+ * file, for example: MantidWebServiceAPIJobManager).
+ *
+ * @throw std::invalid_argument If there is an issue with the URL or
+ * the type (for example the type is not recognized).
+ */
+Mantid::API::IRemoteJobManager_sptr
+RemoteJobManagerFactoryImpl::create(const std::string baseURL,
+                                    const std::string jobManagerType) const {
+  Mantid::API::IRemoteJobManager_sptr jm;
+
+  // use the inherited/generic create method
+  try {
+    jm = this->create(jobManagerType);
+  } catch (Kernel::Exception::NotFoundError &e) {
+    throw Kernel::Exception::NotFoundError(
+        "RemoteJobManagerFactory: failed to create a remote job manager of "
+        "type (class) '" +
+            jobManagerType + "' with base URL " + baseURL +
+            ". Error description: " + e.what(),
+        jobManagerType);
+  }
+
+  return jm;
+}
+
+} // namespace API
+} // Namespace Mantid
diff --git a/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h b/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fa693d8893d48bac960394befb79f17d06bf71b
--- /dev/null
+++ b/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h
@@ -0,0 +1,149 @@
+#ifndef REMOTEJOBMANAGERFACTORYTEST_H_
+#define REMOTEJOBMANAGERFACTORYTEST_H_
+
+#include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
+#include "MantidKernel/FacilityInfo.h"
+
+using namespace Mantid::API;
+
+// Just a minimal implementation of IRemoteJobManager, sufficient for the
+// factory
+class TestJM : public IRemoteJobManager {
+public:
+  virtual void authenticate(const std::string &username,
+                            const std::string &password) {
+    UNUSED_ARG(username);
+    UNUSED_ARG(password);
+  }
+
+  virtual std::string
+  submitRemoteJob(const std::string &transactionID, const std::string &runnable,
+                  const std::string &param, const std::string &taskName = "",
+                  const int numNodes = 1, const int coresPerNode = 1) {
+    UNUSED_ARG(transactionID);
+    UNUSED_ARG(runnable);
+    UNUSED_ARG(param);
+    UNUSED_ARG(taskName);
+    UNUSED_ARG(numNodes);
+    UNUSED_ARG(coresPerNode);
+    return "";
+  }
+
+  virtual void downloadRemoteFile(const std::string &transactionID,
+                                  const std::string &remoteFileName,
+                                  const std::string &localFileName) {
+    UNUSED_ARG(transactionID);
+    UNUSED_ARG(remoteFileName);
+    UNUSED_ARG(localFileName);
+  }
+
+  virtual std::vector<RemoteJobInfo> queryAllRemoteJobs() const {
+    return std::vector<RemoteJobInfo>();
+  }
+
+  virtual std::vector<std::string>
+  queryRemoteFile(const std::string &transactionID) const {
+    UNUSED_ARG(transactionID);
+    return std::vector<std::string>();
+  }
+
+  virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) const {
+    UNUSED_ARG(jobID);
+    return RemoteJobInfo();
+  }
+
+  virtual std::string startRemoteTransaction() { return ""; }
+
+  virtual void stopRemoteTransaction(const std::string &transactionID) {
+    UNUSED_ARG(transactionID);
+  }
+
+  virtual void abortRemoteJob(const std::string &jobID) { UNUSED_ARG(jobID); }
+
+  virtual void uploadRemoteFile(const std::string &transactionID,
+                                const std::string &remoteFileName,
+                                const std::string &localFileName) {
+    UNUSED_ARG(transactionID);
+    UNUSED_ARG(remoteFileName);
+    UNUSED_ARG(localFileName);
+  }
+};
+
+class RemoteJobManagerFactoryTest : public CxxTest::TestSuite {
+public:
+  void test_unsubscribed() {
+
+    IRemoteJobManager_sptr jobManager;
+    TS_ASSERT_THROWS(
+        jobManager = RemoteJobManagerFactory::Instance().create("Inexistent"),
+        std::runtime_error);
+
+    TS_ASSERT_THROWS(jobManager =
+                         RemoteJobManagerFactory::Instance().create("TestJM"),
+                     std::runtime_error);
+  }
+
+  // minimal positive test
+  void test_createTestJM() {
+    RemoteJobManagerFactory::Instance().subscribe<TestJM>("TestJM");
+    // throws not found cause it is not in facilities.xml, but otherwise fine
+    TS_ASSERT_THROWS(
+        jm = Mantid::API::RemoteJobManagerFactory::Instance().create("TestJM"),
+        Mantid::Kernel::Exception::NotFoundError);
+  }
+
+  // this must fail, resource not found in the current facility
+  void test_createAlienResource() {
+    // save facility, do this before any changes
+    const Mantid::Kernel::FacilityInfo &prevFac =
+        Mantid::Kernel::ConfigService::Instance().getFacility();
+
+    Mantid::Kernel::ConfigService::Instance().setFacility("ISIS");
+    TS_ASSERT_THROWS(
+        jm = Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"),
+        Mantid::Kernel::Exception::NotFoundError);
+
+    Mantid::Kernel::ConfigService::Instance().setFacility("SNS");
+    TS_ASSERT_THROWS(
+        Mantid::API::IRemoteJobManager_sptr jobManager =
+            Mantid::API::RemoteJobManagerFactory::Instance().create(
+                "SCARF@STFC"),
+        Mantid::Kernel::Exception::NotFoundError);
+
+    // restore facility, always do this at the end
+    Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name());
+  }
+
+  // a simple positive test
+  void test_createRemoteManagers() {
+    // save facility, do this before any changes
+    const Mantid::Kernel::FacilityInfo &prevFac =
+        Mantid::Kernel::ConfigService::Instance().getFacility();
+
+    Mantid::Kernel::ConfigService::Instance().setFacility("SNS");
+    // TODO: at the moment these two create throw a NotFoundError
+    // because the RemoteJobManager classes are missing and have not
+    // done a DECLARE_REMOTEJOBMANAGER. Change this test when that is
+    // done (ticket #11126 etc.)
+    TS_ASSERT_THROWS(
+        Mantid::API::IRemoteJobManager_sptr jobManager =
+            Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"),
+        Mantid::Kernel::Exception::NotFoundError);
+
+    Mantid::Kernel::ConfigService::Instance().setFacility("ISIS");
+    TS_ASSERT_THROWS(
+        Mantid::API::IRemoteJobManager_sptr jobManager =
+            Mantid::API::RemoteJobManagerFactory::Instance().create(
+                "SCARF@STFC"),
+        Mantid::Kernel::Exception::NotFoundError);
+
+    // restore facility, always do this at the end
+    Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name());
+  }
+
+private:
+  Mantid::API::IRemoteJobManager_sptr jm;
+};
+
+#endif /* REMOTEJOBMANAGERFACTORYTEST_H_ */
diff --git a/Code/Mantid/Framework/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt
index 887bba0271579674dd2aff16e4107f268ffe51ac..07d6f10edbb7529ecaf9e15a95a7d554e653a20e 100644
--- a/Code/Mantid/Framework/Kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt
@@ -8,6 +8,7 @@ set ( SRC_FILES
 	src/CPUTimer.cpp
 	src/CatalogInfo.cpp
 	src/CompositeValidator.cpp
+	src/ComputeResourceInfo.cpp
 	src/ConfigService.cpp
 	src/ChecksumHelper.cpp
 	src/DataItem.cpp
@@ -128,6 +129,7 @@ set ( INC_FILES
 	inc/MantidKernel/Cache.h
 	inc/MantidKernel/CatalogInfo.h
 	inc/MantidKernel/CompositeValidator.h
+	inc/MantidKernel/ComputeResourceInfo.h
 	inc/MantidKernel/ConfigService.h
 	inc/MantidKernel/ChecksumHelper.h
 	inc/MantidKernel/DataItem.h
@@ -264,6 +266,7 @@ set ( TEST_FILES
 	CacheTest.h
 	CatalogInfoTest.h
 	CompositeValidatorTest.h
+	ComputeResourceInfoTest.h
 	ConfigServiceTest.h
 	ChecksumHelperTest.h
 	DataServiceTest.h
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ComputeResourceInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ComputeResourceInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..db27c93ed68e8bcaaf1e7434fc1dca88b3bd1483
--- /dev/null
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ComputeResourceInfo.h
@@ -0,0 +1,82 @@
+#ifndef MANTID_KERNEL_COMPUTERESOURCEINFO_H_
+#define MANTID_KERNEL_COMPUTERESOURCEINFO_H_
+
+#include <string>
+
+#include "MantidKernel/DllConfig.h"
+
+namespace Poco {
+namespace XML {
+class Element;
+}
+}
+
+namespace Mantid {
+namespace Kernel {
+
+class FacilityInfo;
+
+/**
+ComputeResourceInfo holds information about / represents a compute
+resource present in a facility.
+
+At the moment (remote) compute resources are defined by their name,
+the URL they can be accessed at, and the type of remote job manager
+that they use/require (Mantid web service API, LSF, etc.).
+
+Copyright &copy; 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+National Laboratory & European Spallation Source
+
+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 MANTID_KERNEL_DLL ComputeResourceInfo {
+public:
+  /// constructor - from facility info and the element for this resource
+  ComputeResourceInfo(const FacilityInfo *f, const Poco::XML::Element *elem);
+
+  /// Equality operator
+  bool operator==(const ComputeResourceInfo &rhs) const;
+
+  /// Name of the compute resource
+  std::string name() const;
+
+  /// Base URL the compute resource
+  std::string baseURL() const ;
+
+  /// Type/class of remote job manager required to handle this resource
+  std::string remoteJobManagerType() const;
+
+  /// The facility where this compute resource is avalable
+  const FacilityInfo &facility() const;
+
+private:
+  const FacilityInfo *m_facility; ///< Facility
+  std::string m_name;             ///< Cluster/resource name
+  std::string m_baseURL;          ///< access URL (first authentication, etc.)
+  std::string m_managerType;      ///< specific remote job manager class
+};
+
+/// output to stream operator for compute resource info objects
+MANTID_KERNEL_DLL std::ostream &
+operator<<(std::ostream &buffer, const  ComputeResourceInfo &cr);
+
+} // namespace Kernel
+} // namespace Mantid
+
+#endif /* MANTID_KERNEL_COMPUTERESOURCEINFO_H_ */
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
index 2d5976003305abfd697f2a52eb653a3accad0891..20c5d7172471f2ceb0367e185e410cbadf8a26f3 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
@@ -6,6 +6,7 @@
 //----------------------------------------------------------------------
 #include "MantidKernel/DllConfig.h"
 #include "MantidKernel/CatalogInfo.h"
+#include "MantidKernel/ComputeResourceInfo.h"
 #include "MantidKernel/InstrumentInfo.h"
 #include "MantidKernel/RemoteJobManager.h"
 #ifndef Q_MOC_RUN
@@ -80,7 +81,13 @@ public:
   std::vector<InstrumentInfo> instruments(const std::string &tech) const;
   /// Returns instruments with given name
   const InstrumentInfo &instrument(std::string iName = "") const;
-  /// Returns a vector of the available compute resources
+
+  /// Returns a vector of available compute resources
+  std::vector<ComputeResourceInfo> computeResInfos() const;
+  /// Returns a compute resource identified by name
+  const ComputeResourceInfo &computeResource(const std::string &name) const;
+
+  /// Returns a vector of the names of the available compute resources
   std::vector<std::string> computeResources() const;
   /// Returns the RemoteJobManager for the named compute resource
   boost::shared_ptr<RemoteJobManager>
@@ -113,12 +120,18 @@ private:
   std::vector<InstrumentInfo>
       m_instruments;          ///< list of instruments of this facility
   std::string m_liveListener; ///< name of the default live listener
+
+  std::vector<ComputeResourceInfo> m_computeResInfos; ///< (remote) compute
+  /// resources available in
+  /// this facility
+
+  // TODO: remove RemoteJobManager form here (trac ticket #11373)
   typedef std::map<std::string, boost::shared_ptr<RemoteJobManager>>
       ComputeResourcesMap;
   ComputeResourcesMap m_computeResources; ///< list of compute resources
                                           ///(clusters, etc...) available at
-  /// this facility
-  // (Sorted by their names)
+                                          /// this facility
+                                          // (Sorted by their names)
 };
 
 } // namespace Kernel
diff --git a/Code/Mantid/Framework/Kernel/src/ComputeResourceInfo.cpp b/Code/Mantid/Framework/Kernel/src/ComputeResourceInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6669c1f228310ec4bcba078f3f79a072f96cad77
--- /dev/null
+++ b/Code/Mantid/Framework/Kernel/src/ComputeResourceInfo.cpp
@@ -0,0 +1,115 @@
+#include "MantidKernel/ComputeResourceInfo.h"
+#include "MantidKernel/FacilityInfo.h"
+#include "MantidKernel/Logger.h"
+
+#include <Poco/DOM/AutoPtr.h>
+#include <Poco/DOM/Element.h>
+#include <Poco/DOM/NodeList.h>
+#include <Poco/DOM/Text.h>
+
+namespace Mantid {
+namespace Kernel {
+namespace {
+// static logger object
+Logger g_log("ComputeResourceInfo");
+}
+
+/**
+ * Construct a compute resource from information found in a facilities
+ * definition file.
+ *
+ * @param fac Facility where this (remote) compute resource is available
+ * @param elem A (Poco::XML::) Element to read the data from
+ *
+ * @throw std::runtime_error if name or required attributes are not
+ * found
+ */
+ComputeResourceInfo::ComputeResourceInfo(const FacilityInfo *fac,
+                                         const Poco::XML::Element *elem)
+    : m_facility(fac) {
+
+  m_name = elem->getAttribute("name");
+  if (m_name.empty()) {
+    std::string elemStr = "";
+    if (elem)
+      elemStr = elem->innerText();
+    throw std::runtime_error(
+        "The compute resource name is not defined, at element: " + elemStr);
+  }
+
+  // default: Mantid web service API:
+  // http://www.mantidproject.org/Remote_Job_Submission_API
+  m_managerType = "MantidWebServiceAPIJobManager";
+  std::string type = elem->getAttribute("JobManagerType");
+  if (!type.empty()) {
+    m_managerType = type;
+  }
+
+  const std::string baseTag = "baseURL";
+  Poco::AutoPtr<Poco::XML::NodeList> nl = elem->getElementsByTagName(baseTag);
+  if (!nl || nl->length() != 1 || !nl->item(0) || !nl->item(0)->childNodes()) {
+    g_log.error("Failed to get base URL for remote compute resource '" +
+                m_name + "'");
+    throw std::runtime_error("Remote compute resources must have exactly one "
+                             "baseURL tag. It was not found for the resource "
+                             "'" +
+                             m_name + "'");
+  } else {
+    nl = nl->item(0)->childNodes();
+    if (nl->length() > 0) {
+      Poco::XML::Text *txt = dynamic_cast<Poco::XML::Text *>(nl->item(0));
+      if (txt) {
+        m_baseURL = txt->getData();
+      } else {
+        g_log.error("Failed to get base URL for remote compute resource '" +
+                    m_name + "'. The " + baseTag + " tag seems empty!");
+        throw std::runtime_error(
+            "Remote compute resources must have exactly one "
+            "baseURL tag containing a URL string. A tag was found for the "
+            "resource "
+            "'" +
+            m_name + "', but it seems empty!");
+      }
+    }
+  }
+}
+
+/**
+* Equality operator. Two different resources cannot have the same name
+*
+* @param rhs object to compare this with
+*
+* @return True if the objects (names) are equal
+*/
+bool ComputeResourceInfo::operator==(const ComputeResourceInfo &rhs) const {
+  return (this->name() == rhs.name());
+}
+
+std::string ComputeResourceInfo::name() const { return m_name; }
+
+std::string ComputeResourceInfo::baseURL() const { return m_baseURL; }
+
+std::string ComputeResourceInfo::remoteJobManagerType() const {
+  return m_managerType;
+}
+
+const FacilityInfo &ComputeResourceInfo::facility() const {
+  return *m_facility;
+}
+
+/**
+ * Prints the instrument name into an output stream
+ *
+ * @param buffer an output stream being written to
+ * @param cr a ComputeResourceInfo object to print
+ *
+ * @return reference to the output stream being written to
+ */
+std::ostream &operator<<(std::ostream &buffer, const ComputeResourceInfo &cr) {
+  buffer << "'" + cr.name() + "', at '" + cr.baseURL() + "', of type '" +
+                cr.remoteJobManagerType() + "'";
+  return buffer;
+}
+
+} // namespace Kernel
+} // namespace Mantid
diff --git a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
index 7346c52307c62fe54291b6032c56f89309ff623a..dad72eec268239254af844eda8d20fd5d268cf1c 100644
--- a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
+++ b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
@@ -154,10 +154,24 @@ void FacilityInfo::fillComputeResources(const Poco::XML::Element *elem) {
   for (unsigned long i = 0; i < n; i++) {
     Poco::XML::Element *elem =
         dynamic_cast<Poco::XML::Element *>(pNL_compute->item(i));
-    std::string name = elem->getAttribute("name");
 
-    m_computeResources.insert(std::make_pair(
-        name, boost::shared_ptr<RemoteJobManager>(new RemoteJobManager(elem))));
+    if (elem) {
+      try {
+        ComputeResourceInfo cr(this, elem);
+        m_computeResInfos.push_back(cr);
+
+        g_log.debug() << "Compute resource found: " << cr << std::endl;
+      } catch (...) { // next resource...
+      }
+
+      std::string name = elem->getAttribute("name");
+      // TODO: this is a bit of duplicate effort at the moment, until
+      // RemoteJobManager goes away from here (then this would be
+      // removed), see header for details.
+      m_computeResources.insert(std::make_pair(
+          name,
+          boost::shared_ptr<RemoteJobManager>(new RemoteJobManager(elem))));
+    }
   }
 }
 
@@ -202,14 +216,22 @@ const InstrumentInfo &FacilityInfo::instrument(std::string iName) const {
 }
 
 /**
-  * Returns a list of instruments of given technique
-  * @param tech :: Technique name
-  * @return a list of instrument information objects
+  * Get the vector of available compute resources
+  * @return vector of ComputeResourInfo for the current facility
   */
+std::vector<ComputeResourceInfo> FacilityInfo::computeResInfos() const {
+  return m_computeResInfos;
+}
+
+/**
+* Returns a list of instruments of given technique
+* @param tech :: Technique name
+* @return a list of instrument information objects
+*/
 std::vector<InstrumentInfo>
 FacilityInfo::instruments(const std::string &tech) const {
   std::vector<InstrumentInfo> out;
-  std::vector<InstrumentInfo>::const_iterator it = m_instruments.begin();
+  auto it = m_instruments.begin();
   for (; it != m_instruments.end(); ++it) {
     if (it->techniques().count(tech)) {
       out.push_back(*it);
@@ -219,7 +241,7 @@ FacilityInfo::instruments(const std::string &tech) const {
 }
 
 /**
-  * Returns a vector of the available compute resources
+  * Returns a vector of the names of the available compute resources
   * @return vector of strings of the compute resource names
   */
 std::vector<std::string> FacilityInfo::computeResources() const {
@@ -233,6 +255,39 @@ std::vector<std::string> FacilityInfo::computeResources() const {
   return names;
 }
 
+/**
+ * Get a compute resource by name
+ *
+ * @param name Name as specified in the facilities definition file
+ *
+ * @return the named compute resource
+ *
+ * @throws NotFoundError if the resource is not found/available.
+ */
+const ComputeResourceInfo &
+FacilityInfo::computeResource(const std::string &name) const {
+  if (name.empty()) {
+    g_log.debug("Cannot find a compute resource without name "
+                "(empty).");
+    throw Exception::NotFoundError("FacilityInfo, empty compute resource name",
+                                   name);
+  }
+
+  auto it = m_computeResInfos.begin();
+  for (; it != m_computeResInfos.end(); ++it) {
+    if (it->name() == name) {
+      g_log.debug() << "Compute resource '" << name << "' found at facility "
+                    << this->name() << "." << std::endl;
+      return *it;
+    }
+  }
+
+  g_log.debug() << "Could not find requested compute resource: " << name
+                << " in facility " << this->name() << "." << std::endl;
+  throw Exception::NotFoundError("FacilityInfo, missing compute resource",
+                                 name);
+}
+
 /**
   * Returns a reference to the requested remote job manager
   * @param name :: Name of the cluster we want to submit jobs to
diff --git a/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp b/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp
index 60e610a0169609d84eb875d85918293bad4963b9..9b0f8bc57aced45671c461b6f8666ddd10a9832c 100644
--- a/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp
+++ b/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp
@@ -7,10 +7,10 @@
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/Strings.h"
 
+#include <Poco/DOM/AutoPtr.h>
 #include <Poco/DOM/Element.h>
 #include <Poco/DOM/NodeList.h>
 #include <Poco/DOM/Text.h>
-#include <Poco/DOM/AutoPtr.h>
 
 #include <boost/lexical_cast.hpp>
 
diff --git a/Code/Mantid/Framework/Kernel/test/ComputeResourceInfoTest.h b/Code/Mantid/Framework/Kernel/test/ComputeResourceInfoTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..213a98ed2098662b0748101000aaaa992a0a8cc0
--- /dev/null
+++ b/Code/Mantid/Framework/Kernel/test/ComputeResourceInfoTest.h
@@ -0,0 +1,269 @@
+#ifndef COMPUTERESOURCEINFOTEST_H_
+#define COMPUTERESOURCEINFOTEST_H_
+
+#include "MantidKernel/Exception.h"
+#include "MantidKernel/FacilityInfo.h"
+
+#include <Poco/DOM/AutoPtr.h>
+#include <Poco/DOM/Document.h>
+#include <Poco/DOM/DOMParser.h>
+#include <Poco/XML/XMLException.h>
+
+using namespace Mantid::Kernel;
+
+class ComputeResourceInfoTest : public CxxTest::TestSuite {
+public:
+  void test_allMissing() {
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS_NOTHING(fac =
+                                 createCRInfoInMinimalFacility(simpleInstStr));
+    TS_ASSERT(fac);
+    std::vector<ComputeResourceInfo> cri;
+    TS_ASSERT_THROWS_NOTHING(cri = fac->computeResInfos());
+    TS_ASSERT_EQUALS(cri.size(), 0);
+
+    delete fac;
+    fac = NULL;
+    TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(
+                         "<computeResource fooAtt=\"barVal\"/>"),
+                     std::runtime_error);
+    TS_ASSERT(!fac);
+    delete fac;
+  }
+
+  void test_noURLTag() {
+    const std::string crTxt = "<computeResource name=\"foo\">"
+                              "<u>" +
+                              fermiURL + "</u>"
+                                         "</computeResource>";
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(crTxt),
+                     std::runtime_error);
+    TS_ASSERT(!fac);
+    delete fac;
+  }
+
+  void test_wrongXML() {
+    const std::string crTxt = "<computeResource name=\"foo\">"
+                              "<u_foo>" +
+                              fermiURL + "</u_bar>"
+                                         "</compResource>";
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(crTxt),
+                     Poco::XML::XMLException);
+    TS_ASSERT(!fac);
+    delete fac;
+  }
+
+  void test_normalFermi() {
+    const std::string fermi = "<computeResource name=\"" + fermiName +
+                              "\">"
+                              "<baseURL>" +
+                              fermiURL + "</baseURL>"
+                                         "</computeResource>";
+
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS_NOTHING(fac = createCRInfoInMinimalFacility(fermi));
+    TS_ASSERT(fac);
+    TS_ASSERT_EQUALS(fac->name(), this->testFacilityName);
+
+    std::vector<ComputeResourceInfo> cri;
+    TS_ASSERT_THROWS_NOTHING(cri = fac->computeResInfos());
+    TS_ASSERT_EQUALS(cri.size(), 1);
+
+    ComputeResourceInfo cr = fac->computeResInfos().front();
+    TS_ASSERT_THROWS(ComputeResourceInfo fail = fac->computeResource(scarfName),
+                     Mantid::Kernel::Exception::NotFoundError);
+    ComputeResourceInfo cr2 = fac->computeResource(fermiName);
+    TS_ASSERT_EQUALS(cr, cr2);
+    TS_ASSERT_EQUALS(cr, cri.front());
+    TS_ASSERT_EQUALS(cr2, cri.front());
+    TS_ASSERT_EQUALS(cr.name(), fermiName);
+    TS_ASSERT_EQUALS(cr2.name(), fermiName);
+    TS_ASSERT_EQUALS(cr.baseURL(), fermiURL);
+    TS_ASSERT_EQUALS(cr2.baseURL(), fermiURL);
+    TS_ASSERT_EQUALS(cr.remoteJobManagerType(), defaultType);
+    TS_ASSERT_EQUALS(cr2.remoteJobManagerType(), defaultType);
+    TS_ASSERT_EQUALS(cr.facility().name(), fac->name());
+    TS_ASSERT_EQUALS(cr2.facility().name(), fac->name());
+  }
+
+  void test_brokenFermi() {
+    // wrong 'baseURL' tag
+    const std::string fermi = "<computeResource name=\"" + fermiName + "\">"
+                                                                       "<URL>" +
+                              fermiURL + "</URL>"
+                                         "</computeResource>";
+
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(fermi),
+                     std::runtime_error);
+
+    TS_ASSERT(!fac);
+    delete fac;
+  }
+
+  void test_normalSCARF() {
+    const std::string scarf = "<computeResource name=\"" + scarfName +
+                              "\" JobManagerType=\"" + scarfType + "\">"
+                                                                   "<baseURL>" +
+                              scarfURL + "</baseURL>"
+                                         "</computeResource>";
+
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS_NOTHING(fac = createCRInfoInMinimalFacility(scarf));
+    TS_ASSERT(fac);
+    TS_ASSERT_EQUALS(fac->name(), this->testFacilityName);
+    std::vector<ComputeResourceInfo> cri;
+    TS_ASSERT_THROWS_NOTHING(cri = fac->computeResInfos());
+    TS_ASSERT_EQUALS(cri.size(), 1);
+
+    ComputeResourceInfo cr = fac->computeResInfos().front();
+    TS_ASSERT_THROWS(ComputeResourceInfo fail = fac->computeResource("inexistent!"),
+                     Mantid::Kernel::Exception::NotFoundError);
+    ComputeResourceInfo cr2 = fac->computeResource(scarfName);
+    TS_ASSERT_EQUALS(cr, cr2);
+    TS_ASSERT_EQUALS(cri.front(), cr);
+    TS_ASSERT_EQUALS(cri.front(), cr2);
+    TS_ASSERT_EQUALS(scarfName, cr.name());
+    TS_ASSERT_EQUALS(scarfName, cr2.name());
+    TS_ASSERT_EQUALS(scarfURL, cr.baseURL());
+    TS_ASSERT_EQUALS(scarfURL, cr2.baseURL());
+    TS_ASSERT_EQUALS(scarfType, cr.remoteJobManagerType());
+    TS_ASSERT_EQUALS(scarfType, cr2.remoteJobManagerType());
+    TS_ASSERT_EQUALS(fac->name(), cr.facility().name());
+    TS_ASSERT_EQUALS(fac->name(), cr2.facility().name());
+    delete fac;
+  }
+
+  void test_brokenSCARF() {
+    const std::string type = "SCARFLSFJobManager";
+    const std::string err = "<computeResource foo=\"" + scarfName +
+                            "\" JobManagerType=\"" + type + "\">"
+                                                            "<URL>" +
+                            scarfURL + "</URL>"
+                                       "</computeResource>";
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(err),
+                     std::runtime_error);
+    TS_ASSERT(!fac);
+    delete fac;
+  }
+
+  void test_equals() {
+    const std::string otherName = "other";
+    const std::string otherURL = "www.example.com/foo/baz";
+    const std::string thirdName = "third";
+    const std::string rep = "<computeResource name=\"" + fermiName +
+                            "\">"
+                            "<baseURL>" +
+                            fermiURL + "</baseURL>"
+                                       "</computeResource>"
+
+                                       "<computeResource name=\"" +
+                            otherName + "\">"
+                                        "<baseURL>" +
+                            otherURL + "</baseURL>"
+                                       "</computeResource>"
+
+                                       "<computeResource name=\"" +
+                            thirdName + "\">"
+                                        "<baseURL>" +
+                            fermiURL + "</baseURL>"
+                                       "</computeResource>"
+
+                                       "<computeResource name=\"" +
+                            fermiName + "\">"
+                                        "<baseURL>" +
+                            fermiURL + "</baseURL>"
+                                       "</computeResource>";
+
+    FacilityInfo *fac = NULL;
+    TS_ASSERT_THROWS_NOTHING(fac = createCRInfoInMinimalFacility(rep));
+    TS_ASSERT(fac);
+    TS_ASSERT_EQUALS(fac->computeResources().size(), 3);
+    TS_ASSERT_EQUALS(fac->computeResInfos().size(), 4);
+
+    // compare names
+    TS_ASSERT(fac->computeResources()[0] == fac->computeResources()[0]);
+    TS_ASSERT(!(fac->computeResources()[0] == fac->computeResources()[1]));
+    TS_ASSERT(!(fac->computeResources()[0] == fac->computeResources()[2]));
+    TS_ASSERT(!(fac->computeResources()[1] == fac->computeResources()[2]));
+
+    // compare full comp resource info
+    TS_ASSERT(fac->computeResInfos()[0] == fac->computeResInfos()[0]);
+    TS_ASSERT(!(fac->computeResInfos()[0] == fac->computeResInfos()[1]));
+    TS_ASSERT(!(fac->computeResInfos()[0] == fac->computeResInfos()[2]));
+    TS_ASSERT(!(fac->computeResInfos()[1] == fac->computeResInfos()[2]));
+    TS_ASSERT(!(fac->computeResInfos()[2] == fac->computeResInfos()[3]));
+    TS_ASSERT(fac->computeResInfos()[0] == fac->computeResInfos()[3]);
+
+    // compare comp resource info retrieved by names
+    TS_ASSERT(
+        !(fac->computeResource(fermiName) == fac->computeResource(otherName)));
+    TS_ASSERT(
+        !(fac->computeResource(fermiName) == fac->computeResource(thirdName)));
+    TS_ASSERT(
+        !(fac->computeResource(otherName) == fac->computeResource(thirdName)));
+    delete fac;
+  }
+
+private:
+  /// make a minimal facilities file/xml string includin the compute resource
+  /// passed
+  FacilityInfo *createCRInfoInMinimalFacility(const std::string &crStr) {
+    const std::string xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                               "<facilities>"
+                               "  <facility name=\"" +
+                               testFacilityName +
+                               "\" FileExtensions=\".xyz\">" + simpleInstStr +
+                               crStr + "  </facility>"
+                                       "</facilities>";
+
+    return createFacility(xmlStr);
+  }
+
+  FacilityInfo *createFacility(const std::string &xml) {
+    Poco::XML::DOMParser parser;
+    Poco::AutoPtr<Poco::XML::Document> pDoc = parser.parseString(xml);
+    Poco::XML::Element *pRootElem = pDoc->documentElement();
+    Poco::XML::Element *elem = pRootElem->getChildElement("facility");
+
+    return new FacilityInfo(elem);
+  }
+
+private:
+  // a minimal instrument to create a facility info
+  static const std::string simpleInstStr;
+
+  // default remote job manager type
+  static const std::string defaultType;
+
+  static const std::string testFacilityName;
+
+  static const std::string fermiName;
+  static const std::string fermiURL;
+  static const std::string scarfName;
+  static const std::string scarfURL;
+  static const std::string scarfType;
+};
+
+const std::string ComputeResourceInfoTest::simpleInstStr =
+    "<instrument name=\"AnInst\">"
+    "  <technique>Measuring Stuff</technique>"
+    "</instrument>";
+
+const std::string ComputeResourceInfoTest::defaultType =
+    "MantidWebServiceAPIJobManager";
+
+const std::string ComputeResourceInfoTest::testFacilityName = "ATestFacility";
+
+const std::string ComputeResourceInfoTest::fermiURL =
+    "https://fermi.ornl.gov/MantidRemote";
+const std::string ComputeResourceInfoTest::fermiName = "Fermi";
+const std::string ComputeResourceInfoTest::scarfURL =
+    "https://portal.scarf.rl.ac.uk";
+const std::string ComputeResourceInfoTest::scarfName = "SCARF@STFC";
+const std::string ComputeResourceInfoTest::scarfType = "SCARFLSFJobManager";
+
+#endif // COMPUTERESOURCEINFOTEST_H_
diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml
index 5b7c6c8b41a29ad5343a1cd3314291b9d4703f2c..1213adaf37862f103db1ccae6db21105283eec1a 100644
--- a/Code/Mantid/instrument/Facilities.xml
+++ b/Code/Mantid/instrument/Facilities.xml
@@ -6,7 +6,7 @@
     <archiveSearch plugin="ISISDataSearch" />
   </archive>
   
-  <computeResource name="SCARF@STFC">
+  <computeResource name="SCARF@STFC" JobManagerType="SCARFLSFJobManager">
     <baseURL>https://portal.scarf.rl.ac.uk</baseURL>
   </computeResource>