diff --git a/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc b/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc
new file mode 100644
index 0000000000000000000000000000000000000000..070378f5e227ae2c017812444b676802bc31de1e
--- /dev/null
+++ b/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc
@@ -0,0 +1,34 @@
+<?php
+
+interface Files{
+    // File
+    // PHP native functions
+    public function file_exists ($sFilePath);
+    public function file_put_contents ($sFilePath, $sData, $iFlags = 0, $mContext = null);
+    public function file_get_contents ($sFilePath, $bUseIncludePath = FALSE, $mContext = null, $iOffset = 0, $iMaxLen = -1);
+    public function file_get_contents_with_etag ($sFilePath, $sEtag ,$bUseIncludePath = FALSE, $mContext = null, $iOffset = 0, $iMaxLen = -1);
+    public function copy ($sSourceFilePath, $sDestFilePath);
+    public function filesize ($sFilePath);
+    public function readfile ($sFilePath, $bUseIncludePath = FALSE, $mContext = null);
+    public function rename ($sSourceFilePath, $sDestFilePath, $mContext = null);
+    public function unlink ($sFilePath, $mContext = null);
+    public function filemtime ($sFilePath);
+    public function filemtime_formated ($sFilePath, $sFormat);
+    // Veremes functions
+    public function getFileInfos ($sFilePath);
+    public function getProxyPassUrl ($sFilePath);
+    public function getFileEtag($sFilePath);
+
+    // Directory
+    // PHP native functions
+    public function scandir($sDirPath, $iSortOrder = SCANDIR_SORT_ASCENDING, $mContext = null);
+    public function mkdir($sDirPath, $iMode = 0777, $bRecursive = FALSE, $mContext = null);
+    public function rmdir($sDirPath, $mContext = null);
+    public function is_dir($sDirPath);
+    // Veremes functions
+    public function getFolderInfos($sDirPath);
+    public function clearDir($sDirPath);
+    public function copyDirectory($sDirPathSrc, $sDirPathDest);
+
+}
+?>
diff --git a/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..13183cc36b572741466350223a553448457fe0e3
--- /dev/null
+++ b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
@@ -0,0 +1,403 @@
+<?php
+
+require_once ("S3_files.class.inc");
+require_once ("Local_files.class.inc");
+
+require_once ("vmlib/phpUtil.inc");
+require_once ("vmlib/logUtil.inc");
+
+class Files_manager{
+
+    public $oFileInterface;
+    private $oProperties;
+    private $oLocalInterface;
+    //private $oS3Interface;
+
+    private static $sFolderLib = "vmlib";
+
+    function __construct($oProperties){
+        $this->oProperties = $oProperties;
+        // Dans tous les cas on peut avoir besoin d'accéder au système local
+        $this->$oLocalInterface = new Local_files ($oProperties);
+        // Séléction du mode principal
+        switch ($oProperties["filesystem"]) {
+            case 'fs':
+                $this->oFileInterface = $this->$oLocalInterface;
+                break;
+            case 's3':
+                $this->oFileInterface = new S3_files ($oProperties);
+                break;
+            default:
+                writeToErrorLog("The file system " . $oProperties["filesystem"] . " is not available on this server");
+                break;
+        }
+    }
+    /**
+     *This method allow to upload a file on a server.
+     *@file vmlib/phpUtil.inc
+     *@param $sNomObjet Name of the object.
+     *@param $sFileType Type of file needed.
+     *@param $sServerPath New path of the file.
+     *@param $sMaxSize Maximal size of the file.
+     *@param $aFileValues File structure generated by extractFileStruct.
+     *@return $sErrorMsg The error message or the final file path on success.
+     */
+    private function upload_file($sNomObjet, $sFileType, $sServerPath, $sMaxSize, $aFileValues){
+             loadLang($this->sFolderLib, $this->oProperties["language"], $this->sFolderLib . "/");
+
+             $aExtension = array(
+                 "image" => array('gif', 'jpg', 'jpeg', 'png'),
+                 "image-pdf" => array('gif', 'jpg', 'jpeg', 'png', 'pdf'),
+                 "document" => array('pdf', 'gif', 'jpg', 'jpeg', 'png', 'txt'),
+                 "pdf" => array('pdf'),
+                 "zip" => array('zip', 'gex'),
+                 "fmw" => array('fmw')
+             );
+             $aForbiddenExtension = explode('|', str_replace("*.", "", $this->oProperties['forbidden_extension']));
+             $sTmpFile = "";
+             $sErrorMsg = "";
+             // si pas de aValues il y a eu une erreur pendant l'upload dans tmp du PUT
+             if (!empty($aFileValues)){
+                 $sTmpFile = $aFileValues['tmp_name'];
+
+                 // Si l'utilisateur n'a indiqué aucun fichier à uploader, il ne se passe rien
+                 if ($sTmpFile == '') {
+                     if ($aFileValues['name'] != "") {
+                         switch ($aFileValues['error']) {
+                             case "1" :
+                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_UPLOAD_MAX_FILE_SIZE;
+                                 break;
+                             case "2" :
+                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MAX_FILE_SIZE;
+                                 break;
+                             case "3" :
+                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PARTIAL_DOWNLOAD;
+                                 break;
+                             case "4" :
+                                 $sErrorMsg = ERROR_NO_FILE_DOWNLOADED;
+                                 break;
+                             case "6" :
+                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MISSING_TEMP_FOLDER;
+                                 break;
+                             case "7" :
+                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_WRITING_DISK;
+                                 break;
+                             case "8" :
+                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PHP_EXT_SEND;
+                                 break;
+                         }
+                         writeToErrorLog($sErrorMsg);
+                     }
+                     return $sErrorMsg;
+                 }
+
+                 $aTemp = explode("/", $sServerPath);
+
+                 $sFileName = end($aTemp);
+                 $sFileExtension = $this->extension($sFileName);
+
+                 if (!in_array($sFileExtension, $aForbiddenExtension)) {
+                     //Teste si le fichier correspont au format voulu.
+                     $bAllowUpload = false;
+                     $sFormat = "";
+
+                     if (in_array($sFileType, array_keys($aExtension))){
+                         if (in_array($sFileExtension, $aExtension[$sFileType])) {
+                             $bAllowUpload = true;
+                         } else {
+                             foreach ($aExtensionPicture as $sValue) {
+                                 $sFormat .= " " . $sValue;
+                             }
+                             writeToErrorLog(ERROR_FILE . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType);
+                             $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
+                         }
+                     } else {
+                         $bAllowUpload = true;
+                     }
+
+                     //Teste si le fichier n'est pas de trop grande taille.
+                     if ($aFileValues['size'] > $sMaxSize || $aFileValues['error'] == 1) {
+                         $bAllowUpload = false;
+                         if ($aFileValues['size'] > $sMaxSize)
+                             $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . OF_LABEL_PHPUTIL . $aFileValues['size'] . ERROR_EXCEED_MAX_SIZE . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
+                         if ($aFileValues['error'] > $sMaxSize)
+                             $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_EXCEED_MAX_SIZE_PHP . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
+                     }
+
+                     // si c'est une image avec les infos de taille final on resample
+                     if($sFileType === "image" && (isset($aFileValues["width"]) && isset($aFileValues["height"]))){
+                       $sTmpFile = pictureResampler($sTmpFile, $aFileValues["width"], $aFileValues["height"], 0, 0, 0, 0, $sFileExtension);
+                       if(!$sTmpFile){
+                         $bAllowUpload = false;
+                         writeToErrorLog(ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . ', while resampling picture, ' . $sServerPath);
+                         $sErrorMsg = ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . '.';
+                       }
+                     }
+
+                     //Lance l'upload.
+                     if ($bAllowUpload) {
+                         $sFileContent =  file_get_contents($sTmpFile);
+                         $this->oFileInterface->file_put_contents($sServerPath, $sFileContent);
+                         unlink($sTmpFile);
+                         $sErrorMsg = $sServerPath;
+                     }
+                 } else {
+                     writeToErrorLog(ERROR_FILE . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType);
+                     $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
+                 }
+             } else {
+                 writeToErrorLog(ERROR_FILE . "File" . ERROR_DOWNLOAD_SERVER);
+                 $sErrorMsg = FILE_LABEL_PHPUTIL . "File" . ERROR_DOWNLOAD_SERVER . '.';
+             }
+
+             return $sErrorMsg;
+         }
+    //}
+
+  /**
+  *This method convert $_FILE struct or the aValues File to a File Struct usable by uploadFile.
+  *@file vmlib/phpUtil.inc
+  *@param $sField Name of the field.
+  *@param $aValues $aValues to copy file in tmp.
+  *@return $aFileStruct FileStuct or null if an error block the write in tmp.
+  */
+  private function extractFileStruct ($sField, $aValues = null){
+      $aFileStruc = array();
+      if (!isset($aValues[$sField . "_name"])){
+          // Extract From Post $File Struct
+          $aFileStruc = array(
+              "name" => $_FILES[$sField]['name'],
+              "tmp_name" => $_FILES[$sField]['tmp_name'],
+              "error" => $_FILES[$sField]['error'],
+              "size" => $_FILES[$sField]['size']
+          );
+      } else {
+          // Extraction de $aValues, on le met dans tmp pour préparer la copie dans upload file
+          $sTmpFile = $this->oProperties['extract_dir'] . "/" . getUniqRandomId();
+          $oFile = fopen($sTmpFile, 'w+');
+          if (!$oFile){
+              writeToErrorLog("Can't open file in " . $this->oProperties['extract_dir']);
+              return null;
+          }else{
+              fwrite($oFile, $aValues[$sField . "_file"]);
+              fclose($oFile);
+              $aFileStruc = array(
+                  "name" => $aValues[$sField . "_name"],
+                  "tmp_name" => $sTmpFile,
+                  "error" => "0",
+                  "size" => filesize($sTmpFile)
+              );
+          }
+      }
+
+      if(isset($aValues[$sField . "_width"]) && isset($aValues[$sField . "_height"])){
+        $aFileStruc["width"] = $aValues[$sField . "_width"];
+        $aFileStruc["height"] = $aValues[$sField . "_height"];
+      }
+
+      return $aFileStruc;
+    }
+    /**
+     *This method upload a file in ws_data.
+     *@param $sModule Name of the module.
+     *@param $sObject Name of the object.
+     *@param $mId Id of the current object.
+     *@param $sField field name (generally DB column name).
+     *@param $aValues Vitis $aValues.
+     *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
+     *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
+     *@return $sErrorMsg The error message.
+     */
+    function uploadInWsDataDir ($sModule, $sObject, $mId, $sField, $aValues, $iMaxSize = -1, $sFileTypeCtrl = "all"){
+        // on controle les attributs pour éviter les mauvais placements
+        if (strpos($sModule, '/') > -1){
+            writeToErrorLog("Module can't contain path : " . $sModule);
+            return "Module can't contain path : "  . $sModule;
+        }
+
+        if (strpos($sObject, "/") > -1){
+            writeToErrorLog("Object can't contain path : " . $sObject);
+            return "Object can't contain path : "  . $sObject;
+        }
+
+        if (strpos($mId, "/") > -1){
+            writeToErrorLog("Id can't contain path : " . $mId);
+            return "Id can't contain path : "  . $mId;
+        }
+
+        if (strpos($sField, "/") > -1){
+            writeToErrorLog("Field can't contain path : " . $sField);
+            return "Field can't contain path : "  . $sField;
+        }
+        // on génére la Structure fichier
+        $aFileStruct = $this->extractFileStruct ($sField, $aValues);
+        // on génére la destination
+        $sDestDir = $this->oProperties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;
+        if(!empty($sField)){
+          $sDestDir .= "/" . $sField;
+        }
+        $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];
+
+        // on controle la destination pour éviter les mauvais placements
+        if (strpos($sDestPath, "/\.\./") > -1){
+            writeToErrorLog("This function doesn't accept relative reference : " . $sDestPath);
+            return "This function doesn't accept relative reference : " . $sDestPath;
+        }
+        // si taille max vaut -1 alors taille max = taille fichier + 1
+        if ($iMaxSize == -1){
+            $iMaxSize = $aFileStruct["size"] + 1;
+        }
+        // création du fichier si besoin
+        if (!is_dir($sDestDir)){
+            if(!mkdir($sDestDir, 0777, true)){
+                writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDestDir);
+                return 'ERROR_CREATING_DIRECTORY ' . $sDestDir;
+            }
+        }
+        // Upload du fichier
+        return $this->uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
+    }
+    /**
+     *This method upload a file in Public.
+     *@file vmlib/phpUtil.inc
+     *@param $sModule Name of the module.
+     *@param $sField field name (generally DB column name).
+     *@param $aValues Vitis $aValues.
+     *@param $sRandomUniqId random folder to write the file.(set to auto to let the function create the folder)
+     *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
+     *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
+     *@return $sErrorMsg The error message.
+     */
+    function uploadInPublicDir($sModule, $sField, $aValues, $sRandomUniqId = "auto", $iMaxSize = -1, $sFileTypeCtrl = "all"){
+      // on controle les attributs pour éviter les mauvais placements
+      if (strpos($sModule, '/') > -1){
+          writeToErrorLog("Module can't contain path : " . $sModule);
+          return "Module can't contain path : "  . $sModule;
+      }
+      if (strpos($sField, "/") > -1){
+          writeToErrorLog("Field can't contain path : " . $sField);
+          return "Field can't contain path : "  . $sField;
+      }
+      // on génére la Structure fichier
+      $aFileStruct = $this->extractFileStruct ($sField, $aValues);
+      // on génére le dossier unique si besoin
+      if($sRandomUniqId == "auto"){
+        $sRandomUniqId = getUniqRandomId();
+      }
+      // on génére la destination
+      $sDestDir = $this->oProperties['dir_export'] . "/" . $sModule . "/" . $sRandomUniqId;
+      $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];
+
+      // on controle la destination pour éviter les mauvais placements
+      if (strpos($sDestPath, "/\.\./") > -1){
+          writeToErrorLog("This function doesn't accept relative reference : " . $sDestPath);
+          return "This function doesn't accept relative reference : " . $sDestPath;
+      }
+      // si taille max vaut -1 alors taille max = taille fichier + 1
+      if ($iMaxSize == -1){
+          $iMaxSize = $aFileStruct["size"] + 1;
+      }
+
+      // création du fichier si besoin
+      if (!is_dir($sDestDir)){
+          if(!mkdir($sDestDir, 0777, true)){
+              writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDestDir);
+              return 'ERROR_CREATING_DIRECTORY ' . $sDestDir;
+          }
+      }
+      // Upload du fichier
+      return $this->uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
+    }
+    /**
+     *This method upload a file in Upload.
+     *@file vmlib/phpUtil.inc
+     *@param $sModule Name of the module.
+     *@param $sField field name (generally DB column name).
+     *@param $aValues Vitis $aValues.
+     *@param $sRandomUniqId random folder to write the file.(set to auto to let the function create the folder)
+     *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
+     *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
+     *@return $sErrorMsg The error message.
+     */
+    function uploadInUploadDir($sModule, $sField, $aValues, $sRandomUniqId = "auto", $iMaxSize = -1, $sFileTypeCtrl = "all"){
+      // on controle les attributs pour éviter les mauvais placements
+      if (strpos($sModule, '/') > -1){
+          writeToErrorLog("Module can't contain path : " . $sModule);
+          return "Module can't contain path : "  . $sModule;
+      }
+      if (strpos($sField, "/") > -1){
+          writeToErrorLog("Field can't contain path : " . $sField);
+          return "Field can't contain path : "  . $sField;
+      }
+      // on génére la Structure fichier
+      $aFileStruct = $this->extractFileStruct ($sField, $aValues);
+      // on génére le dossier unique si besoin
+      if($sRandomUniqId == "auto"){
+        $sRandomUniqId = getUniqRandomId();
+      }
+      // on génére la destination
+      $sDestDir = $this->oProperties['upload_dir'] . "/" . $sModule . "/" . $sRandomUniqId;
+      $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];
+
+      // on controle la destination pour éviter les mauvais placements
+      if (strpos($sDestPath, "/\.\./") > -1){
+          writeToErrorLog("This function doesn't accept relative reference : " . $sDestPath);
+          return "This function doesn't accept relative reference : " . $sDestPath;
+      }
+      // si taille max vaut -1 alors taille max = taille fichier + 1
+      if ($iMaxSize == -1){
+          $iMaxSize = $aFileStruct["size"] + 1;
+      }
+
+      // création du fichier si besoin
+      if (!is_dir($sDestDir)){
+          if(!mkdir($sDestDir, 0777, true)){
+              writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDestDir);
+              return 'ERROR_CREATING_DIRECTORY ' . $sDestDir;
+          }
+      }
+      // Upload du fichier
+      return $this->uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
+    }
+    /**
+     *This method return the extension of a file.
+     *@file vmlib/phpUtil.inc
+     *@param $sString Full name of a file.
+     *@return Retourne une chaine.
+     */
+    public function extension($sPath) {
+        $aTemp = explode(".", $sString);
+        $sString = strtolower($aTemp[count($aTemp) - 1]);
+
+        return $sString;
+    }
+
+    /**
+     *This method return the name of a file from its full path.
+     *@file vmlib/phpUtil.inc
+     *@param $sFullFileName Full path of a file.
+     *@return $aTemp2 The file name.
+     */
+    public function getFileName($sFullFileName) {
+        $aTemp = explode("/", $sFullFileName);
+        $aTemp2 = explode("\\", $aTemp[(count($aTemp) - 1)]);
+
+        return $aTemp2[(count($aTemp2) - 1)];
+    }
+
+    public function uploadInLocalFs ($sFilePath, $sField, $aValues) {
+        if (strpos($sField, "/") > -1){
+            writeToErrorLog("Field can't contain path : " . $sField);
+            return "Field can't contain path : "  . $sField;
+        }
+        // on génére la Structure fichier
+        $aFileStruct = $this->extractFileStruct ($sField, $aValues);
+        $sTmpFile = $aFileStruct['tmp_name'];
+
+        $sFileContent =  file_get_contents($sTmpFile);
+        $this->$oLocalInterface->file_put_contents($sFilePath, $sFileContent);
+        unlink($sTmpFile);
+    }
+}
+
+?>
diff --git a/src/vitis/vas/rest/class/vmlib/files/Local_files.class.inc b/src/vitis/vas/rest/class/vmlib/files/Local_files.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..d70ae3ba70ada4412fcc31916c4e7cd8160e83c8
--- /dev/null
+++ b/src/vitis/vas/rest/class/vmlib/files/Local_files.class.inc
@@ -0,0 +1,275 @@
+<?php
+
+require_once ("Files.interface.inc");
+
+class Local_files implements Files{
+
+    private $oProperties;
+
+    function __construct($properties){
+        $this->oProperties = $properties;
+    }
+
+    /**
+     *This method return the extension of a file.
+     *@param string $sFilePath File's path.
+     *@return string|boolean hash sha1 of file content or false if the file doesn't exist.
+     */
+    public function getFileEtag($sFilePath){
+        if(file_exists($sFilePath)){
+            return sha1(file_get_contents($sFilePath), false);
+        } else {
+            return false;
+        }
+
+    }
+
+    /**
+     *verify if a file exists.
+     *@param string $sFilePath File's path.
+     *@return boolean true if file exists, false else.
+     */
+    public function file_exists ($sFilePath){
+        return file_exists($sFilePath);
+    }
+    /**
+     *Write a string in a file.
+     *@param string $sFilePath File's path.
+     *@param string $sData string to write in this file.
+     *@param integer $iFlags flags to write in file (http://php.net/manual/fr/function.file-put-contents.php) Default : 0.
+     *@param resource $mContext result de stream_context_create().
+     *@return integer|boolean number of byte written, or false if the process encounter an error.
+     */
+    public function file_put_contents ($sFilePath, $sData, $iFlags = 0, $mContext = null){
+        return file_put_contents($sFilePath, $sData, $iFlags, $mContext);
+    }
+    /**
+     *read a file and return content in a string.
+     *@param string $sFilePath File's path.
+     *@param boolean $bUseIncludePath use include var to resolve a relative path.
+     *@param resource $mContext result de stream_context_create().
+     *@param integer $iOffset offset in bytes to begin file reading, Default : 0.
+     *@param integer $iMaxLen Number of byte to read from the file, Default : -1 = read until the file's end.
+     *@return string|boolean file content, or false if the process encounter an error.
+     */
+    public function file_get_contents ($sFilePath, $bUseIncludePath = FALSE, $mContext = null, $iOffset = 0, $iMaxLen = -1){
+        if ($iMaxLen == -1){
+            return file_get_contents ($sFilePath, $bUseIncludePath, null, $iOffset);
+        } else {
+            return file_get_contents ($sFilePath, $bUseIncludePath, null, $iOffset, $iMaxLen);
+        }
+    }
+    /**
+     *read a file and return content in a string if eTag matches.
+     *@param string $sFilePath File's path.
+     *@param string $sEtag Hash Sha1 of file's content.
+     *@param boolean $bUseIncludePath use include var to resolve a relative path.
+     *@param resource $mContext result de stream_context_create().
+     *@param integer $iOffset offset in bytes to begin file reading, Default : 0.
+     *@param integer $iMaxLen Number of byte to read from the file, Default : -1 = read until the file's end.
+     *@return string|boolean file content, or false if the process encounter an error.
+     */
+    public function file_get_contents_with_etag ($sFilePath, $sEtag ,$bUseIncludePath = FALSE, $mContext = null, $iOffset = 0, $iMaxLen = -1){
+        $sProcessedEtag = $this->getFileEtag($sFilePath);
+        if ($sEtag == $sProcessedEtag){
+            return $this->file_get_contents($sFilePath, $bUseIncludePath, $mContext, $iOffset, $iMaxLen);
+        } else {
+            return false;
+        }
+    }
+    /**
+     *copy a file.
+     *@param string $sSourceFilePath File's path to copy.
+     *@param string $sDestFilePath File's destination.
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function copy ($sSourceFilePath, $sDestFilePath){
+        return copy ($sSourceFilePath, $sDestFilePath);
+    }
+    /**
+     *return the size of a file in bytes.
+     *@param string $sFilePath File's path.
+     *@return integer|boolean File's size in bytes or false if the process encounter an error.
+     */
+    public function filesize ($sFilePath){
+        return filesize($sFilePath);
+    }
+    /**
+     *send file's content into stdout.
+     *@param string $sFilePath File's path.
+     *@param boolean $bUseIncludePath use include var to resolve a relative path.
+     *@param resource $mContext result de stream_context_create().
+     *@return integer|boolean File's size in bytes or false if the process encounter an error.
+     */
+    public function readfile ($sFilePath, $bUseIncludePath = FALSE, $mContext = null){
+        return readfile($sFilePath, $bUseIncludePath, $mContext);
+    }
+    /**
+     *move a file.
+     *@param string $sSourceFilePath File's path to copy.
+     *@param string $sDestFilePath File's destination.
+     *@param resource $mContext result de stream_context_create().
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function rename ($sSourceFilePath, $sDestFilePath, $mContext = null){
+        if(empty($mContext)){
+            return rename($sSourceFilePath, $sDestFilePath);
+        }else{
+            return rename($sSourceFilePath, $sDestFilePath, $mContext);
+        }
+    }
+    /**
+     *remove a file.
+     *@param string $sFilePath File's path.
+     *@param resource $mContext result de stream_context_create().
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function unlink ($sFilePath, $mContext = null){
+        if(empty($mContext)){
+            return unlink($sFilePath);
+        } else {
+            return unlink($sFilePath, $mContext);
+        }
+    }
+    /**
+     *return the number of second UNIX of the last modification on a file.
+     *@param string $sFilePath File's path.
+     *@return integer|boolean timestamp on sucess or false if the process encounter an error.
+     */
+    public function filemtime ($sFilePath){
+        return filemtime($sFilePath);
+    }
+    /**
+     *return the fomrated date of the last modification on a file.
+     *@param string $sFilePath File's path.
+     *@param string $sFormat Format to convert the timestamp.
+     *@return string|boolean date string on sucess or false if the process encounter an error.
+     */
+    public function filemtime_formated($sFilePath, $sFormat){
+        return date ($sFormat, $this->filemtime($sFilePath));
+    }
+    /**
+     *return the metadata structure of a file.
+     *@param string $sFilePath File's path.
+     *@return array filename, size, lastModification, href.
+     */
+    public function getFileInfos ($sFilePath){
+        $iFileSize = $this->filesize($sFilePath);
+
+        $sFileSize = $iFileSize . " octets";
+        if($iFileSize > 1024){
+            if($iFileSize > 1024*1024){
+                if($iFileSize > 1024*1024*1024){
+                    $sFileSize = "-";
+                } else {
+                    $sFileSize = (ceil($iFileSize/(1024*1024))) . "Mo";
+                }
+            }else{
+                $sFileSize = (ceil($iFileSize/1024)) . "Ko";
+            }
+        }
+
+        $aFileName = explode("/", $sFilePath);
+
+        return array("filename"=>$aFileName[count($aFileName) - 1], "size"=>$sFileSize, "lastModification"=> $this->filemtime_formated ($sFilePath, "d/m/Y H:i:s"), "href" => $this->getProxyPassUrl($sFilePath));
+    }
+    /**
+     *return an url to download the file through Vitis API .
+     *@param string $sFilePath File's path.
+     *@return string url.
+     */
+    public function getProxyPassUrl ($sFilePath){
+        $date = new DateTime();
+        $sDataUrl = $this->oProperties['web_server_name'] . "/rest/vitis/file_downloader?key=[KEY]&eTag=[ETAG]&d=" . $date->getTimestamp();
+
+        $sFileUrl = str_replace("[KEY]", str_replace($this->oProperties['ws_data_dir'], "ws_data" , $sFilePath), $sDataUrl);
+        $sFileUrl = str_replace("[ETAG]", sha1(file_get_contents($sFilePath), false), $sFileUrl);
+
+        return $sFileUrl;
+    }
+    public function scandir($sDirPath, $iSortOrder = SCANDIR_SORT_ASCENDING, $mContext = null){
+        if(empty($mContext)){
+            return scandir($sDirPath, $iSortOrder);
+        }else{
+            return scandir($sDirPath, $iSortOrder, $mContext);
+        }
+    }
+    public function mkdir($sDirPath, $iMode = 0777, $bRecursive = FALSE, $mContext = null){
+        if(empty($mContext)){
+            return mkdir($sDirPath, $iMode, $bRecursive);
+        }else{
+            return mkdir($sDirPath, $iMode, $bRecursive, $mContext);
+        }
+    }
+    public function rmdir($sDirPath, $mContext = null){
+        if(empty($mContext)){
+            return rmdir($sDirPath);
+        }else{
+            return rmdir($sDirPath, $mContext);
+        }
+    }
+    public function is_dir($sDirPath){
+        return is_dir($sDirPath);
+    }
+    public function getFolderInfos($sDirPath){
+         if($this->is_dir($sDirPath)){
+             $aContentDir = $this->scandir($sDirPath);
+             $aTree = $this->getFileInfos($sDirPath);
+             $aDir = array();
+             for ($i =0 ; $i < count($aContentDir); $i++){
+                 if($aContentDir[$i] !== "." && $aContentDir[$i] !== ".."){
+                     array_push($aDir, $this->getFolderInfos($sDirPath . "/" . $aContentDir[$i]));
+                 }
+             }
+
+             $aTree["content"] = $aDir;
+             unset($aTree["href"]);
+             return $aTree;
+         } else {
+             return $this->getFileInfos($sDirPath);
+         }
+    }
+    public function clearDir($sDirPath){
+        $ouverture = @opendir($sDossier);
+        if (!$ouverture)
+            return;
+        while ($sFichier = readdir($ouverture)) {
+
+            if ($sFichier == '.' || $sFichier == '..')
+                continue;
+            if ($this->is_dir($sDossier . "/" . $sFichier)) {
+                $bCleared = $this->clearDir($sDossier . "/" . $sFichier);
+                if (!$bCleared)
+                    return false;
+            }
+            else {
+                $bCleared = @unlink($sDossier . "/" . $sFichier);
+                if (!$bCleared)
+                    return false;
+            }
+        }
+        closedir($ouverture);
+        $bCleared = @rmdir($sDossier);
+        if (!$bCleared)
+            return false;
+        return true;
+    }
+    public function copyDirectory($sDirPathSrc, $sDirPathDest){
+        $dir = opendir($src);
+        @mkdir($dst);
+        while(false !== ( $file = readdir($dir)) ) {
+            if (( $file != '.' ) && ( $file != '..' )) {
+                if ( is_dir($src . '/' . $file) ) {
+                    $this->copyDirectory($src . '/' . $file,$dst . '/' . $file);
+                }
+                else {
+                    copy($src . '/' . $file,$dst . '/' . $file);
+                }
+            }
+        }
+        closedir($dir);
+    }
+}
+
+
+?>
diff --git a/src/vitis/vas/rest/class/vmlib/files/S3_files.class.inc b/src/vitis/vas/rest/class/vmlib/files/S3_files.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..8287713ad3db09a0b78c73e2b510919391255113
--- /dev/null
+++ b/src/vitis/vas/rest/class/vmlib/files/S3_files.class.inc
@@ -0,0 +1,534 @@
+<?php
+
+require_once ("Files.interface.inc");
+require_once ("vmlib/phpUtil.inc");
+require_once ("vmlib/logUtil.inc");
+require_once ("aws_sdk/aws-autoloader.php");
+
+use Aws\Credentials\CredentialProvider;
+
+class S3_files implements Files{
+
+    private $oProperties;
+    private $oS3Client;
+
+    function __construct($properties){
+        $this->oProperties = $properties;
+
+        $oProvider = CredentialProvider::ini($properties['fileS3UploaderProfil'], $properties['AWSCredentialsFilePath']);
+        $oProvider = CredentialProvider::memoize($oProvider);
+        // create client s3
+        $this->oS3Client = new Aws\S3\S3Client(array(
+            'version'=>'latest',
+            'region'=> $properties['fileS3UploaderRegion'],
+            //'profile'=> $properties['fileS3UploaderProfil'],
+            'credentials' => $oProvider,
+            'debug' => false
+        ));
+    }
+    /**
+     *parse vitis properties ti extract bucket name and bucket prefix.
+     *@private
+     *@return array bucket'name, prefix.
+     */
+    private function getBucketConst(){
+        $sBucket = $this->oProperties['fileS3UploaderBucket'];
+        $sPrefix = "";
+
+        if (strpos($sBucket, "/") > -1){
+            $aBucket = explode("/", $sBucket );
+            $sBucket = $aBucket[0];
+            $sPrefix = implode("/", array_slice($aBucket, 1));
+        }
+
+        return array($sBucket, $sPrefix);
+    }
+    /**
+     *This method return the extension of a file.
+     *@param string $sFilePath File's path.
+     *@return string|boolean hash md5 of file content or false if the file doesn't exist.
+     */
+    public function getFileEtag($sFilePath){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        try {
+            $oResult = $this->oS3Client->headObject(array(
+                'Bucket' => $sBucket,
+                'Key'    => $sFilePath)
+            );
+
+            return str_replace('"', '', $oResult["ETag"]);
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *verify if a file exists.
+     *@param string $sFilePath File's path.
+     *@return boolean true if file exists, false else.
+     */
+    public function file_exists ($sFilePath){
+
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        try {
+            $this->oS3Client->headObject(array(
+                'Bucket' => $sBucket,
+                'Key'    => $sFilePath)
+            );
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+        return true;
+    }
+    /**
+     *Write a string in a file.
+     *@param string $sFilePath File's path.
+     *@param string $sData string to write in this file.
+     *@param integer $iFlags flags to write in file (http://php.net/manual/fr/function.file-put-contents.php) Default : 0.
+     *@param resource $mContext result de stream_context_create().
+     *@return integer|boolean number of byte written, or false if the process encounter an error.
+     */
+    public function file_put_contents ($sFilePath, $sData, $iFlags = 0, $mContext = null){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        try {
+            $this->oS3Client->putObject(array(
+                'Bucket' => $sBucket,
+                'Key'    => $sFilePath,
+                'Body'   => $sData,
+            )
+        );
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+        return strlen($sData);
+    }
+    /**
+     *read a file and return content in a string.
+     *@param string $sFilePath File's path.
+     *@param boolean $bUseIncludePath use include var to resolve a relative path.
+     *@param resource $mContext result de stream_context_create().
+     *@param integer $iOffset offset in bytes to begin file reading, Default : 0.
+     *@param integer $iMaxLen Number of byte to read from the file, Default : -1 = read until the file's end.
+     *@return string|boolean file content, or false if the process encounter an error.
+     */
+    public function file_get_contents ($sFilePath, $bUseIncludePath = FALSE, $mContext = null, $iOffset = 0, $iMaxLen = -1){
+
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        $sPath = $this->oProperties['extract_dir'] . "/" . getUniqRandomId();
+
+        try{
+            $this->oS3Client->getObject(array(
+              'Bucket' => $sBucket,
+              'Key' => $sFilePath,
+              'SaveAs' => $sPath
+            ));
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            unlink($sPath);
+            return false;
+        }
+
+        $sFile = "";
+
+        if ($iMaxLen == -1){
+            $sFile =  file_get_contents ($sPath, $bUseIncludePath, null, $iOffset);
+        } else {
+            $sFile =  file_get_contents ($sPath, $bUseIncludePath, null, $iOffset, $iMaxLen);
+        }
+        unlink($sPath);
+        return $sFile;
+    }
+    /**
+     *read a file and return content in a string if eTag matches.
+     *@param string $sFilePath File's path.
+     *@param string $sEtag Hash Sha1 of file's content.
+     *@param boolean $bUseIncludePath use include var to resolve a relative path.
+     *@param resource $mContext result de stream_context_create().
+     *@param integer $iOffset offset in bytes to begin file reading, Default : 0.
+     *@param integer $iMaxLen Number of byte to read from the file, Default : -1 = read until the file's end.
+     *@return string|boolean file content, or false if the process encounter an error.
+     */
+    public function file_get_contents_with_etag ($sFilePath, $sEtag ,$bUseIncludePath = FALSE, $mContext = null, $iOffset = 0, $iMaxLen = -1){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        $sPath = $this->oProperties['extract_dir'] . "/" . getUniqRandomId();
+
+        try{
+            $this->oS3Client->getObject(array(
+              'Bucket' => $sBucket,
+              'Key' => $sFilePath,
+              'IfMatch' => $sEtag,
+              'SaveAs' => $sPath
+            ));
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            unlink($sPath);
+            return false;
+        }
+        $sFile = "";
+
+        if ($iMaxLen == -1){
+            $sFile =  file_get_contents ($sPath, $bUseIncludePath, null, $iOffset);
+        } else {
+            $sFile =  file_get_contents ($sPath, $bUseIncludePath, null, $iOffset, $iMaxLen);
+        }
+        unlink($sPath);
+        return $sFile;
+    }
+    /**
+     *copy a file in the same bucket.
+     *@param string $sSourceFilePath Object's key to copy.
+     *@param string $sDestFilePath Object's destination key.
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function copy ($sSourceFilePath, $sDestFilePath){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sDestFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sDestFilePath);
+        $sSourceFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sSourceFilePath);
+
+        try{
+            $this->oS3Client->copyObject(array(
+              'Bucket' => $sBucket,
+              'Key' => $sDestFilePath,
+              'CopySource' => $sBucket . "/" . $sSourceFilePath
+            ));
+            return true;
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *copy a file in another bucket.
+     *@param string $sSourceFilePath Object's key to copy.
+     *@param string $sDests3Key Object's destination key.
+     *@param string $sDestBucket Object's destination bucket.
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function copyInAnotherBucket ($sSourceFilePath, $sDests3Key, $sDestBucket){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sSourceFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sSourceFilePath);
+
+        try{
+            $this->oS3Client->copyObject(array(
+              'Bucket' => $sDestBucket,
+              'Key' => $sDests3Key,
+              'CopySource' => $sBucket . "/" . $sSourceFilePath
+            ));
+            return true;
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *send a local file to S3.
+     *@param string $sSourceFilePath File's path to copy.
+     *@param string $sDestFilePath Object's destination key.
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function copyLocalToS3 ($sSourceFilePath, $sDestFilePath){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sDestFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sDestFilePath);
+
+        try {
+            $this->oS3Client->putObject(array(
+                'Bucket' => $sBucket,
+                'Key'    => $sDestFilePath,
+                'Body'   => file_get_contents($sSourceFilePath),
+            )
+        );
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+        return true;
+    }
+    /**
+     *return the size of a file in bytes.
+     *@param string $sFilePath File's path.
+     *@return integer|boolean File's size in bytes or false if the process encounter an error.
+     */
+    public function filesize ($sFilePath){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        try {
+            $oResult = $this->oS3Client->headObject(array(
+                'Bucket' => $sBucket,
+                'Key'    => $sFilePath)
+            );
+
+            return $oResult["ContentLength"];
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *send file's content into stdout.
+     *@param string $sFilePath File's path.
+     *@param boolean $bUseIncludePath use include var to resolve a relative path.
+     *@param resource $mContext result de stream_context_create().
+     *@return integer|boolean File's size in bytes or false if the process encounter an error.
+     */
+    public function readfile ($sFilePath, $bUseIncludePath = FALSE, $mContext = null){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        $sPath = $this->oProperties['extract_dir'] . "/" . getUniqRandomId();
+
+        try{
+            $this->oS3Client->getObject(array(
+              'Bucket' => $sBucket,
+              'Key' => $sFilePath,
+              'SaveAs' => $sPath
+            ));
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            unlink($sPath);
+            return false;
+        }
+
+        $iLength = readfile($sPath, $bUseIncludePath, $mContext);
+        unlink($sPath);
+        return $iLength;
+    }
+    /**
+     *move a file.
+     *@param string $sSourceFilePath File's path to copy.
+     *@param string $sDestFilePath File's destination.
+     *@param resource $mContext result de stream_context_create().
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function rename ($sSourceFilePath, $sDestFilePath, $mContext = null){
+        $bReturn = $this->copy($sSourceFilePath, $sDestFilePath);
+        if ($bReturn)
+            $bReturn = $this->unlink($sSourceFilePath, $mContext);
+        return $bReturn;
+    }
+    /**
+     *remove a file.
+     *@param string $sFilePath File's path.
+     *@param resource $mContext result de stream_context_create().
+     *@return boolean true on sucess or false if the process encounter an error.
+     */
+    public function unlink ($sFilePath, $mContext = null){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        try{
+            $this->oS3Client->deleteObject(array(
+              'Bucket' => $sBucket,
+              'Key' => $sFilePath
+            ));
+            return true;
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *return the number of second UNIX of the last modification on a file.
+     *@param string $sFilePath File's path.
+     *@return integer|boolean timestamp on sucess or false if the process encounter an error.
+     */
+    public function filemtime ($sFilePath){
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+
+        try {
+            $oResult = $this->oS3Client->headObject(array(
+                'Bucket' => $sBucket,
+                'Key'    => $sFilePath)
+            );
+
+            return $oResult["LastModified"]->format("U");
+        }catch (Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *return the fomrated date of the last modification on a file.
+     *@param string $sFilePath File's path.
+     *@param string $sFormat Format to convert the timestamp.
+     *@return string|boolean date string on sucess or false if the process encounter an error.
+     */
+    public function filemtime_formated ($sFilePath, $sFormat){
+        return date ($sFormat, $this->filemtime($sFilePath));
+    }
+    /**
+     *return the metadata structure of a file.
+     *@param string $sFilePath File's path.
+     *@return array filename, size, lastModification, href.
+     */
+    public function getFileInfos ($sFilePath){
+        $iFileSize = $this->filesize($sFilePath);
+
+        $sFileSize = $iFileSize . " octets";
+        if($iFileSize > 1024){
+            if($iFileSize > 1024*1024){
+                if($iFileSize > 1024*1024*1024){
+                    $sFileSize = "-";
+                } else {
+                    $sFileSize = (ceil($iFileSize/(1024*1024))) . "Mo";
+                }
+            }else{
+                $sFileSize = (ceil($iFileSize/1024)) . "Ko";
+            }
+        }
+
+        $aFileName = explode("/", $sFilePath);
+
+        return array("filename"=>$aFileName[count($aFileName) - 1], "size"=>$sFileSize, "lastModification"=> $this->filemtime_formated ($sFilePath, "d/m/Y H:i:s"), "href" => $this->getProxyPassUrl($sFilePath));
+    }
+    /**
+     *return an url to download the file through Vitis API .
+     *@param string $sFilePath File's path.
+     *@return string url.
+     */
+    public function getProxyPassUrl ($sFilePath){
+        $sEtag = $this->getFileEtag($sFilePath);
+        list($sBucket, $sPrefix) = $this->getBucketConst();
+        $sFilePath = str_replace($this->oProperties["vas_home"], $sPrefix , $sFilePath);
+        $date = new DateTime();
+        $sDataUrl = $this->oProperties['web_server_name'] . "/rest/vitis/file_downloader?key=[KEY]&eTag=[ETAG]&d=" . $date->getTimestamp();
+
+        $sFileUrl = str_replace("[KEY]", str_replace($this->oProperties['ws_data_dir'], "ws_data" , $sFilePath), $sDataUrl);
+        $sFileUrl = str_replace("[ETAG]", $sEtag, $sFileUrl);
+
+        return $sFileUrl;
+    }
+    /**
+     *scan a directory with a depth of 1.
+     *@param string $sDirPath Directory's path.
+     *@param integer $iSortOrder flag (http://php.net/manual/fr/function.scandir.php).
+     *@param resource $mContext result de stream_context_create().
+     *@return array list of file and subdirectoy .
+     */
+    public function scandir($sDirPath, $iSortOrder = SCANDIR_SORT_ASCENDING, $mContext = null){
+        $aReturn = array(".", "..");
+        // traitement du bucket et de ses sous-dossiers
+       list($sBucket, $sPrefix) = $this->getBucketConst();
+       $sListPrefix = str_replace($this->oProperties["vas_home"], $sPrefix , $sDirPath);
+      // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
+      if (strpos($sListPrefix, '/') === 0){
+          $sListPrefix = substr($sListPrefix, 1);
+      }
+      if (substr($sListPrefix, -1) !== "/"){
+          $sListPrefix .= "/";
+      }
+       try{
+           $aList = $this->oS3Client->listObjectsV2(array(
+               'Bucket' => $sBucket,
+               'Prefix' => $sListPrefix
+           ));
+
+            if ($aList["KeyCount"] > 0){
+               foreach ($aList["Contents"] as $aObject){
+                   $sObjectPath = str_replace($sListPrefix, "", $aObject["Key"]);
+                   $aObjectPath = explode("/", $sObjectPath);
+                   if(!empty($aObjectPath[0])){
+                       array_push($aReturn, $aObjectPath[0]);
+                   }
+               }
+            }
+            if($iSortOrder === SCANDIR_SORT_ASCENDING){
+                sort($aReturn);
+            }
+            if($iSortOrder === SCANDIR_SORT_DESCENDING){
+                rsort($aReturn);
+            }
+            return $aReturn;
+        }catch(Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    public function mkdir($sDirPath, $iMode = 0777, $bRecursive = FALSE, $mContext = null){
+        // ne sert à rien dans un stockage d'objet
+        return false;
+    }
+    public function rmdir($sDirPath, $mContext = null){
+        // ne sert à rien dans un stockage d'objet (pas de dossier vide ou peu favoriser clearDir)
+        return false;
+    }
+    /**
+     *define if the path is a directory or a file .
+     *@param string $sDirPath directory's path.
+     *@return boolean true if it's a dir, false else.
+     */
+    public function is_dir($sDirPath){
+        // traitement du bucket et de ses sous-dossiers
+       list($sBucket, $sPrefix) = $this->getBucketConst();
+       $sListPrefix = str_replace($this->oProperties["vas_home"], $sPrefix , $sDirPath);
+      // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
+      if (strpos($sListPrefix, '/') === 0){
+          $sListPrefix = substr($sListPrefix, 1);
+      }
+       try{
+           $aList = $this->oS3Client->listObjectsV2(array(
+               'Bucket' => $sBucket,
+               'Prefix' => $sListPrefix
+           ));
+
+           if ($aList["KeyCount"] > 1){
+               return true;
+           } else if ($aList["KeyCount"] == 1){
+               $iPrefixPathCount = count(explode("/", $sListPrefix));
+               $iKeyCount = count(explode("/", $aList["Contents"][0]["Key"]));
+               if ($iKeyCount > $iPrefixPathCount){
+                   return true;
+               } else {
+                   return false;
+               }
+
+           } else {
+               return false;
+           }
+        }catch(Aws\S3\Exception\S3Exception $e){
+            writeToErrorLog($e->getMessage());
+            return false;
+        }
+    }
+    /**
+     *scan a directory without depth limitation and return metadata usefull for treeview.
+     *@param string $sDirPath Directory's path.
+     *@return array list of file and subdirectory .
+     */
+    public function getFolderInfos($sDirPath){
+         if($this->is_dir($sDirPath)){
+             $aContentDir = $this->scandir($sDirPath);
+             $aTree = array(
+                     "filename"=> end(explode("/",$sDirPath)),
+                     "lastModification" => "none",
+                     "size"=> "",
+                     "content" => array()
+             );
+             for ($i =0 ; $i < count($aContentDir); $i++){
+                 if($aContentDir[$i] !== "." && $aContentDir[$i] !== ".."){
+                     array_push($aTree["content"], $this->getFolderInfos($sDirPath . "/" . $aContentDir[$i]));
+                 }
+             }
+
+             return $aTree;
+         } else {
+             return $this->getFileInfos($sDirPath);
+         }
+    }
+}
+
+
+?>