diff --git a/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc b/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc
index 261396886ebae7c4dbd9833619fbd9acb2bd8951..070378f5e227ae2c017812444b676802bc31de1e 100644
--- a/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc
+++ b/src/vitis/vas/rest/class/vmlib/files/Files.interface.inc
@@ -1,6 +1,7 @@
 <?php
 
 interface Files{
+    // File
     // PHP native functions
     public function file_exists ($sFilePath);
     public function file_put_contents ($sFilePath, $sData, $iFlags = 0, $mContext = null);
@@ -17,5 +18,17 @@ interface Files{
     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
index 715e18bf3224bfe6be2447251347241dbe0e0d72..13183cc36b572741466350223a553448457fe0e3 100644
--- a/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
+++ b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
@@ -3,14 +3,26 @@
 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 = new Local_files ($oProperties);
+                $this->oFileInterface = $this->$oLocalInterface;
                 break;
             case 's3':
                 $this->oFileInterface = new S3_files ($oProperties);
@@ -19,13 +31,334 @@ class Files_manager{
                 writeToErrorLog("The file system " . $oProperties["filesystem"] . " is not available on this server");
                 break;
         }
-        // create
     }
+    /**
+     *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"];
 
-    /*private upload_file($sNomObjet, $sFileType, $sServerPath, $sMaxSize, $aFileValues){
+      // 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
@@ -52,8 +385,18 @@ class Files_manager{
         return $aTemp2[(count($aTemp2) - 1)];
     }
 
-    public function uploadInLocalFs ($sFilePath) {
+    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
index 37f99882d54fc3c313c72114c8dddd3b480f2db4..d70ae3ba70ada4412fcc31916c4e7cd8160e83c8 100644
--- a/src/vitis/vas/rest/class/vmlib/files/Local_files.class.inc
+++ b/src/vitis/vas/rest/class/vmlib/files/Local_files.class.inc
@@ -4,7 +4,7 @@ require_once ("Files.interface.inc");
 
 class Local_files implements Files{
 
-    var $oProperties;
+    private $oProperties;
 
     function __construct($properties){
         $this->oProperties = $properties;
@@ -187,6 +187,88 @@ class Local_files implements Files{
 
         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
index ec03d5ab58e6f4ff417ff937882c590d77413908..8287713ad3db09a0b78c73e2b510919391255113 100644
--- a/src/vitis/vas/rest/class/vmlib/files/S3_files.class.inc
+++ b/src/vitis/vas/rest/class/vmlib/files/S3_files.class.inc
@@ -5,18 +5,24 @@ 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{
 
-    var $oProperties;
-    var $oS3Client;
+    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'],
+            //'profile'=> $properties['fileS3UploaderProfil'],
+            'credentials' => $oProvider,
             'debug' => false
         ));
     }
@@ -405,6 +411,123 @@ class S3_files implements Files{
 
         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);
+         }
+    }
 }