diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp
index 5c705b15f8387f2c1ba5d26573bc12ec771e0d69..1dd5caaec010793c7031c8394b1512a645447b13 100644
--- a/catalogue/Catalogue.hpp
+++ b/catalogue/Catalogue.hpp
@@ -182,6 +182,8 @@ public:
   virtual void fileWrittenToTape(
  const cta::common::dataStructures::ArchiveRequest &archiveRequest,
  const cta::common::dataStructures::TapeFileLocation tapeFileLocation) = 0;
+  
+  virtual std::map<uint64_t,std::string> getCopyNbToTapePoolMap(const std::string &storageClass) = 0;
 
 }; // class Catalogue
 
diff --git a/catalogue/DummyCatalogue.cpp b/catalogue/DummyCatalogue.cpp
index a038f87712aa808811626f8f69afa0d21f55a21b..8db678318f357f75fe6ecfa746371e063d4d6643 100644
--- a/catalogue/DummyCatalogue.cpp
+++ b/catalogue/DummyCatalogue.cpp
@@ -408,3 +408,10 @@ void cta::catalogue::DummyCatalogue::fileWrittenToTape(
   const cta::common::dataStructures::ArchiveRequest &archiveRequest,
   const cta::common::dataStructures::TapeFileLocation tapeFileLocation) {
 }
+
+//------------------------------------------------------------------------------
+// getCopyNbToTapePoolMap
+//------------------------------------------------------------------------------  
+std::map<uint64_t,std::string> cta::catalogue::DummyCatalogue::getCopyNbToTapePoolMap(const std::string &storageClass) {
+  return std::map<uint64_t,std::string>();
+}
\ No newline at end of file
diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp
index 884a84ee35d3874f94c6ea5f815d9b2b55bb9ecb..24f776abfba20e9624a5cf4d642d3d56491d31f4 100644
--- a/catalogue/DummyCatalogue.hpp
+++ b/catalogue/DummyCatalogue.hpp
@@ -141,6 +141,8 @@ public:
   virtual void fileWrittenToTape(
     const cta::common::dataStructures::ArchiveRequest &archiveRequest,
     const cta::common::dataStructures::TapeFileLocation tapeFileLocation);
+  
+  std::map<uint64_t,std::string> getCopyNbToTapePoolMap(const std::string &storageClass);
 
 }; // class DummyCatalogue
 
diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp
index 657d7bb9c44396e6640a23c43a21f850fe170656..375500327df8711b03c2526849b0a6b3771c72c3 100644
--- a/scheduler/OStoreDB/OStoreDB.cpp
+++ b/scheduler/OStoreDB/OStoreDB.cpp
@@ -40,6 +40,7 @@
 #include "ArchiveToTapeCopyRequest.hpp"
 #include "common/archiveNS/ArchiveFile.hpp"
 #include "objectstore/ArchiveRequest.hpp"
+#include "common/dataStructures/UserGroup.hpp"
 #include <algorithm>
 #include <stdlib.h>     /* srand, rand */
 #include <time.h>       /* time */
@@ -743,9 +744,63 @@ std::unique_ptr<cta::SchedulerDatabase::ArchiveToFileRequestCreation>
   return ret;
 }
 
-std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation>
-  OStoreDB::queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId) {  
-  return std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation>();
+std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> OStoreDB::queue(const cta::common::dataStructures::ArchiveRequest &request, 
+        const uint64_t archiveFileId, const std::map<uint64_t, std::string> &copyNbToPoolMap) {
+  assertAgentSet();
+  // Construct the return value immediately
+  std::unique_ptr<cta::OStoreDB::ArchiveRequestCreation> internalRet(new cta::OStoreDB::ArchiveRequestCreation(m_agent, m_objectStore));
+  cta::objectstore::ArchiveRequest & ar = internalRet->m_request;
+  ar.setAddress(m_agent->nextId("ArchiveRequest"));
+  ar.initialize();
+  ar.setChecksumType(request.getChecksumType());
+  ar.setChecksumValue(request.getChecksumValue());
+  ar.setCreationLog(request.getCreationLog());
+  ar.setDiskpoolName(request.getDiskpoolName());
+  ar.setDiskpoolThroughput(request.getDiskpoolThroughput());
+  ar.setDrData(request.getDrData());
+  ar.setEosFileID(request.getEosFileID());
+  ar.setFileSize(request.getFileSize());
+  ar.setRequester(request.getRequester());
+  ar.setSrcURL(request.getSrcURL());
+  ar.setStorageClass(request.getStorageClass());
+  // We will need to identity tapepools is order to construct the request
+  RootEntry re(m_objectStore);
+  ScopedSharedLock rel(re);
+  re.fetch();
+  auto & cl = copyNbToPoolMap;
+  std::list<cta::objectstore::ArchiveRequest::JobDump> jl;
+  for (auto copy=cl.begin(); copy != cl.end(); copy++) {
+    std::string tpaddr = re.getTapePoolAddress(copy->second);
+    ar.addJob(copy->first, copy->second, tpaddr);
+    jl.push_back(cta::objectstore::ArchiveRequest::JobDump());
+    jl.back().copyNb = copy->first;
+    jl.back().tapePool = copy->second;
+    jl.back().tapePoolAddress = tpaddr;
+  }
+  if (!jl.size()) {
+    throw ArchiveRequestHasNoCopies("In OStoreDB::queue: the archive to file request has no copy");
+  }
+  // We create the object here
+  {
+    objectstore::ScopedExclusiveLock al(*m_agent);
+    m_agent->fetch();
+    m_agent->addToOwnership(ar.getAddressIfSet());
+    m_agent->commit();
+  }
+  ar.setOwner(m_agent->getAddressIfSet());
+  ar.insert();
+  internalRet->m_lock.lock(ar);  
+  // We successfully prepared the object. It will remain attached to the agent 
+  // entry for the time being and get plugged to the tape pools on a second
+  // pass. 
+  // TODO: this can be improved by passing an opaque set of data to the called
+  // (including the lock) in order to optimise the acesses to the object store.
+  // In the mean time, the step 2 of this insertion will be done by finding the
+  // archiveRequest from the agent's owned object. Crude, but should not be too
+  // bad as the agent is not supposed to own many objects in this place.
+  std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> ret;
+  ret.reset(internalRet.release());
+  return ret;
 }
 
 void OStoreDB::deleteArchiveRequest(const SecurityIdentity& requester, 
diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp
index df03194c7166009335ddb23f6830bd7fb7e494bb..9a79f37af7b31c1733b82e20d6ffa403f9544f75 100644
--- a/scheduler/OStoreDB/OStoreDB.hpp
+++ b/scheduler/OStoreDB/OStoreDB.hpp
@@ -252,7 +252,7 @@ public:
     
   virtual std::unique_ptr<cta::SchedulerDatabase::ArchiveToFileRequestCreation> queue(const ArchiveToFileRequest& rqst);
   
-  virtual std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId);
+  virtual std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId, const std::map<uint64_t, std::string> &copyNbToPoolMap);
 
   CTA_GENERATE_EXCEPTION_CLASS(NoSuchArchiveRequest);
   CTA_GENERATE_EXCEPTION_CLASS(ArchiveRequestAlreadyDeleted);
diff --git a/scheduler/OStoreDB/OStoreDBFactory.hpp b/scheduler/OStoreDB/OStoreDBFactory.hpp
index e0e6f6be3492bb703f6ce122cad16d68767899a1..950950512c68169146ad6e58792c10dbf4974858 100644
--- a/scheduler/OStoreDB/OStoreDBFactory.hpp
+++ b/scheduler/OStoreDB/OStoreDBFactory.hpp
@@ -165,8 +165,8 @@ public:
     return m_OStoreDB.queue(rqst);
   }
 
-  virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId) {
-    return m_OStoreDB.queue(request, archiveFileId);
+  virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId, const std::map<uint64_t, std::string> &copyNbToPoolMap) {
+    return m_OStoreDB.queue(request, archiveFileId, copyNbToPoolMap);
   }
 
   virtual void queue(const RetrieveToFileRequest& rqst) {
diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 9c640358678839a3b7b41f5a731e3b4e7a3b5199..04315c9af16cfc65be263f71242958ae3a0cf7a3 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -49,7 +49,8 @@ cta::Scheduler::~Scheduler() throw() {
 //------------------------------------------------------------------------------
 uint64_t cta::Scheduler::queueArchiveRequest(const cta::common::dataStructures::SecurityIdentity &requestPusher, const cta::common::dataStructures::ArchiveRequest &request) {  
   const uint64_t archiveFileId = m_catalogue.getNextArchiveFileId();
-  std::unique_ptr<SchedulerDatabase::ArchiveRequestCreation> requestCreation(m_db.queue(request, archiveFileId));
+  const std::map<uint64_t, std::string> copyNbToPoolMap = m_catalogue.getCopyNbToTapePoolMap(request.getStorageClass());
+  std::unique_ptr<SchedulerDatabase::ArchiveRequestCreation> requestCreation(m_db.queue(request, archiveFileId, copyNbToPoolMap));
   requestCreation->complete();
   
   return 0;
diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp
index d8f8486055af7368ae08255d78b26f35fd975bca..bb194cb90edef1a1b91f72c0dc2618e1f78e2df4 100644
--- a/scheduler/SchedulerDatabase.hpp
+++ b/scheduler/SchedulerDatabase.hpp
@@ -92,7 +92,7 @@ public:
    *
    * @param rqst The request.
    */
-  virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId) = 0;
+  virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId, const std::map<uint64_t, std::string> &copyNbToPoolMap) = 0;
 
   /**
    * Returns all of the queued archive requests.  The returned requests are