diff --git a/src/main/java/it/inaf/oats/vospacebackend/utils/ResourceManager.java b/src/main/java/it/inaf/oats/vospacebackend/utils/ResourceManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..18f096d3eca222edf75f377129688025049a26ac
--- /dev/null
+++ b/src/main/java/it/inaf/oats/vospacebackend/utils/ResourceManager.java
@@ -0,0 +1,410 @@
+/**
+ * _____________________________________________________________________________
+ *
+ *                                 OATS - INAF
+ *  Osservatorio Astronomico di Tireste - Istituto Nazionale di Astrofisica
+ *  Astronomical Observatory of Trieste - National Institute for Astrophysics
+ * ____________________________________________________________________________
+ *
+ * Copyright (C) 20016  Istituto Nazionale di Astrofisica
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * _____________________________________________________________________________
+ *
+ */
+package it.inaf.oats.vospacebackend.utils;
+
+import ca.nrc.cadc.net.TransientException;
+import org.apache.log4j.Logger;
+
+import ca.nrc.cadc.util.RsaSignatureVerifier;
+import ca.nrc.cadc.uws.ErrorSummary;
+import ca.nrc.cadc.uws.ExecutionPhase;
+import ca.nrc.cadc.uws.Job;
+import ca.nrc.cadc.uws.Result;
+import ca.nrc.cadc.uws.server.DatabaseJobPersistence;
+import ca.nrc.cadc.uws.server.JobNotFoundException;
+import ca.nrc.cadc.uws.server.JobPersistenceException;
+import ca.nrc.cadc.uws.server.JobUpdater;
+import it.inaf.oats.vospacebackend.VOSpaceBackendResource;
+import it.inaf.oats.vospacebackend.exceptions.ExceptionMessage;
+import it.inaf.oats.vospacebackend.exceptions.VOSpaceBackendException;
+import it.inaf.oats.vospacebackend.implementation.DatabaseJobPersistenceImpl;
+import it.inaf.oats.vospacebackend.implementation.VOSpaceBackendImplFactory;
+import it.inaf.oats.vospacebackend.implementation.VOSpaceBackend;
+import it.inaf.oats.vospacebackend.utils.ConfigReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import java.util.logging.Level;
+import javax.xml.bind.DatatypeConverter;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.http.HttpStatus;
+
+import org.restlet.data.MediaType;
+import org.restlet.representation.FileRepresentation;
+import org.restlet.representation.Representation;
+
+/**
+ *
+ * @author bertocco
+ */
+public class ResourceManager implements org.apache.http.HttpStatus {
+
+    private static Logger log = Logger.getLogger(VOSpaceBackendResource.class);
+
+    private static int readAndSaveFile(String vosuri, FileItem fi)
+            throws IOException, VOSpaceBackendException {
+
+        Representation result;
+        log.debug("Entering in readAndSaveFile");
+
+        InputStream is = fi.getInputStream();
+        log.debug("Input stream get");
+
+        return readAndSaveFile(vosuri, is);
+
+    }
+
+    public static int readAndSaveFile(String vosuri, InputStream is)
+            throws IOException, VOSpaceBackendException {
+
+        int result;
+        String md5sum = null;
+
+        // Generate the unique file identifier (storageFileID)
+        String unique_file_id_str = UUID.randomUUID().toString();
+        log.debug("Unique file identifyer " + unique_file_id_str);
+
+        // Get temporary document root from configuration file
+        String tmpStorageRoot = new String();
+        try {
+            ConfigReader myConf = new ConfigReader("VOSpace.properties");
+            tmpStorageRoot = myConf.getProperty("fs.posix.tmp.storage.root");
+        } catch (Exception e) {
+            ExceptionMessage exMsg = new ExceptionMessage();
+            log.debug(MessageFormat.format(
+                    exMsg.getMessage("UNABLE_TO_READ_PROPERTIES"), "VOSpace.properties"));
+            throw new VOSpaceBackendException(MessageFormat.format(
+                    exMsg.getMessage("PROPERTY_NOT_FOUND"), "fs.posix.tmp.storage.root", "VOSpace.properties"));
+        }
+        // Create the temporary directory, if needed
+        File path = new File(tmpStorageRoot);
+        if (!path.exists()) {
+            boolean status = path.mkdirs();
+        }
+        // Seve the temporary file in temporary location with the new unique name
+        File savedUploadedFile = new File(path + File.separator + unique_file_id_str);
+        FileOutputStream outStream = new FileOutputStream(savedUploadedFile);
+        try {
+            md5sum = readWriteAndGetChecksum(is, outStream);
+        } catch (VOSpaceBackendReadInputException e) {
+            log.debug("File to upload received is a zero-length file");
+            log.debug("File NOT Uploaded! Something went wrong in readWriteAndGetChecksum." + e.getMessage());
+            result = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+        } catch (IOException e) {
+            log.debug("Error reading file to upload");
+            log.debug("File NOT Uploaded! Something went wrong in readWriteAndGetChecksum." + e.getMessage());
+            result = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+        } catch (NoSuchAlgorithmException e) {
+            log.debug("Exception in MD5 checksum generation");
+            log.debug("File NOT Uploaded! Something went wrong in readWriteAndGetChecksum." + e.getMessage());
+            result = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+        } catch (VOSpaceBackendTransferAbortedException e) {
+            log.debug("Exception in reading file to upload");
+            log.debug("File NOT Uploaded! Something went wrong in readWriteAndGetChecksum." + e.getMessage());
+            result = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+        }
+
+        try {
+            if (storeUploadedFile(vosuri, unique_file_id_str, md5sum)) {
+                log.debug("File successfully uploaded");
+                result = HttpStatus.SC_OK;
+            } else {
+                log.debug("File NOT Uploaded! Something went wrong in storeUploadedFile.");
+                result = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+            }
+        } catch (Exception e) {
+
+            log.debug("File NOT Uploaded! Something went wrong in readWriteAndGetChecksum." + e.getMessage());
+            result = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+        }
+
+        return result;
+    }
+
+    public static boolean storeUploadedFile(String vosuri, String tmp_file_name,
+            String md5_sum) {
+        boolean stored = false;
+        log.debug("Entering in storeUploadedFile");
+        try {
+            VOSpaceBackendImplFactory myVOSpaceFactory = new VOSpaceBackendImplFactory();
+            log.debug("myVOSpaceFactory created");
+            VOSpaceBackend myVOSpace = myVOSpaceFactory.getVOSpaceBackImpl();
+            log.debug("myVOSpace get");
+            stored = myVOSpace.createFile(vosuri, tmp_file_name, md5_sum);
+            log.debug("File stored: " + stored);
+        } catch (Exception e) {
+            log.debug("Unrecoverable exception storing file.");
+        }
+        return stored;
+
+    }
+
+    /* Return the file representation if ok, null elsewhere */
+    public static Representation downloadFile(String fileName) throws Exception {
+
+        Representation result;
+
+        log.debug("Entering in downloadFile");
+        VOSpaceBackendImplFactory myVOSpaceFactory = new VOSpaceBackendImplFactory();
+        log.debug("myVOSpaceFactory created");
+        VOSpaceBackend myVOSpace = myVOSpaceFactory.getVOSpaceBackImpl();
+        log.debug("myVOSpace get");
+        File fileToDownload = myVOSpace.returnFile(fileName);
+        if (fileToDownload != null) {
+            log.debug("File found, fileToDownload is not null");
+            FileRepresentation fr = new FileRepresentation(fileToDownload.getAbsolutePath(),
+                    MediaType.APPLICATION_OCTET_STREAM);
+            result = fr;
+
+        } else {
+            log.debug("File NOT found, fileToDownload is null");
+            result = null;
+        }
+
+        return result;
+    }
+
+    public static String manageParametersDecoding(String toBeVerified) throws VOSpaceBackendException {
+
+        String vosuri;
+        int count = 0;
+
+        log.debug("manageParametersEncoding BEGIN");
+        String urlStr = new String(DatatypeConverter.parseBase64Binary(toBeVerified));
+        log.debug("urlStr = " + urlStr);
+        vosuri = urlStr.substring(0, urlStr.indexOf("|"));
+        log.debug("vosuri = " + vosuri);
+        String remaining = urlStr.substring(urlStr.indexOf("|") + 1, urlStr.length());
+        log.debug("Remaining after get vosuri = " + remaining);
+        String signature = remaining.substring(remaining.indexOf("|") + 1, remaining.length());
+        log.debug("signature = \n" + signature);
+
+        // Validation
+        log.debug("I am going to create RsaSignatureVerifier");
+        RsaSignatureVerifier su = new RsaSignatureVerifier();
+        log.debug("Created");
+
+        boolean valid = false;
+        try {
+            valid = su.verify(new ByteArrayInputStream(vosuri.getBytes()),
+                    DatatypeConverter.parseBase64Binary(signature));
+        } catch (IOException ioe) {
+            log.debug("IOException in valid = su.verify(new ByteArrayInputStream(vosuri.getBytes()),\n"
+                    + "DatatypeConverter.parseBase64Binary(signature))");
+            throw new VOSpaceBackendException(ioe.getMessage());
+        } catch (InvalidKeyException ike) {
+            log.debug("InvalidKeyException in valid = su.verify(new ByteArrayInputStream(vosuri.getBytes()),\n"
+                    + "DatatypeConverter.parseBase64Binary(signature))");
+            log.debug("InvalidKeyException");
+            throw new VOSpaceBackendException(ike.getMessage());
+        }
+
+        return vosuri;
+
+    }
+
+    /* Read a file from the InputStream parameter,
+       write the file in the FileOutputStream parameter.
+       Returns the MD5 checksum of the stored file.    
+     */
+    public static String readWriteAndGetChecksum(InputStream istream, FileOutputStream ostream)
+            throws VOSpaceBackendReadInputException, IOException, NoSuchAlgorithmException,
+            VOSpaceBackendTransferAbortedException {
+
+        log.debug("Entering in readWriteAndGetChecksum(InputStream, FileOutputStream)");
+
+        int DEFAULT_BUFFER_SIZE = 1024 * 4;
+        String checksum = null;
+        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+        int bytesRead;
+
+        MessageDigest msgDigest = MessageDigest.getInstance("MD5");
+
+        // do an initial read to ensure there are bytes in the stream
+        try {
+            bytesRead = istream.read(buffer, 0, DEFAULT_BUFFER_SIZE);
+            if (bytesRead <= 0) {
+                // do not allow the creation of zero-length files
+                log.debug("Cannot write a zero-length file.");
+                throw new VOSpaceBackendReadInputException("Cannot write a zero-length file.");
+            } else {
+                log.debug("First bytes read OK. Input stream available and readable");
+            }
+        } catch (IOException ex) {
+            String errorMsg = "Upstream exception while reading from "
+                    + istream.getClass().getName() + ": "
+                    + ex.getMessage();
+            log.debug("IOException in the first byte reading of the incoming file");
+            log.debug(errorMsg);
+            throw new VOSpaceBackendTransferAbortedException(errorMsg);
+        }
+
+        // Loop reading and writing data.
+        msgDigest.update(buffer, 0, bytesRead);
+        log.debug("First msgDigest.update OK");
+
+        while (bytesRead >= 0) {
+            ostream.write(buffer, 0, bytesRead);
+            try {
+                bytesRead = istream.read(buffer, 0, DEFAULT_BUFFER_SIZE);
+                if (bytesRead > 0) {
+                    msgDigest.update(buffer, 0, bytesRead);
+                }
+            } catch (IOException ex) {
+                String errorMsg = "Upstream exception while reading from "
+                        + istream.getClass().getName() + ": "
+                        + ex.getMessage();
+                log.debug(errorMsg);
+                log.debug("A Exception in reading/writing file" + ex.getMessage());
+                throw new VOSpaceBackendTransferAbortedException(errorMsg);
+            }
+        }
+        ostream.flush();
+        ostream.close();
+
+        //Get the hash's bytes
+        byte[] bytes = msgDigest.digest();
+
+        String md5_checksum = new String(Hex.encodeHex(bytes));
+        log.debug("MD5 checksum calculated: " + md5_checksum);
+
+        return md5_checksum;
+
+    }
+    
+    public static ExecutionPhase getJobPhase(String jobID) {
+
+        ExecutionPhase execPhase = null;
+        try {
+            MyJobUpdater ju = new MyJobUpdater();
+            execPhase = ju.getPhase(jobID);
+                        
+            log.debug("Execution phase get!");
+        } catch (JobNotFoundException jnfe) {
+            log.debug("JobNotFoundException in getting job persistence");
+        } catch (JobPersistenceException ex) { 
+            log.debug("JobPersistenceException setting job phase");
+        }
+        if(execPhase != null)
+            return execPhase;
+        else
+            return null;
+
+    }
+
+    public static void setJobPhase(String jobID, ExecutionPhase start, ExecutionPhase end) {
+        
+        try {
+            MyJobUpdater ju = new MyJobUpdater();
+            ju.setPhase(jobID, start, end);                       
+            log.debug("Execution phase set!");
+        } catch (JobNotFoundException jnfe) {
+            log.debug("JobNotFoundException in getting job persistence");
+        } catch (JobPersistenceException ex) { 
+            log.debug("JobPersistenceException setting job phase");
+        }
+
+    }
+
+    public static class MyJobUpdater implements JobUpdater {
+
+        public ExecutionPhase getPhase(String jobID) throws JobNotFoundException, JobPersistenceException {
+            
+            DatabaseJobPersistence dbJobPers = new DatabaseJobPersistenceImpl();
+            Job myJob;
+            try {
+                log.debug("Going to get Job from jobID = " + jobID);
+                myJob = dbJobPers.get(jobID);
+                log.debug("Job get! I am going to set the execution phase to completed");
+            } catch (JobNotFoundException jnfe) {
+                log.debug("JobNotFoundException in getting job persistence or setting");
+                throw new JobNotFoundException(jobID);
+            } catch (JobPersistenceException jpe) {
+                log.debug("JobPersistenceException in getting job persistence or setting");
+                throw new JobNotFoundException(jobID);
+            } catch (TransientException te) {
+                log.debug("TransientException in getting job persistence or setting");
+                throw new JobNotFoundException(jobID);
+            }
+            if (myJob == null) {
+                throw new JobNotFoundException(jobID);
+            }
+            return myJob.getExecutionPhase();
+        }
+
+        public ExecutionPhase setPhase(String jobID, ExecutionPhase start, ExecutionPhase end) throws JobNotFoundException, JobPersistenceException {
+                        
+            DatabaseJobPersistence dbJobPers = new DatabaseJobPersistenceImpl();
+            Job myJob;
+            try {
+                log.debug("Going to get Job from jobID = " + jobID);
+                myJob = dbJobPers.get(jobID);
+                log.debug("Job get! I am going to set the execution phase to completed");
+            } catch (JobNotFoundException jnfe) {
+                log.debug("JobNotFoundException in getting job persistence or setting");
+                throw new JobNotFoundException(jobID);
+            } catch (JobPersistenceException jpe) {
+                log.debug("JobPersistenceException in getting job persistence or setting");
+                throw new JobNotFoundException(jobID);
+            } catch (TransientException te) {
+                log.debug("TransientException in getting job persistence or setting");
+                throw new JobNotFoundException(jobID);
+            }
+            if (myJob == null) {
+                throw new JobNotFoundException(jobID);
+            }
+            ExecutionPhase phase = myJob.getExecutionPhase();
+            if (phase.equals(start)) {
+                myJob.setExecutionPhase(end);
+            }
+            return myJob.getExecutionPhase();
+        }
+
+        public ExecutionPhase setPhase(String jobID, ExecutionPhase start, ExecutionPhase end, Date date) throws JobNotFoundException, JobPersistenceException {
+            return setPhase(jobID, start, end);
+        }
+
+        public ExecutionPhase setPhase(String jobID, ExecutionPhase start, ExecutionPhase end, List<Result> results, Date date) throws JobNotFoundException, JobPersistenceException {
+            return setPhase(jobID, start, end);
+        }
+
+        public ExecutionPhase setPhase(String jobID, ExecutionPhase start, ExecutionPhase end, ErrorSummary error, Date date) throws JobNotFoundException, JobPersistenceException {
+            return setPhase(jobID, start, end);
+        }
+    }
+
+}