diff --git a/src/main/java/it/inaf/oats/vospacebackend/implementation/VOSpaceBackendPosix.java b/src/main/java/it/inaf/oats/vospacebackend/implementation/VOSpaceBackendPosix.java
new file mode 100644
index 0000000000000000000000000000000000000000..a13eabb391cb89e81af04c83d45a6cbff2ae1b58
--- /dev/null
+++ b/src/main/java/it/inaf/oats/vospacebackend/implementation/VOSpaceBackendPosix.java
@@ -0,0 +1,373 @@
+/**_____________________________________________________________________________
+ *
+ *                                 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.implementation;
+
+import ca.nrc.cadc.util.FileMetadata;
+import ca.nrc.cadc.vos.DataNode;
+import it.inaf.oats.vospacebackend.exceptions.ExceptionMessage;
+import it.inaf.oats.vospacebackend.exceptions.VOSpaceBackendException;
+import it.inaf.oats.vospacebackend.utils.ConfigReader;
+
+import ca.nrc.cadc.vos.Node;
+import ca.nrc.cadc.vos.server.NodeID;
+import ca.nrc.cadc.vos.VOS;
+import ca.nrc.cadc.vos.VOSURI;
+
+import java.sql.SQLException;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.commons.io.FileUtils;
+
+/**
+ *
+ * @/author bertocco
+ */
+public class VOSpaceBackendPosix implements VOSpaceBackend {
+    
+    private static String documentRoot;
+    private static String tmpStorageRoot;
+    private static final String CONFIG_FILE_NAME = "VOSpace.properties";
+    private static final Logger log = Logger.getLogger(VOSpaceBackendImplFactory.class);
+    
+    public VOSpaceBackendPosix() throws VOSpaceBackendException {
+        
+        try {
+            ConfigReader myConf = new ConfigReader(CONFIG_FILE_NAME);
+        
+            this.documentRoot = myConf.getProperty("fs.posix.document.root");     
+            this.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"), CONFIG_FILE_NAME));
+            throw new VOSpaceBackendException(                   
+               MessageFormat.format(exMsg.getMessage("UNABLE_TO_READ_PROPERTIES"), CONFIG_FILE_NAME));
+            
+        }
+        log.debug("VOSpace Backend Document Root = " + this.documentRoot);
+        log.debug("VOSpace Backend Temporary Document Root = " + this.tmpStorageRoot);
+        
+    }
+    
+
+    public boolean createFile(String vosuri, String tmp_file, String md5_sum) 
+                           throws VOSpaceBackendException, SQLException, IOException {
+        
+        log.debug("Entering in vospacebackendposix.createfile");
+        VOSpaceBackendMetadata metadata = new VOSpaceBackendMetadata();
+        
+        log.debug("md5_checksum received in backendposix.createFile : " + md5_sum);
+        String relativePath = this.createPathFromString(md5_sum);
+        
+        // Gets metadata on frontend
+        log.debug("SBE: Checkpint 1 -> before new DatabaseNodePersistenceExt()");
+        DatabaseNodePersistenceImpl dbNodePers = new DatabaseNodePersistenceImpl();
+        log.debug("SBE: Checkpint 2 -> after new DatabaseNodePersistenceExt() and before myNode = dbNodePers.get(new VOSURI(vosuri));");
+        log.debug("SBE: Checkpint 2A ->  vosuri = #" + vosuri + "#");
+        Node myNode = null;
+        try {
+            myNode = dbNodePers.get(new VOSURI(vosuri));
+            log.debug("SBE: Checkpint 3 -> after dbNodePers.get(new VOSURI(vosuri)); vosuri = #" + vosuri + "#");
+        } catch (Exception e) {
+            log.debug("Exception getting node from persistence.");
+            log.debug("Exception message : " + e.getMessage());
+            StringWriter sw = new StringWriter();
+            e.printStackTrace(new PrintWriter(sw));
+            String exceptionAsString = sw.toString();
+            log.debug(exceptionAsString);
+        }
+        NodeID nodeID = (NodeID)myNode.appData;
+        log.debug("SBE: Checkpint 4 -> nodeID = " + nodeID.toString());
+        Long myNodeID = nodeID.getID();
+        log.debug("SBE: Checkpint 5  -> nodeID.getID() = " + myNodeID);
+
+        if (!(myNode instanceof DataNode)) {
+            log.debug("Node instance NOT found");
+            throw new VOSpaceBackendException("Node instance NOT found");
+        } 
+        log.debug("SBE: Checkpint 6 ");
+        DataNode myDataNode = (DataNode)myNode;
+        
+        // Needs syncronisation BEGIN
+        boolean result = false;
+        synchronized (this) {
+            try {
+            
+                dbNodePers.setBusyState(myDataNode, VOS.NodeBusyState.notBusy, VOS.NodeBusyState.busyWithWrite);
+                log.debug("SBE: Checkpint 7 -> after  dbNodePers.setBusyState");
+            } catch (Exception ex) {
+                log.debug("Exception in dbNodePers.setBusyState");
+                throw new VOSpaceBackendException("TransientException in dbNodePers.setBusyState");
+            }
+            log.debug("SBE: Checkpint 8 -> tmp_file = " + tmp_file + " --- myNodeID.toString() = " + myNodeID.toString());
+            FileRecord putReqData = metadata.setRequest(tmp_file, myNodeID.toString());
+            log.debug("SBE: Checkpint 9  -> after metadata.setPutRequest(tmp_file, myNodeID.toString())");
+            boolean myresult = putReqData.getIfOperationSuccessful();
+            log.debug("SBE: Checkpint 9A -> myresult = " + myresult);
+            if(!myresult) {
+                log.debug("Fails updating table NodeStoredFileAndNode");
+                throw new VOSpaceBackendException("Node instance NOT found");
+            }   
+            log.debug("SBE: Checkpint 10  -> operation successful");
+            log.debug("SBE: Checkpint 10  -> tmp_file = " +tmp_file  + " --- md5_sum = " + md5_sum + " --- relativePath = " + relativePath);
+
+        
+            // sets backend metadata
+            FileRecord fileMetadata = metadata.setFile(tmp_file, md5_sum, relativePath);
+            log.debug("SBE: Checkpint 11  -> after metadata.setFile");
+ 
+            // Writes the file on the file system
+            result = fileMetadata.getIfOperationSuccessful();
+            if (result) {
+                log.debug("File metadata successfully saved. I'm going to store the file content");
+                this.fileFromTmpToFinalStorageArea(tmp_file, relativePath, "MOVE"); 
+            } else
+                log.debug("File backend metadata NOT saved. Need to abort the operation");
+            // Set front-end metadata and not busy
+            FileMetadata nodeMetadata = new FileMetadata();
+            nodeMetadata.setMd5Sum(md5_sum);
+            log.debug("SBE: Checkpint 12 ->  After nodeMetadata.setMd5Sum(md5_sum)");
+
+            // INSERT A CORRECT FileSize !!!!!!!!!!!!!!!!!!!!
+            nodeMetadata.setContentLength(345678L);
+            //nodeMetadata.setContentLength("file_size");
+            try {
+                log.debug("SBE: Checkpint 13 ->  myDataNode = " + myDataNode + " --- nodeMetadata = " + nodeMetadata);
+                dbNodePers.setFileMetadata(myDataNode, nodeMetadata, false);
+                log.debug("SBE: Checkpint 13 ->  After dbNodePers.setFileMetadata(myDataNode, nodeMetadata, false)");
+            } catch (Exception ex) {
+                log.debug("Exception doing databasePersistence.setFileMetadat.");
+                throw new VOSpaceBackendException("Node instance NOT found");
+            }
+        }
+        // Needs syncronisation END
+        
+        return result;
+                   
+    }
+    
+    
+    /* Retrieve the file, copy it in the temporary location, return the File */
+    public File returnFile(String vosuri) 
+               throws VOSpaceBackendException, SQLException, IOException {
+        
+        // Check if fileName is present in metadata DB
+        VOSpaceBackendMetadata metadataDB = new VOSpaceBackendMetadata();
+        
+        // Gets metadata on frontend 
+        NodeUtils nodeUtil = new NodeUtils();
+        Long myNodeID = nodeUtil.getNodeIdLongfromVosuriStr(vosuri);
+        
+        if (myNodeID == null) {
+            log.debug("Problem encountered reading backend node metadata");
+            return null;
+        }
+               
+        FileRecord backendMetadata = metadataDB.getRequest(myNodeID.toString());
+        if (!backendMetadata.getIfOperationSuccessful()) {
+            log.debug("Backend metadata not found");
+            return null;
+        }
+        
+        String storedFileName = backendMetadata.getStoredfileName();
+        
+        FileRecord myMetadata = metadataDB.getFile(storedFileName);
+ 
+        File outFile = null;
+        
+        if (myMetadata.getIfOperationSuccessful()) {
+            log.debug("Metadata record found for vosuri " + vosuri);
+            log.debug("storedFileName = " + myMetadata.getStoredfileName());
+            log.debug("relative_path = " + myMetadata.getRelativePath());
+            log.debug("md5_checksum = " + myMetadata.getMD5Checksum());
+            storedFileName = myMetadata.getStoredfileName();
+            String relativePath = myMetadata.getRelativePath();
+            String unique_file_id_str = UUID.randomUUID().toString();
+            // Needs syncronisation START
+            this.fileFromStorageAreaToTmp(storedFileName, unique_file_id_str, relativePath, "COPY");
+            outFile = new File(this.getTmpPath() + storedFileName);
+            return outFile;
+            // Needs syncronisation END
+        } else {
+            log.debug("Metadata record NOT found for file " + vosuri);
+            outFile = null;
+            return outFile;
+        } 
+    
+    }
+    
+    
+    public String createPathFromString(String initialStr) throws VOSpaceBackendException{
+        
+        log.debug("initialStr = " + initialStr);
+        log.debug("initialStr.substring(initialStr.length()-2, initialStr.length())" + initialStr.substring(initialStr.length()-2));
+        log.debug("initialStr.length()-4, initialStr.length()-2)" + initialStr.substring(initialStr.length()-4, initialStr.length()-2)); 
+        
+        String relativePath = null;
+        try{
+            relativePath = new String(File.separator + 
+                              initialStr.substring(initialStr.length()-4, initialStr.length()-2) +                              
+                              File.separator +
+                              initialStr.substring(initialStr.length()-2, initialStr.length()));
+        } catch (Exception e) {
+            log.debug("Exception creating partial path from string " + initialStr);
+            throw new VOSpaceBackendException(e);
+        }
+        log.debug("relative path = " + relativePath);
+        
+        return relativePath;
+        
+    }
+    
+    public void fileFromTmpToFinalStorageArea(String tmpfile, String relPath, String operation)
+                                 throws VOSpaceBackendException {
+    
+        
+        File tmpFile = new File(this.getTmpPath() + tmpfile);  
+        File finalStoredFile = new File(this.getStoragePath(relPath) + tmpfile);  
+        
+        log.debug("tmpStoredFile is: " + tmpFile);
+        log.debug("finalStoredFile is: " + finalStoredFile);
+        
+        this.operateOnFiles(tmpFile, finalStoredFile, operation);
+               
+    }
+    
+    public void fileFromStorageAreaToTmp(String stored, String tmp, String relativePath, String operation)
+                                 throws VOSpaceBackendException {
+        
+        File storedFile = new File(this.getStoragePath(relativePath) + stored);
+        File tmpFile = new File(this.getTmpPath() + tmp);
+         
+        log.debug("storedFile is: " + storedFile);
+        log.debug("tmpFile is: " + tmpFile);
+
+        this.operateOnFiles(storedFile, tmpFile, operation);
+
+    }
+    
+    
+    public void operateOnFiles (File A, File B, String operation) throws VOSpaceBackendException {
+                    
+        log.debug("File A is: " + A);
+        log.debug("File B is: " + B);
+        log.debug("Operation required is " + operation);
+
+        switch (operation) {
+            case "MOVE":  
+                this.moveFileAToFileB(A, B);
+                break;
+            case "COPY":  
+                this.copyFileAToFileB(A, B);
+                break;
+            default: 
+                log.debug("Error in operation required");
+                throw new VOSpaceBackendException("Error in operation required");
+        }
+        
+    }
+        
+        
+    public boolean checksBeforeCopyOrMove(File A, File B)
+                                            throws VOSpaceBackendException {
+        
+        boolean checkOK = false;
+    
+        if (!A.exists()) {
+            log.debug("Move operation impossible: source file" + A.getAbsolutePath() 
+                                                          + "does not exists.");
+            throw new VOSpaceBackendException("Operation impossible: source file" 
+                                              + A.getAbsolutePath() + "does not exists.");             
+        }       
+        
+        String absolutePathB = B.getAbsolutePath();
+        String pathB = absolutePathB.substring(0,absolutePathB.lastIndexOf(File.separator)); 
+        File pathBFile = new File(pathB);
+        if (!pathBFile.exists()) {
+            try {
+                checkOK = pathBFile.mkdirs();
+            } catch (Exception e) {
+                log.debug("Exception creating the final destination directory of file "
+                                                      + B.getAbsolutePath());
+                throw new VOSpaceBackendException(e);                
+            }
+        } else if (pathBFile.isDirectory()){
+            checkOK = true;
+        } else {
+            log.debug("File " + pathB + " already exsists, but is not a directory.");
+            checkOK = false;
+        }
+        
+        return checkOK;
+    
+    }
+
+    public void moveFileAToFileB (File A, File B) throws VOSpaceBackendException {
+                    
+        if (this.checksBeforeCopyOrMove(A, B)) {
+            try {
+                FileUtils.moveFile(A, B);
+            } catch (Exception e) {
+                log.debug("Exception moving temporary copy of uploaded file in its final destination directory");
+                throw new VOSpaceBackendException(e);                
+            }
+        }
+        
+    }
+    
+    public void copyFileAToFileB (File A, File B) throws VOSpaceBackendException {
+                    
+        if (this.checksBeforeCopyOrMove(A, B)) {
+            try {
+                FileUtils.copyFile(A, B);
+            } catch (Exception e) {
+                log.debug("Exception moving temporary copy of uploaded file in its final destination directory");
+                throw new VOSpaceBackendException(e);                
+            }
+        }
+        
+    }
+    
+    private String getStoragePath(String relativePath) {
+        
+        String storagePath = this.documentRoot + relativePath + File.separator;
+        return storagePath;
+        
+    }
+    
+    private String getTmpPath() {
+        
+        String tmpFilePath = this.tmpStorageRoot + File.separator;
+        return tmpFilePath;
+        
+    }
+        
+}