diff --git a/gtf.engine/gtf.engines/Traitement.class.inc b/gtf.engine/gtf.engines/Traitement.class.inc
index 1d3c1717b3c43cc014754285190acad1b70a1124..042bcbbd8570ed0e854e67b94ed1669275ae7ca8 100755
--- a/gtf.engine/gtf.engines/Traitement.class.inc
+++ b/gtf.engine/gtf.engines/Traitement.class.inc
@@ -121,6 +121,9 @@ class Traitement {
      * \param $oBd Connexion à la base de données.
      * \param $iDemandeId Identifiant de la demande.
      * \param $sRobotLogFile Fichier de log.
+     * \param $sParams Liste des paramètres saisis par l'utilisateur à la création de la demande.
+     * \param $aProperties Tableau des properties associés à l'application
+     * \param $sFmwFileName Nom du fichier FMW associé à la demande.
      */
     function __construct($oBd, $iDemandeId, $sRobotLogFile, $sParams, $aProperties, $sFmwFileName) {
         $this->oBd = $oBd;
@@ -133,20 +136,9 @@ class Traitement {
         // table de correspondance entre GTF et le FMW utiliser dans les fonction d'encodage 
         $this->aReplaceGTF = array("\r\n", " ", "(", ")", "$", "&", "@", "°", "'", ",", "\"", "{", "}", "[", "]", ";", "/", "\\", "é", "à");
         $this->aReplaceFME = array("<lf>", "<space>", "<openparen>", "<closeparen>", "<dollar>", "<amp>", "<at>", "<u00b0>", "<apos>", "<comma>", "<quote>", "<opencurly>", "<closecurly>", "<openbracket>", "<closebracket>", "<semicolon>", "<solidus>", "<backslash>", "<u00e9>", "<u00e0>");
-
         writeToLog(str_replace('[this->sFmwFileName]', $this->sFmwFileName, str_replace('[sParams]', $sParams, INFO_RESOURCES)), $this->sRobotLogFile);
     }
 
-    /*
-     * Initialisation du traitement.
-     * \param $oBd Connexion à la base de données.
-     * \param $iDemandeId Identifiant de la demande.
-     * \param $sLogFile Fichier de log.
-     * \param $sParams Liste des paramètres saisis par l'utilisateur à la création de la demande.
-     * \param $aProperties Tableau des properties associés à l'application
-     * \param $sFmwFileName Nom du fichier FMW associé à la demande.
-     */
-
     /**
      * Cette méthode permet de générer un tableau de paramètres à partir d'une chaîne dont les délimiteurs sont "|" et "=".
      * \param $sAllParams Chaine composé de tous les paramètres.
@@ -644,7 +636,7 @@ class Traitement {
      */
 
     function Process() {
-        $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName);
+        $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName, $this->aProperties);
         // Création du répertoire de résultat.
         $this->sResultDirectoryName = $this->createResultDirectory();
 
@@ -704,7 +696,7 @@ class Traitement {
         // Création du répertoire de résultat.
         $this->sResultDirectoryName = $this->createResultDirectory();
         // Fichiers sources en entrée et sortie.
-        $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName);
+        $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName, $this->aProperties);
         $aTGui = array();
         $aSourceFiles = array();
         $aDestinationFiles = array();
diff --git a/gtf.engine/gtf.engines/engine.php b/gtf.engine/gtf.engines/engine.php
index e044689721da4a4d2b7ec2b8cf450c9fa4ea7bcc..de4ebb04155b7ea36e52e97eef295f53241896da 100755
--- a/gtf.engine/gtf.engines/engine.php
+++ b/gtf.engine/gtf.engines/engine.php
@@ -55,6 +55,13 @@ if ($ErrorLicense == "0") {
         $oPDOResult4 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["getFmeEngine"], $aParams);
         $aFmeEngine = $oBd->ligneSuivante($oPDOResult4);
         
+        // Si stockage sur S3 -> fichiers du projet FME dans un répertoire temporaire.
+        if ($properties['fileS3Uploader'] === true) {
+            $properties["workspace_dir"] = $properties['extract_dir'] . '/workspace';
+            if (!(file_exists($properties["workspace_dir"])))
+                mkdir($properties["workspace_dir"], 0777, true);
+        }
+        
         // Variables d'environnement.
         if ($aFmeEngine['fme_engine_type_id'] == 'desktop') {
             //Recherche du Moteur V2 (ExecuteWithParams)
@@ -254,7 +261,27 @@ if ($ErrorLicense == "0") {
                             // $aAction = $oBd->ligneSuivante ($oPDOResult4);
                             // $properties["transit_dir"] = $aAction["value"];
                             // $oPDOResult4 = $oBd->fermeResultat();
-
+                            
+                            // Si stockage sur S3 -> Téléchargement de tous les fichiers du projet FME.
+                            if ($properties['fileS3Uploader'] === true) {
+                                if ($iTentative == 1) {
+                                    $sWorkspaceDir = $properties["workspace_dir"] . '/' . $aDemande['workspace_id'];
+                                    if (file_exists($sWorkspaceDir))
+                                        clearDir($sWorkspaceDir);
+                                    mkdir($sWorkspaceDir, 0777, true);
+                                    mkdir($sWorkspaceDir . '/fme', 0777, true);
+                                    $aTree = getDirectoryInfosFromWsDataDir('gtf', 'workspace', $aDemande['workspace_id'], 'fme');
+                                    if (!empty($aTree)) {
+                                        if (!empty($aTree[0]['content'])) {
+                                            foreach($aTree[0]['content'] as $aFile) {
+                                                $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $aDemande['workspace_id'], 'fme', $aFile['filename']);
+                                                file_put_contents($sWorkspaceDir . '/fme/' . $aFile['filename'], $sFmwFileContent);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            
                             //Lancement du traitement correspondant à la demande.
                             $bValidFmeLicence = false;
                             switch($aFmeEngine['fme_engine_type_id']) {
diff --git a/gtf.engine/gtf.engines/subscription.php b/gtf.engine/gtf.engines/subscription.php
index a6caaae0c62bf4c2f22d34a87e9f93f7e36ffca3..8570751ad4ff4de2be33dc8b844b5a91710c36ba 100755
--- a/gtf.engine/gtf.engines/subscription.php
+++ b/gtf.engine/gtf.engines/subscription.php
@@ -258,7 +258,7 @@ if ($oBd->erreurRencontree) {
                                 if ($bAutorisationDemande == true) {
                                     //Création d'une nouvelle demande.
                                     //writeToLog($properties["workspace_dir"],$properties["subscription_log_file"]);
-                                    $oGtfFmwParser = new GtfFmwParser($properties['vas_home'] . '/ws_data/gtf/workspace' . "/" . $aDemande['workspace_id'] . "/fme/" . $aDemande['fmw_file']);
+                                    $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $aDemande['workspace_id'] . "/fme/" . $aDemande['fmw_file'], $this->aProperties);
                                     $iNouvelId = "";
 
                                     if ($bIsFile) {
diff --git a/web_service/class/gtf_lib/GtfFmwParser.class.inc b/web_service/class/gtf_lib/GtfFmwParser.class.inc
index ca236956eefccdc01e3047c3788133eb48cdb4ee..d85789c4f27863fca87647cdd8654c35c4695a11 100755
--- a/web_service/class/gtf_lib/GtfFmwParser.class.inc
+++ b/web_service/class/gtf_lib/GtfFmwParser.class.inc
@@ -28,6 +28,7 @@ class GtfFmwParser {
     var $sSaveBuild;
     var $sRequirement;
     var $aProperties;
+    var $bDeleteFmwFile = false;
 
 // var $sOriginalName;
 
@@ -36,15 +37,20 @@ class GtfFmwParser {
      * le fichier fmw est parcouru ligne par ligne et chaque occurrence
      * correspondant à un GUI est stocké dans le tableau approrié
      */
-    function __construct($sFmwFileName, $sFmwFileContent, $aProperties) {
-        // Création du fichier temporaire.
+    function __construct($sFmwFileName, $aProperties, $sFmwFileContent = '') {
         $this->aProperties = $aProperties;
-        $this->sFmwFileName = $this->aProperties['extract_dir'] . '/' . getUniqRandomId() . '/' . $sFmwFileName;
-        $sFmwFileDirPath = pathinfo($this->sFmwFileName, PATHINFO_DIRNAME);
-        if (file_exists($sFmwFileDirPath))
-            cleardir($sFmwFileDirPath);
-        mkdir($sFmwFileDirPath, 0777, true);
-        file_put_contents($this->sFmwFileName, $sFmwFileContent);
+        // Création du fichier temporaire (si le contenu du fichier .fmw est passé et pas un nom de fichier).
+        if (!empty($sFmwFileContent)) {
+            $this->sFmwFileName = $this->aProperties['extract_dir'] . '/' . getUniqRandomId() . '/' . $sFmwFileName;
+            $sFmwFileDirPath = pathinfo($this->sFmwFileName, PATHINFO_DIRNAME);
+            if (file_exists($sFmwFileDirPath))
+                cleardir($sFmwFileDirPath);
+            mkdir($sFmwFileDirPath, 0777, true);
+            file_put_contents($this->sFmwFileName, $sFmwFileContent);
+            $this->bDeleteFmwFile = true;
+        }
+        else
+            $this->sFmwFileName = $sFmwFileName;
         //
         $oFichier = fopen(utf8_decode($this->sFmwFileName), "r");
         $sRc = chr(10); // Compatible avec FME 2014 et inférieur
@@ -639,7 +645,7 @@ class GtfFmwParser {
     function __destruct() {
         // Supprime le fichier .fmw temporaire du projet.
         $sFmwFileDirPath = pathinfo($this->sFmwFileName, PATHINFO_DIRNAME);
-        if (file_exists($sFmwFileDirPath))
+        if ($this->bDeleteFmwFile && file_exists($sFmwFileDirPath))
             cleardir($sFmwFileDirPath);
     }
 }
diff --git a/web_service/ws/Workspaces.class.inc b/web_service/ws/Workspaces.class.inc
index 2ae96b411879c5da643747ef0ed38791e4da2ab4..7db2edfa7184fd9802ecde099225d94996773c8d 100755
--- a/web_service/ws/Workspaces.class.inc
+++ b/web_service/ws/Workspaces.class.inc
@@ -409,7 +409,7 @@ class Workspaces extends GTF {
                         // Lit le contenu du fichier .fmw du projet.
                         $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $this->aValues["my_vitis_id"], 'fme', $_FILES['fmw_file']['name'][$i]);
                         // Sauve le .fmw sans les visualizers.
-                        $oFmwParser = new GtfFmwParser($_FILES['fmw_file']['name'][$i], $sFmwFileContent, $this->aProperties);
+                        $oFmwParser = new GtfFmwParser($_FILES['fmw_file']['name'][$i], $this->aProperties, $sFmwFileContent);
                         $oFmwParser->save($oFmwParser->sFmwFileName);
                         putFileContentInWsDataDir('gtf', 'workspace', $this->aValues["my_vitis_id"], 'fme', $_FILES['fmw_file']['name'][$i], file_get_contents($oFmwParser->sFmwFileName));
                         // Création des formulaires json.
@@ -538,7 +538,7 @@ class Workspaces extends GTF {
                                     // Lit le contenu du fichier .fmw du projet.
                                     $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $this->aValues["my_vitis_id"], 'fme', $_FILES['fmw_file']['name']);
                                     // Sauve le .fmw sans les visualizers.
-                                    $oFmwParser = new GtfFmwParser($_FILES['fmw_file']['name'], $sFmwFileContent, $this->aProperties);
+                                    $oFmwParser = new GtfFmwParser($_FILES['fmw_file']['name'], $this->aProperties, $sFmwFileContent);
                                     $oFmwParser->save($oFmwParser->sFmwFileName);
                                     putFileContentInWsDataDir('gtf', 'workspace', $this->aValues["my_vitis_id"], 'fme', $_FILES['fmw_file']['name'], file_get_contents($oFmwParser->sFmwFileName));
                                     // Création des formulaires json.
@@ -779,7 +779,7 @@ class Workspaces extends GTF {
                         // Lit le contenu du fichier .fmw du projet.
                         $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $this->aValues["my_vitis_id"], 'fme', $oWorkspace->aFields["fmw_file"]);
                         // Création des formulaires json.
-                        $oFmwParser = new GtfFmwParser($oWorkspace->aFields["fmw_file"], $sFmwFileContent, $this->aProperties);
+                        $oFmwParser = new GtfFmwParser($oWorkspace->aFields["fmw_file"], $this->aProperties, $sFmwFileContent);
                         $aJson = $oFmwParser->productJson($oWorkspace->aFields["name"]);
                         if (putFileContentInWsDataDir('gtf', 'workspace', $this->aValues["my_vitis_id"], 'form', 'DSubform.json', json_encode($aJson)) === false)
                             writeToErrorLog("Subform.json can't be writed : " . $sDirName . "/form/ressources/Subform.json" . "(Workspaces.class.inc : verify the folder's rights)");
@@ -877,7 +877,7 @@ class Workspaces extends GTF {
                                 // Lit le contenu du fichier .fmw du projet.
                                 $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $this->aValues["my_vitis_id"], 'fme', $this->aValues['fmw_file_name']);
                                 // Sauve le .fmw sans les visualizers.
-                                $oFmwParser = new GtfFmwParser($this->aValues['fmw_file_name'], $sFmwFileContent, $this->aProperties);
+                                $oFmwParser = new GtfFmwParser($this->aValues['fmw_file_name'], $this->aProperties, $sFmwFileContent);
                                 $oFmwParser->save($oFmwParser->sFmwFileName);
                                 putFileContentInWsDataDir('gtf', 'workspace', $this->aValues["my_vitis_id"], 'fme', $this->aValues['fmw_file_name'], file_get_contents($oFmwParser->sFmwFileName));
                                 // Création des formulaires json.
@@ -1238,7 +1238,7 @@ class Workspaces extends GTF {
         $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $this->aValues["my_vitis_id"], 'fme', $aFields['fmw_file']);
         // Remplace les métas données.
         if ($sFmwFileContent !== false) {
-            $oFmwParser = new GtfFmwParser($aFields['fmw_file'], $sFmwFileContent, $this->aProperties);
+            $oFmwParser = new GtfFmwParser($aFields['fmw_file'], $this->aProperties, $sFmwFileContent);
             // Valeurs des colonnes "last_save_date" et "last_save_build" originales.
             $aParams = array();
             $aParams['sSchemaGtf'] = array('value' => $this->aProperties['schema_gtf'], 'type' => 'schema_name');
@@ -1267,7 +1267,7 @@ class Workspaces extends GTF {
         $sFmwFileContent = getFileContentInWsDataDir("gtf", "workspace", $this->aValues["my_vitis_id"], 'fme', $aFields['fmw_file']);
         // Remplace les métas données.
         if ($sFmwFileContent !== false) {
-            $oFmwParser = new GtfFmwParser($aFields['fmw_file'], $sFmwFileContent, $this->aProperties);
+            $oFmwParser = new GtfFmwParser($aFields['fmw_file'], $this->aProperties, $sFmwFileContent);
             $oFmwParser->getBdMetadata($this->oConnection->oBd, $this->aValues["my_vitis_id"]);
             $oFmwParser->save($oFmwParser->sFmwFileName);
             putFileContentInWsDataDir('gtf', 'workspace', $this->aValues["my_vitis_id"], 'fme', $aFields['fmw_file'], file_get_contents($oFmwParser->sFmwFileName));