diff --git a/conf/_install/dependency.xml b/conf/_install/dependency.xml
index 14366ebb2ea9a48312ccc266f1e7a50413709305..43b51ea07363ab489a542d2d8967d8a7264dec44 100644
--- a/conf/_install/dependency.xml
+++ b/conf/_install/dependency.xml
@@ -5,32 +5,32 @@
 		<dependency>
 			<nature>framework</nature>
 			<name>vitis</name>
-			<version>app_vmap</version>
+			<version>next_app_vmap</version>
 		</dependency>
 		<dependency>
 			<nature>modules</nature>
 			<name>module_vmap</name>
-			<version>app_vmap</version>
+			<version>next_app_vmap</version>
 		</dependency>
 		<dependency>
 			<nature>modules</nature>
 			<name>module_vm4ms</name>
-			<version>app_vmap</version>
+			<version>next_app_vmap</version>
 		</dependency>
 		<dependency>
 			<nature>modules</nature>
 			<name>module_anc</name>
-			<version>app_vmap</version>
+			<version>next_app_vmap</version>
 		</dependency>
 		<dependency>
 			<nature>modules</nature>
 			<name>module_cadastreV2</name>
-			<version>app_vmap</version>
+			<version>next_app_vmap</version>
 		</dependency>
 		<dependency>
 			<nature>modules</nature>
 			<name>module_cadastre</name>
-			<version>app_vmap</version>
+			<version>next_app_vmap</version>
 		</dependency>
 	</dependenciesCollection>
 </installer>
diff --git a/src/module_cadastre/.gitignore b/src/module_cadastre/.gitignore
index 98ef169d65ec22973d313123ec3a178af98b7d71..d8b5d9919508b3efbd1b1fdc1d91adb22b53876d 100644
--- a/src/module_cadastre/.gitignore
+++ b/src/module_cadastre/.gitignore
@@ -1,2 +1,17 @@
-web_service/conf/properties*
-web_service/conf/version.inc
+client
+vas
+conf/closure
+conf/node_modules/
+conf/properties.json
+src/closure/conf/depswriter/
+src/vitis/vas/log/
+src/vitis/vas/public/
+src/vitis/vas/server/
+src/vitis/vas/ws_data/
+src/vitis/vas/tmp/
+src/vitis/client/modules/
+! src/vitis/client/modules/vitis/
+src/vitis/vas/rest/ws/*
+! src/vitis/vas/rest/ws/vitis/
+src/vitis/vas/sql/*
+! src/vitis/vas/sql/sqlQueries.xml
diff --git a/src/module_vmap/module/css/vmap.less b/src/module_vmap/module/css/vmap.less
index 0afd13f194d292e38f188753422b6b48c5ebab8c..cc42f401d348f812f18c9a25d00af7abcaa4dcb4 100644
--- a/src/module_vmap/module/css/vmap.less
+++ b/src/module_vmap/module/css/vmap.less
@@ -236,7 +236,7 @@ html, body {
     position: relative;
     height: 100%;
 }
-app-map > div {
+app-map > div,  app-map-compare > div{
     width: auto;
     height: 100%;
     background-color: @background;
@@ -380,7 +380,7 @@ input[readonly] {
     display: -ms-flex !important;
     display: flex !important;
 }
-#map-container{
+#map-container, #map-container-compare{
     -webkit-transition: all 300ms ease-out 0s;
     -o-transition: all 300ms ease-out 0s;
     transition: all 300ms ease-out 0s;
@@ -389,8 +389,37 @@ input[readonly] {
     height: ~"-webkit-calc(100% - 32px)";
     height: ~"-o-calc(100% - 32px)";
     height: ~"calc(100% - 32px)";
+    width : 100%;
 }
-#map-container.minus{
+#map-container.half,#map-container-compare.half{
+    width : calc(50% ~"-" @right-sidebar-width/2);
+    float: left;
+}
+#map-container-compare.half{
+  border-left: solid 2px #4a4a41;
+}
+/*#map-container.right-module-bar-present{
+   width : calc(100% ~"-" @right-sidebar-width);
+}*/
+/*#map-container.left-map-manager-open{
+   width : calc(100% ~"-" @right-sidebar-width ~"-" @left-sidebar-content-width);
+}*/
+#map-container.half.left-map-manager-open, #map-container-compare.half.left-map-manager-open{
+   width : calc(50% ~"-" @right-sidebar-width/2 ~"-" @left-sidebar-content-width/2);
+}
+#map-container.half.right-module-bar-present,#map-container-compare.half.right-module-bar-present{
+    width : calc(50% ~"-" @right-sidebar-width/2 ~"-" @left-sidebar-width/2);
+}
+#map-container.half.right-module-bar-present.left-map-manager-open,#map-container-compare.half.right-module-bar-present.left-map-manager-open{
+    width : calc(50% ~"-" @right-sidebar-width/2 ~"-" @left-sidebar-width/2 ~"-" @left-sidebar-content-width/2);
+}
+#map-container.half.right-module-bar-present.right-module-manager-open,#map-container-compare.half.right-module-bar-present.right-module-manager-open{
+    width : calc(50% ~"-" @right-sidebar-width/2 ~"-" @left-sidebar-width/2 ~"-" @right-sidebar-content-width/2);
+}
+#map-container.half.right-module-bar-present.left-map-manager-open.right-module-manager-open,#map-container-compare.half.right-module-bar-present.left-map-manager-open.right-module-manager-open{
+    width : calc(50% ~"-" @right-sidebar-width/2 ~"-" @left-sidebar-width/2 ~"-" @left-sidebar-content-width/2 ~"-" @right-sidebar-content-width/2);
+}
+#map-container.minus,#map-container-compare.minus{
     height: 95%;
     height: ~"-moz-calc(100% - 47px)";
     height: ~"-webkit-calc(100% - 47px)";
@@ -399,13 +428,13 @@ input[readonly] {
     font-size: 12px;
     padding: 0px 0px;
 }
-#map-container.open{
+#map-container.open, #map-container-compare.open{
     height: -moz-calc(100% ~"-" @botom-open-height ~"-" 47px);
     height: -webkit-calc(100% ~"-" @botom-open-height ~"-" 47px);
     height: -o-calc(100% ~"-" @botom-open-height ~"-" 47px);
     height: calc(100% ~"-" @botom-open-height ~"-" 47px);
 }
-#map-container.open2{
+#map-container.open2, #map-container-compare.open2{
     height: -moz-calc(100% ~"-" @botom-open2-height ~"-" 47px);
     height: -webkit-calc(100% ~"-" @botom-open2-height ~"-" 47px);
     height: -o-calc(100% ~"-" @botom-open2-height ~"-" 47px);
@@ -810,6 +839,35 @@ app-layertree button:hover {
     text-align: center;
     background-color: transparent;
 }
+
+.ol-target-overlay .ol-target
+{	border: 1px solid transparent;
+	box-shadow: 0 0 1px 1px #fff;
+	display: block;
+	height: 20px;
+	width: 0;
+}
+
+.ol-target-overlay .ol-target:after,
+.ol-target-overlay .ol-target:before
+{	content:"";
+	border: 1px solid #369;
+	box-shadow: 0 0 1px 1px #fff;
+	display: block;
+	width: 20px;
+	height: 0;
+	position:absolute;
+	top:9px;
+	left:-9px;
+}
+.ol-target-overlay .ol-target:after
+{	box-shadow: none;
+	height: 20px;
+	width: 0;
+	top:0px;
+	left:0px;
+}
+
 #map-name, #current-projection{
     position: initial;
 }
@@ -2371,3 +2429,12 @@ div.vmap-select-scale-alert{
     max-width: 197px !important;
     text-align: center !important;
 }
+
+#basic-tools-dropdown-comapremode{
+    margin: -10px -1px;
+    width: 30%;
+    min-width: 450px;
+    max-width: 550px;
+    min-height: 55px;
+    padding-top: 15px !important;
+}
diff --git a/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.js b/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.js
index ad663b75ea42b64cae3ef34ae7ed92a5700ea8f9..80ce27242794ab26e6305251870eb4adbaa0c17b 100644
--- a/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.js
+++ b/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.js
@@ -250,6 +250,21 @@ var oFormScope;
                         oFormValues['id_field']['options'] = aColumnsOptions;
                     }
                 }
+                if (angular.isDefined(oFormValues['geom_column'])) {
+                    if (angular.isDefined(oFormValues['geom_column']['options'])) {
+                        oFormValues['geom_column']['options'] = aColumnsOptions;
+                    }
+                }
+                if (angular.isDefined(oFormValues['search_field'])) {
+                    if (angular.isDefined(oFormValues['search_field']['options'])) {
+                        oFormValues['search_field']['options'] = aColumnsOptions;
+                    }
+                }
+                if (angular.isDefined(oFormValues['result_field'])) {
+                    if (angular.isDefined(oFormValues['result_field']['options'])) {
+                        oFormValues['result_field']['options'] = aColumnsOptions;
+                    }
+                }
             });
 
         },
diff --git a/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.json b/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.json
index b5697404c934a44fa2069f9ed2ce3be2fec2b480..17dbe0468ee4c3609c0710e359ad976f627aea44 100644
--- a/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.json
+++ b/src/module_vmap/module/forms/vmap_business_object/vmap_business_object_vmap_business_object.json
@@ -291,41 +291,76 @@
             },
             {
                 "fields": [{
-                        "type": "text",
+                        "type": "editable_select",
                         "name": "geom_column",
                         "label": "FORM_GEOM_COLUMN_DEVELOPMENT_0",
                         "required": true,
-                        "pattern": "",
-                        "nb_cols": 6,
-                        "id": "New_el_10_12_1"
+                        "nb_cols": 5
+                    }, {
+                        "type": "button",
+                        "class": "btn-group btn-group-sm margin-top-20",
+                        "nb_cols": 1,
+                        "buttons": [{
+                                "type": "button",
+                                "name": "table-datalist",
+                                "label": "FORM_GEOM_COLUMN_DEVELOPMENT_0",
+                                "class": "btn-primary",
+                                "event": "loadVMapBoFormColumns()",
+                                "glyphicon": "refresh"
+                            }
+                        ]
                     }]
             },
             {
                 "fields": [{
-                        "type": "text",
+                        "type": "editable_select",
                         "name": "search_field",
                         "label": "FORM_SEARCH_FIELD_0",
-                        "nb_cols": 6,
-                        "id": "New_el_11_13_1",
+                        "nb_cols": 5,
                         "tooltip": {
                             "title": "",
                             "content": "FORM_SEARCH_FIELD_0_TOOLTIP",
                             "container": "body"
                         }
+                    }, {
+                        "type": "button",
+                        "class": "btn-group btn-group-sm margin-top-20",
+                        "nb_cols": 1,
+                        "buttons": [{
+                                "type": "button",
+                                "name": "table-datalist",
+                                "label": "FORM_SEARCH_FIELD_0",
+                                "class": "btn-primary",
+                                "event": "loadVMapBoFormColumns()",
+                                "glyphicon": "refresh"
+                            }
+                        ]
                     }]
             },
             {
                 "fields": [{
-                        "type": "text",
+                        "type": "editable_select",
                         "name": "result_field",
                         "label": "FORM_RESULT_FIELD_0",
-                        "nb_cols": 6,
-                        "id": "New_el_12_14_1",
+                        "nb_cols": 5,
                         "tooltip": {
                             "title": "",
                             "content": "FORM_RESULT_FIELD_0_TOOLTIP",
                             "container": "body"
                         }
+                    }, {
+                        "type": "button",
+                        "class": "btn-group btn-group-sm margin-top-20",
+                        "nb_cols": 1,
+                        "buttons": [{
+                                "type": "button",
+                                "name": "table-datalist",
+                                "label": "FORM_RESULT_FIELD_0",
+                                "class": "btn-primary",
+                                "event": "loadVMapBoFormColumns()",
+                                "glyphicon": "refresh"
+                            }
+                        ]
                     }]
             },
             {
@@ -685,41 +720,76 @@
             },
             {
                 "fields": [{
-                        "type": "text",
+                        "type": "editable_select",
                         "name": "geom_column",
                         "label": "FORM_GEOM_COLUMN_DEVELOPMENT_0",
                         "required": true,
-                        "pattern": "",
-                        "nb_cols": 6,
-                        "id": "New_el_10_12_1"
+                        "nb_cols": 5
+                    }, {
+                        "type": "button",
+                        "class": "btn-group btn-group-sm margin-top-20",
+                        "nb_cols": 1,
+                        "buttons": [{
+                                "type": "button",
+                                "name": "table-datalist",
+                                "label": "FORM_GEOM_COLUMN_DEVELOPMENT_0",
+                                "class": "btn-primary",
+                                "event": "loadVMapBoFormColumns()",
+                                "glyphicon": "refresh"
+                            }
+                        ]
                     }]
             },
             {
                 "fields": [{
-                        "type": "text",
+                        "type": "editable_select",
                         "name": "search_field",
                         "label": "FORM_SEARCH_FIELD_0",
-                        "nb_cols": 6,
-                        "id": "New_el_11_13_1",
+                        "nb_cols": 5,
                         "tooltip": {
                             "title": "",
                             "content": "FORM_SEARCH_FIELD_0_TOOLTIP",
                             "container": "body"
                         }
+                    }, {
+                        "type": "button",
+                        "class": "btn-group btn-group-sm margin-top-20",
+                        "nb_cols": 1,
+                        "buttons": [{
+                                "type": "button",
+                                "name": "table-datalist",
+                                "label": "FORM_SEARCH_FIELD_0",
+                                "class": "btn-primary",
+                                "event": "loadVMapBoFormColumns()",
+                                "glyphicon": "refresh"
+                            }
+                        ]
                     }]
             },
             {
                 "fields": [{
-                        "type": "text",
+                        "type": "editable_select",
                         "name": "result_field",
                         "label": "FORM_RESULT_FIELD_0",
-                        "nb_cols": 6,
-                        "id": "New_el_12_14_1",
+                        "nb_cols": 5,
                         "tooltip": {
                             "title": "",
                             "content": "FORM_RESULT_FIELD_0_TOOLTIP",
                             "container": "body"
                         }
+                    }, {
+                        "type": "button",
+                        "class": "btn-group btn-group-sm margin-top-20",
+                        "nb_cols": 1,
+                        "buttons": [{
+                                "type": "button",
+                                "name": "table-datalist",
+                                "label": "FORM_RESULT_FIELD_0",
+                                "class": "btn-primary",
+                                "event": "loadVMapBoFormColumns()",
+                                "glyphicon": "refresh"
+                            }
+                        ]
                     }]
             },
             {
diff --git a/src/module_vmap/module/javascript/app/vmap/map/map.js b/src/module_vmap/module/javascript/app/vmap/map/map.js
index 7c0ba9a4a13165ccacc01ee5c7584bd9b561101d..fbd9fabb1a9b9305ce02faa83d8b38f4bfa9b227 100644
--- a/src/module_vmap/module/javascript/app/vmap/map/map.js
+++ b/src/module_vmap/module/javascript/app/vmap/map/map.js
@@ -389,6 +389,12 @@ nsVmap.Map = function () {
     if (oVmap['properties']['is_mobile']) {
         this_.trackGPSPosition();
     }
+
+    // Termine les dessins par le clic droit
+    this.oOpenLayersMap_.getViewport().addEventListener('contextmenu', function (evt) {
+        evt.preventDefault();
+        this_.termineDrawInteractions();
+    })
 };
 
 /**
@@ -1209,6 +1215,29 @@ nsVmap.Map.prototype.trackGPSPosition = function () {
     }
 };
 
+/**
+ * Termine all the draw interactions
+ *  
+ */
+nsVmap.Map.prototype.termineDrawInteractions = function () {
+    oVmap.log('nsVmap.Map.prototype.termineDrawInteractions');
+
+    for (var i = 0; i < this.vmapInteractions_.length; i++) {
+        if (this.vmapInteractions_[i] instanceof ol.interaction.Draw) {
+            try {
+                // Termine le dessin en cours
+                this.vmapInteractions_[i].finishDrawing();
+                // Desactive la fonctionnalié pour ne pas commencer un autre dessin
+                this.vmapInteractions_[i].setActive(false);
+                // Réactive la fonctionnalité
+                setTimeout(angular.bind(this, function(oDrawInteraction){
+                    oDrawInteraction.setActive(true);
+                }, this.vmapInteractions_[i]), 500);
+            } catch (e) {}
+        }
+    }
+};
+
 /********************************************
  *           INTERFACE MOBILE
  *******************************************/
diff --git a/src/module_vmap/module/javascript/app/vmap/map/mapcompare.js b/src/module_vmap/module/javascript/app/vmap/map/mapcompare.js
new file mode 100644
index 0000000000000000000000000000000000000000..4fdf3a756d3a58291345c3b5b19ca7a9428f311a
--- /dev/null
+++ b/src/module_vmap/module/javascript/app/vmap/map/mapcompare.js
@@ -0,0 +1,760 @@
+/* global nsVmap, ol, oVmap, goog, angular, vitisApp, bootbox */
+
+/**
+ * @author: Anthony Borghi
+ * @Description: Fichier contenant la classe nsVmap.MapCompare
+ * cette classe permet l'initialisation de la carte
+ */
+
+goog.provide('nsVmap.MapCompare');
+
+goog.require('oVmap');
+
+goog.require('ol.Map');
+goog.require('ol.View');
+goog.require('MapJSON');
+goog.require('ol.Overlay');
+goog.require('ol.source.Vector');
+goog.require('ol.layer.Vector');
+goog.require('goog.async.AnimationDelay');
+
+/**
+ * @classdesc
+ * Class {@link nsVmap.MapCompare}: initializes the map to compare
+ *
+ * @constructor
+ * @export
+ */
+nsVmap.MapCompare = function () {
+    oVmap.log("nsVmap.MapCompare");
+
+    var this_ = this;
+
+    /**
+     * Map layers
+     * @type {Array.<ol.layer>}
+     * @private
+     */
+    this.olLayers_ = [];
+
+    /**
+     * Map view
+     * @type {ol.View}
+     * @private
+     */
+    this.olView_ = new ol.View({
+        center: [0, 0],
+        zoom: 2
+    });
+
+    /**
+     * Map
+     * @type {ol.map}
+     * @private
+     */
+    this.oOpenLayersMap_ = new ol.Map({
+        layers: this.olLayers_,
+        view: this.olView_,
+        moveTolerance: 5
+    });
+
+    this.oOpenLayersMap_.getViewport().setAttribute('id', 'map1Compare');
+    /**
+     * Contient les évènements ajoutés sur la carte par la méthode addEventOnMap ou setEventOnMap
+     * @type {array}
+     * @private
+     */
+    this.vmapEvents_ = [];
+
+    /**
+     * Contient les évènements ajoutés sur la carte par la méthode addDrawInteraction ou setDrawInteraction
+     * @type {array}
+     * @private
+     */
+    this.vmapInteractions_ = [];
+
+    /**
+     * Contient les tooltips ajoutés par addTooltip
+     * @type {array}
+     * @private
+     */
+    this.vmapOverlays_ = [];
+
+    /**
+     * Initialisé dans le controlleur
+     * @type {nsVmap.Map.MapTooltip}
+     * @private
+     */
+    this.vmapTooltip_ = {};
+    // Ajoute les couches à reprojeter en cas de changement de carte dans layersToTransform_
+    this.layersToTransform_ = [];
+}
+
+/**
+ * nsVmap.Map.oOpenLayersMap_ getter
+ * @return {ol.map} Used map
+ * @export
+ * @api experimental
+ */
+nsVmap.MapCompare.prototype.getOLMap = function () {
+    return this.oOpenLayersMap_;
+};
+
+/**
+ * nsVmap.Map.olView_ setter
+ * @param {ol.View} view View to use
+ * @export
+ * @api experimental
+ */
+nsVmap.MapCompare.prototype.setOpenLayersView = function (view) {
+    this.olView_ = view;
+    this.oOpenLayersMap_.setView(this.olView_);
+};
+
+/**
+ * Use this function to add a new vector layer
+ * @param {object} opt_options
+ * @param {object} opt_options.style
+ * @param {object} opt_options.extent
+ * @param {object} opt_options.minResolution
+ * @param {object} opt_options.maxResolution
+ * @param {object} opt_options.opacity
+ * @param {object} opt_options.properties
+ * @param {object} opt_options.visible
+ * @param {object} opt_options.zIndex
+ * @returns {undefined}
+ */
+nsVmap.MapCompare.prototype.addVectorLayer = function (opt_options) {
+    oVmap.log('nsVmap.MapCompare.prototype.addVectorLayer');
+
+    var vectorLayer = new ol.layer.Vector({
+        map: this.oOpenLayersMap_,
+        source: new ol.source.Vector({
+            useSpatialIndex: false
+        }),
+        updateWhileAnimating: true,
+        updateWhileInteracting: true
+    });
+
+    if (goog.isDef(opt_options)) {
+        if (goog.isDef(opt_options.style))
+            vectorLayer.setStyle(opt_options.style);
+
+        if (goog.isDef(opt_options.extent))
+            vectorLayer.setExtent(opt_options.extent);
+
+        if (goog.isDef(opt_options.minResolution))
+            vectorLayer.setMinResolution(opt_options.minResolution);
+
+        if (goog.isDef(opt_options.maxResolution))
+            vectorLayer.setMaxResolution(opt_options.maxResolution);
+
+        if (goog.isDef(opt_options.opacity))
+            vectorLayer.setOpacity(opt_options.opacity);
+
+        if (goog.isDef(opt_options.properties))
+            vectorLayer.setProperties(opt_options.properties);
+
+        if (goog.isDef(opt_options.visible))
+            vectorLayer.setVisible(opt_options.visible);
+
+        if (goog.isDef(opt_options.zIndex))
+            vectorLayer.setZIndex(opt_options.zIndex);
+    }
+
+    // Ajoute la couche à layersToTransform_ pour que les features soient reprojetés en cas de changement de projection
+    this.layersToTransform_.push(vectorLayer);
+
+    return vectorLayer;
+};
+
+/**
+ * Remove events and interactions and then add a interaction
+ * @param {ol.interaction.Interaction} interaction
+ * @param {string|undefined} currentAction name of the current action
+ * @returns {ol.interaction.Interaction}
+ */
+nsVmap.MapCompare.prototype.setInteraction = function (interaction, currentAction) {
+    oVmap.log('nsVmap.MapCompare.prototype.setInteraction');
+    // Supprime les anciens évènements et interractions
+    this.removeActionsOnMap();
+    // Ajoute la nouvelle interaction
+    this.addInteraction(interaction);
+    // Définit l'action en cours
+    if (goog.isDef(currentAction))
+        this.setCurrentAction(currentAction);
+    return interaction;
+};
+
+/**
+ * Add a interaction
+ * @param {ol.interaction.Interaction} interaction
+ * @param {string|undefined} currentAction name of the current action
+ * @returns {ol.interaction.Interaction}
+ */
+nsVmap.MapCompare.prototype.addInteraction = function (interaction, currentAction) {
+    oVmap.log('nsVmap.MapCompare.prototype.addInteraction');
+    // Ajout de l'interaction
+    this.oOpenLayersMap_.addInteraction(interaction);
+    // Stocke l'interaction
+    this.vmapInteractions_.push(interaction);
+    // Définit l'action en cours
+    if (goog.isDef(currentAction))
+        this.setCurrentAction(currentAction);
+    return interaction;
+};
+
+/**
+ * currentAction setter
+ * @param {string} currentAction
+ * @export
+ */
+nsVmap.MapCompare.prototype.setCurrentAction = function (currentAction) {
+    var scope = angular.element($("#map1Compare")).scope();
+    scope.$evalAsync(function (scope) {
+        scope['ctrl']['currentAction'] = currentAction;
+    });
+};
+
+/**
+ * Remove the mapTooltip and the actions added by addEventOnMap, setEventOnMap, addDrawInteraction or setDrawInteraction
+ * @returns {undefined}
+ * @export
+ */
+nsVmap.MapCompare.prototype.removeActionsAndTooltips = function () {
+    this.removeActionsOnMap();
+    //this.getMapTooltip().hide();
+    for (var i = 0; i < this.vmapOverlays_.length; i++) {
+        this.vmapOverlays_[i].getElement().style.display = "none";
+    }
+};
+
+/**
+ * Remove the events and draw interactions added by addEventOnMap, setEventOnMap, addDrawInteraction or setDrawInteraction
+ * @returns {undefined}
+ * @export
+ */
+nsVmap.MapCompare.prototype.removeActionsOnMap = function () {
+    oVmap.log('nsVmap.Map.prototype.removeActionsOnMap');
+    // Supprime les évènements
+    for (var i = 0; i < this.vmapEvents_.length; i++) {
+        ol.Observable.unByKey(this.vmapEvents_[i]);
+    }
+
+    // Supprime les interractions
+    for (var i = 0; i < this.vmapInteractions_.length; i++) {
+
+        // Supprime les features occasionelles
+        if (goog.isDef(this.vmapInteractions_[i].getFeatures))
+            this.vmapInteractions_[i].getFeatures().clear();
+        this.oOpenLayersMap_.removeInteraction(this.vmapInteractions_[i]);
+    }
+
+    // Définit l'action en cours
+    this.setCurrentAction('');
+};
+
+/**
+ * Set a event on the map and remove the others.
+ * @param {string|Array.<string>} type The event type or array of event types.
+ * @param {function(?): ?} listener The listener function.
+ * @param {Object=} opt_this The object to use as `this` in `listener`.
+ * @param {string|undefined} currentAction name of the current action
+ * @return {goog.events.Key} Unique key for the listener.
+ * @export
+ */
+nsVmap.MapCompare.prototype.setEventOnMap = function (type, listener, opt_this, currentAction) {
+    oVmap.log('nsVmap.Map.prototype.setEventOnMap');
+    if (!goog.isDef(type)) {
+        console.error('setEventOnMap: type not defined');
+        return 0;
+    }
+
+    if (!goog.isDef(listener)) {
+        console.error('setEventOnMap: listener not defined');
+        return 0;
+    }
+
+    opt_this = goog.isDef(opt_this) ? opt_this : '';
+    // Supprime les anciens évènements et interractions
+    this.removeActionsOnMap();
+    // Ajoute le nouvel évènement
+    var event = this.addEventOnMap(type, listener, opt_this);
+    // Définit l'action en cours
+    if (goog.isDef(currentAction))
+        this.setCurrentAction(currentAction);
+    return event;
+};
+
+/**
+ * Add a certain type of event on the map.
+ * @param {string|Array.<string>} type The event type or array of event types.
+ * @param {function(?): ?} listener The listener function.
+ * @param {Object=} opt_this The object to use as `this` in `listener`.
+ * @param {string|undefined} currentAction name of the current action
+ * @return {goog.events.Key} Unique key for the listener.
+ * @export
+ */
+nsVmap.MapCompare.prototype.addEventOnMap = function (type, listener, opt_this, currentAction) {
+
+    if (!goog.isDef(type)) {
+        console.error('setEventOnMap: type not defined');
+        return 0;
+    }
+
+    if (!goog.isDef(listener)) {
+        console.error('setEventOnMap: listener not defined');
+        return 0;
+    }
+
+    opt_this = goog.isDef(opt_this) ? opt_this : '';
+    // Active l'évènement
+    var event = this.oOpenLayersMap_.on(type, listener, opt_this);
+    // Stocke l'évènement
+    this.vmapEvents_.push(event);
+    // Définit l'action en cours
+    if (goog.isDef(currentAction))
+        this.setCurrentAction(currentAction);
+    return event;
+};
+
+/**
+ * Get the current scale
+ * @param {object} opt_options
+ * @param {boolean|undefined} opt_options.pretty true for pretty format (ex: 1:25,000)
+ * @returns {Number|String}
+ * @export
+ */
+nsVmap.MapCompare.prototype.getScale = function (opt_options) {
+    oVmap.log('nsVmap.MapCompare.prototype.getScale');
+
+    opt_options = goog.isDef(opt_options) ? opt_options : {};
+    opt_options['pretty'] = goog.isDef(opt_options['pretty']) ? opt_options['pretty'] : false;
+
+    var wgs84Sphere_ = new ol.Sphere(6378137);
+    var projection = this.oOpenLayersMap_.getView().getProjection();
+
+    var map = oVmap.getMapCompare().getOLMap();
+
+    // récupère les coordonnées d'une ligue de 1cm (avec le zoom en cours)
+    var line = map.getView().calculateExtent([37.795275591, 0]);
+    var c1 = ol.proj.transform([line[0], line[1]], projection, 'EPSG:4326');
+    var c2 = ol.proj.transform([line[2], line[3]], projection, 'EPSG:4326');
+
+    // Récuère la longueur sur la carte de la ligne de 1cm
+    var length = wgs84Sphere_.haversineDistance(c1, c2);
+
+    // donc 1m sur la carte correspond à (length mètres dans la réalité x 100)
+    var scale = length * 100;
+
+    // Rend l'échelle sous format (1:25,000)
+    if (opt_options['pretty'] === true) {
+        scale = this.getPrettyScale(scale);
+    }
+
+    return scale;
+};
+
+/**
+ * Set the map scale
+ * @param {number} scale
+ * @returns {number} new scale
+ * @export
+ */
+nsVmap.MapCompare.prototype.setScale = function (scale) {
+    oVmap.log('nsVmap.Map.prototype.setScale');
+
+    // calcule et va à l'échelle celon une règle de 3
+    var currentScale = this.getScale();
+    var currentResolution = this.oOpenLayersMap_.getView().getResolution();
+
+    var scaleResolution = scale * currentResolution / currentScale;
+    this.oOpenLayersMap_.getView().setResolution(scaleResolution);
+
+    // Ajuste l'échelle en augementant la résolution
+    currentScale = this.getScale();
+
+    oVmap.log(currentScale);
+};
+
+/**
+ * Get the scale like (1:25,000)
+ * @param {number} scale
+ * @returns {String} scale (pretty)
+ */
+nsVmap.MapCompare.prototype.getPrettyScale = function (scale) {
+
+    // Rend l'échelle sous format (1:25,000)
+    scale = String(Math.round(scale));
+    var j = 1;
+    for (var i = scale.length - 1; i > 0; i--) {
+        if (j % 3 === 0)
+            scale = scale.slice(0, i) + ',' + scale.slice(i + Math.abs(0));
+        j++;
+    }
+    scale = '1:' + scale;
+
+    return scale;
+};
+
+/**
+ * App-specific directive wrapping the ngeo map directive. The directive's
+ * controller has a property "map" including a reference to the OpenLayers
+ * map.
+ *
+ * @return {angular.Directive} The directive specs.
+ * @constructor
+ */
+nsVmap.MapCompare.prototype.mapCompareDirective = function () {
+    oVmap.log("nsVmap.MapCompare.prototype.mapCompareDirective");
+    return {
+        restrict: 'E',
+        scope: {
+            'map': '=appMap',
+            'currentAction': '=appAction'
+        },
+        controller: 'AppMapCompareController',
+        controllerAs: 'ctrl',
+        bindToController: true,
+        template: '<div id="olMapCompare"></div>'
+    };
+};
+
+/**
+ * The application's main controller.
+ * @ngInject
+ * @constructor
+ */
+nsVmap.MapCompare.prototype.mapCompareController = function ($scope, $window, $element, $timeout) {
+    oVmap.log("nsVmap.MapCompare.prototype.mapController");
+    var this_ = this;
+
+    /**
+     * @private
+     */
+    this.$scope_ = $scope;
+
+    /**
+     * @type {object}
+     */
+    this.element = $element;
+
+    /**
+     * Animation duration
+     * @type Number
+     * @private
+     */
+    this.duration = 1000;
+
+    /**
+     * Timestamp of the last map center sync
+     */
+    this.lastMapSyncCenter_ = 0;
+
+    /**
+     * Timestamp of the last map compare center sync
+     */
+    this.lastCompareMapSyncCenter_ = 0;
+
+    /**
+     * Timestamp of the last map scale sync
+     */
+    this.lastMapSyncScale_ = 0;
+
+    /**
+     * Timestamp of the last map compare scale sync
+     */
+    this.lastCompareMapSyncScale_ = 0;
+
+    /**
+     * @type {ol.Map}
+     * @private
+     */
+    this.map = this['map'];
+    /**
+     * @type {ol.Overlay}
+     * @private
+     */
+    this.targetOverlay_ = null;
+
+    /**
+     * Objet permettant de lancer des fonctions utiles
+     * pour parser la définition de la carte
+     * @type MapJSON
+     */
+    var oMapJSON = new MapJSON({
+        'properties': oVmap['properties']
+    });
+
+    var tileSize = [oVmap['properties']['vmap']['wmsTilesWidth'], oVmap['properties']['vmap']['wmsTilesHeight']];
+
+    /**
+     * Contains the tileloaderror and imageloaderror events
+     * @private
+     */
+    this.loadErrorEventsContainer_ = [];
+
+    this.map.setTarget('olMapCompare');
+
+    $scope.$on("mapCompareChanged", function(){
+        // MAJ de la taille du composant
+        this_.map.setSize([document.getElementById('olMapCompare').offsetWidth, document.getElementById('olMapCompare').offsetHeight]);
+        if (this_.map.getLayers().getArray().length > 0)
+        this_.map.getLayers().clear();
+
+        var tree_ = oVmap.getMapManager().getCompareLayersTree();
+        var olView_ = oMapJSON.getViewFromDef(tree_, {
+            'size': this_.map.getSize(),
+            'tileSize': tileSize
+        });
+
+        var olLayers_ = oMapJSON.getLayersFromDef(tree_, {
+            'size': this_.map.getSize(),
+            'tileSize': tileSize
+        });
+        // Définit la vue de la carte
+        this_.addView(olView_);
+        // Définit les couches de la carte
+        for (var i = 0; i < olLayers_.length; i++) {
+            this_.addLayer(olLayers_[i]);
+        }
+        $timeout(function(){
+            this_.synchronizeMap();
+        }, 10);
+
+        // Rafraichit l'échelle
+        setTimeout(function () {
+            this_.updateCompareScaleMap();
+        });
+    })
+
+    /**
+     * Update the map size with animation
+     * @type goog.async.AnimationDelay
+     */
+    this.animationDelay = new goog.async.AnimationDelay(
+            function () {
+                this_.map.updateSize();
+                this_.map.renderSync();
+                if (goog.now() - start < this_.duration) {
+                    this_.animationDelay.start();
+                }
+            }, $window);
+
+    /**
+     * Watch for resizing
+     */
+    $scope.$watchCollection(function () {
+        return [this_.element.children()[0]['clientWidth'], this_.element.children()[0]['clientHeight']];
+    }, function () {
+        this_.startAnimation();
+    });
+};
+
+// Définit les directives et controlleurs
+oVmap.module.directive('appMapCompare', nsVmap.MapCompare.prototype.mapCompareDirective);
+oVmap.module.controller('AppMapCompareController', nsVmap.MapCompare.prototype.mapCompareController);
+
+/**
+ * Update the map size with animation
+ * @returns {undefined}
+ * @export
+ */
+nsVmap.MapCompare.prototype.mapCompareController.prototype.startAnimation = function () {
+    oVmap.log('nsVmap.MapCompare.prototype.mapCompareController.prototype.startAnimation');
+    start = goog.now();
+    this.animationDelay.stop();
+    this.animationDelay.start();
+};
+
+/**
+ * Update the map size with animation
+ * @returns {undefined}
+ */
+nsVmap.MapCompare.prototype.mapCompareController.prototype.synchronizeMap = function () {
+    oVmap.log('nsVmap.MapCompare.prototype.mapCompareController.prototype.synchronizeMap');
+
+    var this_ = this;
+
+    // Synchro Échelle
+    oVmap.getMap().getOLMap().getTargetElement().addEventListener('mouseenter', function(){
+        oVmap.getMap().getOLMap().on("moveend", this_.updateCompareScaleMap, this_);
+        this_.map.un("moveend", this_.updateScaleMap, this_);
+    });
+    this_.map.getTargetElement().addEventListener('mouseenter', function(){
+      oVmap.getMap().getOLMap().un("moveend", this_.updateCompareScaleMap, this_);
+      this_.map.on("moveend", this_.updateScaleMap, this_);
+    });
+
+    // Synchro centre
+    oVmap.getMap().getOLMap().on("pointerdrag", this_.updateCenterCompareMap, this_);
+    this_.map.on("pointerdrag", this_.updateCenterMap, this_);
+
+    // Synchro curseur sur l'autre carte
+    oVmap.getMap().getOLMap().on('pointermove', function(e){
+      var coord = e.coordinate;
+      //si le composant existe sur l'autre composant on le supprime
+      if(angular.element(".over-map-compare.ol-target-overlay").length > 0){
+        this_.targetOverlay_.setPosition(undefined);
+        this_.map.removeOverlay(this_.targetOverlay_);
+        this_.targetOverlay_ = undefined;
+        angular.element(".over-map-compare.ol-target-overlay").remove();
+      }
+      // si le composant n'existe pas on le crée
+      if (!this_.targetOverlay_){
+        var element = document.createElement("div");
+    		element.classList.add("ol-target");
+    		this_.targetOverlay_ = new ol.Overlay({ 'element': element });
+    		this_.targetOverlay_.setPositioning('center-center');
+    		this_.map.addOverlay(this_.targetOverlay_);
+    		element.parentElement.classList.add("ol-target-overlay");
+    		element.parentElement.classList.add("over-map");
+    		// hack to render targetOverlay before positioning it
+    		this_.targetOverlay_.setPosition([0,0]);
+    	}
+
+      var oldProjection = oVmap.getMap().getOLMap().getView().getProjection().getCode();
+      var newProjection = this_.map.getView().getProjection().getCode();
+
+      var convertCoord = ol.proj.transform(coord, oldProjection, newProjection)
+
+    	this_.targetOverlay_.setPosition(convertCoord);
+    });
+    this_.map.on('pointermove', function(e){
+      var coord = e.coordinate;
+      //si le composant existe sur l'autre composant on le supprime
+      if(angular.element(".over-map.ol-target-overlay").length > 0){
+        this_.targetOverlay_.setPosition(undefined);
+        oVmap.getMap().getOLMap().removeOverlay(this_.targetOverlay_);
+        this_.targetOverlay_ = undefined;
+        angular.element(".over-map-compare.ol-target-overlay").remove();
+      }
+      // si le composant n'existe pas on le crée
+      if (!this_.targetOverlay_){
+        var element = document.createElement("div");
+        element.classList.add("ol-target");
+        this_.targetOverlay_ = new ol.Overlay({ 'element': element });
+        this_.targetOverlay_.setPositioning('center-center');
+        oVmap.getMap().getOLMap().addOverlay(this_.targetOverlay_);
+        element.parentElement.classList.add("ol-target-overlay");
+        element.parentElement.classList.add("over-map-compare");
+        // hack to render targetOverlay before positioning it
+        this_.targetOverlay_.setPosition([0,0]);
+      }
+
+      var oldProjection = this_.map.getView().getProjection().getCode();
+      var newProjection = oVmap.getMap().getOLMap().getView().getProjection().getCode();
+
+      var convertCoord = ol.proj.transform(coord, oldProjection, newProjection)
+
+      this_.targetOverlay_.setPosition(convertCoord);
+    });
+};
+
+/**
+ * Update the map extent with animation
+ * @returns {undefined}
+ */
+nsVmap.MapCompare.prototype.mapCompareController.prototype.updateCompareScaleMap = function(e) { console.log('updateCompareScaleMap');
+    var this_ = this
+    this_.updateCenterCompareMap();
+    oVmap.getMapCompare().setScale(oVmap.getMap().getScale());
+
+    this.lastCompareMapSyncScale_ = Date.now();
+}
+
+/**
+ * Update the map extent with animation
+ * @returns {undefined}
+ */
+nsVmap.MapCompare.prototype.mapCompareController.prototype.updateScaleMap = function(e) { console.log('updateScaleMap');
+    var this_ = this
+    this_.updateCenterMap();
+    oVmap.getMap().setScale(oVmap.getMapCompare().getScale());
+
+    this.lastMapSyncScale_ = Date.now();
+}
+
+/**
+* Update the map extent with animation
+* @returns {undefined}
+*/
+nsVmap.MapCompare.prototype.mapCompareController.prototype.updateCenterMap = function(e) {
+
+    var this_ = this
+    // Récupère l'étendue de la carte principale
+    var oldCenter = this_.map.getView().getCenter();
+
+    // Récupère l'ancienne et la nouvelle projection
+    var newProjection = oVmap.getMap().getOLMap().getView().getProjection().getCode();
+    var oldProjection = this_.map.getView().getProjection().getCode();
+
+    var newCenter = ol.proj.transform(oldCenter, oldProjection, newProjection);
+    oVmap.getMap().getOLMap().getView().setCenter(newCenter);
+
+    this.lastMapSyncCenter_ = Date.now();
+}
+
+/**
+* Update the map extent with animation
+* @returns {undefined}
+*/
+nsVmap.MapCompare.prototype.mapCompareController.prototype.updateCenterCompareMap = function(e) {
+
+    var this_ = this;
+    // Récupère l'étendue de la carte principale
+    var oldCenter = oVmap.getMap().getOLMap().getView().getCenter();
+
+    // Récupère l'ancienne et la nouvelle projection
+    var oldProjection = oVmap.getMap().getOLMap().getView().getProjection().getCode();
+    var newProjection = this_.map.getView().getProjection().getCode();
+
+    var newCenter = ol.proj.transform(oldCenter, oldProjection, newProjection);
+    this_['map'].getView().setCenter(newCenter);
+
+    this.lastCompareMapSyncCenter_ = Date.now();
+}
+
+/**
+ * Add a layer on the map
+ * @param {object} olLayer
+ */
+nsVmap.MapCompare.prototype.mapCompareController.prototype.addLayer = function (olLayer) {
+    oVmap.log('nsVmap.MapCompare.prototype.mapCompareController.prototype.addLayer');
+    this['map'].addLayer(olLayer);
+};
+
+/**
+ * Add the olView
+ * @param {object} olView
+ * @returns {undefined}
+ */
+nsVmap.MapCompare.prototype.mapCompareController.prototype.addView = function (olView) {
+    oVmap.log('nsVmap.nsMapManager.LayersTree.prototype.LayertreeController.prototype.addView');
+
+    // Récupère l'étendue de la carte principale
+    var oldExtent = oVmap.getMap().getOLMap().getView().calculateExtent(this['map'].getSize());
+
+    // Récupère l'ancienne et la nouvelle projection
+    var oldProjection = oVmap.getMap().getOLMap().getView().getProjection().getCode();
+    var newProjection = olView.getProjection().getCode();
+
+    // Set le home position pour cette vue
+    olView.set('homePosition', {
+        center: olView.getCenter(),
+        resolution: olView.getResolution()
+    });
+
+    oVmap.getMapCompare().setOpenLayersView(olView);
+    this['map'].setView(olView);
+    this['proj'] = olView.getProjection().getCode();
+
+    // Reprojette en cas de changment de carte
+    if (goog.isDef(oldProjection) && goog.isDef(newProjection) && goog.isDef(oldExtent) /*&& goog.isDef(oldPosition)*/) {
+        // Reprojette l'étendue
+        var newExtent = ol.proj.transformExtent(oldExtent, oldProjection, newProjection);
+        this['map'].getView().fit(newExtent, {
+            nearest: true
+        });
+    }
+};
diff --git a/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmanager.js b/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmanager.js
index c13c9aae888788c3844528a192df7f652b71cb9a..13114d60d7874701fa6fc84a16d079e020ee1634 100644
--- a/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmanager.js
+++ b/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmanager.js
@@ -45,6 +45,12 @@ nsVmap.nsMapManager.MapManager = function () {
      * @private
      */
     this.oLayersTree_ = {};
+    /**
+     * Object which contains the layers tree
+     * @type {object}
+     * @private
+     */
+    this.oCompareLayersTree_ = {};
 
     /**
      * Objet which contains the map modal manager tool
@@ -281,20 +287,73 @@ nsVmap.nsMapManager.MapManager.prototype.loadMap = function (element) {
     });
 };
 
+/**
+ * Load a new map to compare
+ * @param {object} element Html element witch contains the url to the map.json file
+ * @param {object} element.url link to the map.json file
+ * @export
+ */
+nsVmap.nsMapManager.MapManager.prototype.loadCompareMap = function (element) {
+    oVmap.log('nsVmap.nsMapManager.MapManager.loadCompareMap');
+
+    if (oVmap['properties']['is_mobile']) {
+        oVmap.getToolsManager().getBasicTools().hideMobileMenu();
+    }
+
+    // Récupère l'url
+    var sUrl = element.getAttribute("url");
+
+    if (!goog.isDefAndNotNull(sUrl)) {
+        return 0;
+    }
+    if (sUrl.length === 0) {
+        return 0;
+    }
+
+    // Récupère l'arbre de couches
+    var this_ = this;
+    this_.getAjaxLayersTree(sUrl, function(oTree){
+
+        oVmap.log("oTree: ", oTree);
+
+        // Change la variable oLayersTree
+        this_.setCompareLayersTree(oTree);
+
+        // Rafraichit la carte
+        this_.reloadMap();
+
+        // Signale que c'est la carte utilisée
+        for (var i = 0; i < this_.oMapCatalog_['maps'].length; i++) {
+            if (this_.oMapCatalog_['maps'][i]['url'] === sUrl)
+            this_.oMapCatalog_['compareMap'] = i;
+        }
+        this_.setUsedMap('compare');
+
+        oVmap.log("oVmap.event: mapCompareChanged");
+        oVmap['scope'].$broadcast('mapCompareChanged');
+        angular.element('#map-compare-tool-btn').click();
+        setTimeout(function () {
+            oVmap.resizeLayerTools();
+        }, 1000);
+    });
+};
+
 /**
  * Put the used map to used
  * @returns {undefined}
  */
-nsVmap.nsMapManager.MapManager.prototype.setUsedMap = function () {
+nsVmap.nsMapManager.MapManager.prototype.setUsedMap = function (sKey) {
     oVmap.log('nsVmap.nsMapManager.MapManager.prototype.setUsedMap');
 
+    sKey = (goog.isDefAndNotNull(sKey)) ? sKey : 'used';
+
     // Met toutes les cartes à used = false
     for (var i = 0; i < this.oMapCatalog_['maps'].length; i++) {
-        this.oMapCatalog_['maps'][i]['used'] = false;
+        this.oMapCatalog_['maps'][i][sKey] = false;
     }
 
     // Met la carte utilisée à used = true
-    this.oMapCatalog_['maps'][this.oMapCatalog_['usedMap']]['used'] = true;
+    this.oMapCatalog_['maps'][this.oMapCatalog_[sKey + 'Map']][sKey] = true;
 
     oVmap.resizeLayerTools(false);
 };
@@ -1206,16 +1265,59 @@ nsVmap.nsMapManager.MapManager.prototype.getLayersTree = function () {
     return this.oLayersTree_;
 };
 
+/**
+ * LayersTree_ getter (also set the visibility of the layers with the new ones)
+ * @return {object} Layers tree
+ * @api experimental
+ * @export
+ */
+nsVmap.nsMapManager.MapManager.prototype.getCompareLayersTree = function () {
+
+    var oMap = oVmap.getMapCompare().getOLMap();
+    var aLayers = oMap.getLayers().getArray();
+
+    /**
+     * Recursive function that update parameters recursively
+     * @param {object} node
+     */
+    var updateOnTree = function (node) {
+        // Recursive
+        if (goog.isDef(node['children'])) {
+            for (var i = 0; i < node['children'].length; i++) {
+                updateOnTree(node['children'][i]);
+            }
+        }
+        // Update
+        if (goog.isDef(node['olLayer'])) {
+            node['visible'] = node['olLayer'].getVisible();
+            node['index'] = aLayers.indexOf(node['olLayer']);
+            node['opacity'] = node['olLayer'].getOpacity();
+        }
+    };
+
+    for (var i = 0; i < this.oCompareLayersTree_['children'].length; i++) {
+        updateOnTree(this.oCompareLayersTree_['children'][i]);
+    }
+
+    return this.oCompareLayersTree_;
+};
+
 /**
  * Get the JSON layers tree
  * @returns {String}
  * @export
  */
-nsVmap.nsMapManager.MapManager.prototype.getJSONLayersTree = function () {
+nsVmap.nsMapManager.MapManager.prototype.getJSONLayersTree = function ($bCompareLayersTree) {
 
     // recupère une copie de l'arbre des couches
     var oLayersTree = jQuery.extend(true, {}, oVmap.getMapManager().getLayersTree());
     var oMap = oVmap.getMap().getOLMap();
+
+    if($bCompareLayersTree){
+      oLayersTree = jQuery.extend(true, {}, oVmap.getMapManager().getCompareLayersTree());
+      oMap = oVmap.getMapCompare().getOLMap();
+    }
+
     var aDiscardedAttributes = [
         'olLayer',
         '$$hashKey',
@@ -1281,6 +1383,15 @@ nsVmap.nsMapManager.MapManager.prototype.getJSONLayersTree = function () {
 nsVmap.nsMapManager.MapManager.prototype.setLayersTree = function (oTree) {
     this.oLayersTree_ = oTree;
 };
+/**
+ * LayersTree_ setter
+ * @param {object} oTree Layers tree
+ * @api experimental
+ * @export
+ */
+nsVmap.nsMapManager.MapManager.prototype.setCompareLayersTree = function (oTree) {
+    this.oCompareLayersTree_ = oTree;
+};
 
 /**
  * oMapCatalog_ getter
diff --git a/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmodal/maplistlitle.js b/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmodal/maplistlitle.js
index bd1150b4f386c2807fa30a27b3638aeeb84a8c26..0782d0c2dc9c6cb82acca40e873c11c7c2ec3bb9 100644
--- a/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmodal/maplistlitle.js
+++ b/src/module_vmap/module/javascript/app/vmap/mapmanager/mapmodal/maplistlitle.js
@@ -42,7 +42,11 @@ nsVmap.nsMapManager.nsMapModal.MapListLitle.prototype.maplistlitleDirective = fu
         controller: 'AppMaplistlitleController',
         controllerAs: 'ctrl',
         bindToController: true,
-        templateUrl: oVmap['properties']['vmap_folder'] + '/' + 'template/layers/mapmodal/' + (oVmap['properties']['is_mobile'] ? 'maplistlitle_mobile.html' : 'maplistlitle.html')
+        templateUrl: oVmap['properties']['vmap_folder'] + '/' + 'template/layers/mapmodal/' + (oVmap['properties']['is_mobile'] ? 'maplistlitle_mobile.html' : 'maplistlitle.html'),
+        link : function ($scope, $element, $attrs){
+          $scope["compare"] = goog.isDefAndNotNull($attrs["compare"]);
+          $attrs.$observe("compare", function(){$scope["compare"] = goog.isDefAndNotNull($attrs["compare"])});
+        }
     };
 };
 
diff --git a/src/module_vmap/module/javascript/app/vmap/requires.js b/src/module_vmap/module/javascript/app/vmap/requires.js
index 2eae1b6a727b42ff523d7e606e3dfa5baecbe4fd..997cb30e697bb1d836e3591af4d3f28eb68c81c6 100755
--- a/src/module_vmap/module/javascript/app/vmap/requires.js
+++ b/src/module_vmap/module/javascript/app/vmap/requires.js
@@ -8,7 +8,8 @@
 goog.provide('vmap');
 goog.require('oVmap');
 goog.require('nsVmap.Map');
+goog.require('nsVmap.MapCompare');
 goog.require('nsVmap.Map.MapTooltip');
 goog.require('nsVmap.Map.MapPopup');
 goog.require('nsVmap.nsMapManager.MapManager');
-goog.require('nsVmap.nsToolsManager.ToolsManager');
\ No newline at end of file
+goog.require('nsVmap.nsToolsManager.ToolsManager');
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/basictools.js b/src/module_vmap/module/javascript/app/vmap/tools/basictools.js
index f53955c43cccd66024db099c860b32b003b11aca..32d672545e8e07809eef979e646647a798855dd1 100644
--- a/src/module_vmap/module/javascript/app/vmap/tools/basictools.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/basictools.js
@@ -17,6 +17,7 @@ goog.require('nsVmap.nsToolsManager.Select');
 goog.require('nsVmap.nsToolsManager.Insert');
 goog.require('nsVmap.nsToolsManager.Print');
 goog.require('nsVmap.nsToolsManager.Urlexporter');
+goog.require('nsVmap.nsToolsManager.Compare');
 
 
 /**
@@ -429,4 +430,4 @@ nsVmap.nsToolsManager.BasicTools.prototype.basictoolsController.prototype.locati
 
 // Définit la directive et le controller
 oVmap.module.directive('appBasictools', nsVmap.nsToolsManager.BasicTools.prototype.basictoolsDirective);
-oVmap.module.controller('AppBasictoolsController', nsVmap.nsToolsManager.BasicTools.prototype.basictoolsController);
\ No newline at end of file
+oVmap.module.controller('AppBasictoolsController', nsVmap.nsToolsManager.BasicTools.prototype.basictoolsController);
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/compare.js b/src/module_vmap/module/javascript/app/vmap/tools/compare.js
new file mode 100644
index 0000000000000000000000000000000000000000..076766831e9746bc36e12cac715b641048b9b8ed
--- /dev/null
+++ b/src/module_vmap/module/javascript/app/vmap/tools/compare.js
@@ -0,0 +1,81 @@
+/* global oVmap, nsVmap, goog, ol, vitisApp */
+
+/**
+ * @author: Anthony Borghi
+ * @Description: Fichier contenant la classe nsVmap.nsToolsManager.Urlexporter
+ * cette classe permet à l'utilisateur d'exporter une url pour un autre utilisateur
+ */
+goog.provide('nsVmap.nsToolsManager.Compare');
+
+goog.require('oVmap');
+
+/**
+ * @classdesc
+ * Class {@link nsVmap.nsToolsManager.VmapUser}
+ * @constructor
+ * @export
+ */
+nsVmap.nsToolsManager.compare = function () {
+    oVmap.log('nsVmap.nsToolsManager.Compare');
+};
+
+
+
+/**
+ * Directive
+ * @return {angular.Directive} The directive specs.
+ * @constructor
+ */
+nsVmap.nsToolsManager.compare.prototype.compareDirective = function () {
+    oVmap.log("nsVmap.nsToolsManager.compare.prototype.compareDirective");
+    return {
+        restrict: 'A',
+        scope: {
+            'map': '=appMap',
+            'lang': '=appLang'
+        },
+        controller: 'AppCompareMode',
+        controllerAs: 'ctrl',
+        bindToController: true,
+        templateUrl: oVmap['properties']['vmap_folder'] + '/' + 'template/tools/comparemapmanager.html'
+    };
+};
+
+/**
+ * Controler
+ * @constructor
+ * @param {object} $scope
+ * @returns {undefined}
+ * @ngInject
+ */
+nsVmap.nsToolsManager.compare.prototype.compareController = function ($scope, $element) {
+    oVmap.log("nsVmap.nsToolsManager.compare.prototype.compareController");
+
+    var this_ = this;
+
+    this.$scope_ = $scope;
+
+    /**
+     * The current properties
+     */
+    this['properties'] = oVmap['properties'];
+
+    /**
+     * The current token
+     */
+    this['token'] = oVmap['properties']['token'];
+
+    /**
+     * @type {boolean}
+     */
+    this["useCompareMode"] = false;
+
+    $scope.$watch("ctrl.useCompareMode", function(){
+        $scope.$root["compare_enabled"] = this_["useCompareMode"];
+    })
+
+};
+
+// Définit la directive et le controller
+oVmap.module.directive('appCompareMode', nsVmap.nsToolsManager.compare.prototype.compareDirective);
+oVmap.module.controller('AppCompareMode', nsVmap.nsToolsManager.compare.prototype.compareController);
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/infocontainer.js b/src/module_vmap/module/javascript/app/vmap/tools/infocontainer.js
index e04b0496471f34d663bfaed78a3dfe88d0e20ac2..e499814f2fbb84c8edcb52ff224fbab69d70bd8a 100644
--- a/src/module_vmap/module/javascript/app/vmap/tools/infocontainer.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/infocontainer.js
@@ -662,6 +662,7 @@ nsVmap.nsToolsManager.InfoContainer.prototype.infocontainerController.prototype.
         $("#opener-bottombar").css("visibility", "visible");
     }
     $("#map-container").addClass('minus');
+    $("#map-container-compare").addClass('minus');
 
     // Ouvre la barre
     this.$timeout(function () {
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/insert.js b/src/module_vmap/module/javascript/app/vmap/tools/insert.js
index 803d13add3e95a2916e129c4eb60e6db3b981b01..456136bce313f4f78931835bdeec5e500dec4500 100644
--- a/src/module_vmap/module/javascript/app/vmap/tools/insert.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/insert.js
@@ -187,6 +187,7 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController = function ($scope,
         this['snapOptions']['mode'] = oVmap['properties']['snapping']['defaut_snapp_mode'];
         this['snapOptions']['limit'] = oVmap['properties']['snapping']['defaut_limit'];
         this['snapOptions']['visible'] = oVmap['properties']['snapping']['defaut_visibility'];
+        this['snapOptions']['avoidSuperpositions'] = {};
     }
 
     /**
@@ -257,6 +258,11 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController = function ($scope,
      */
     $scope['aQueryableBOs'] = oVmap.getMapManager().getQueryableBusinessObjectsAsArray(true);
 
+    /**
+     * Business objects avaliable for avoiding superpositions
+     */
+    $scope['aAvoidSuperpositionsBOs'] = [];
+
     /**
      * Object to insert
      * oInsertObject.sFormDefinitionName name of the form (insert, upload, display)
@@ -366,8 +372,10 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController = function ($scope,
 
     // Au changement d'objet métier en cours d'insertion
     this.$scope_.$watch('selectedBoId', function () {
-        this_.updateInsertForm();
-        this_.selectCurrentBoForSnapping();
+        this_.updateInsertForm(null, function(){
+            this_.selectCurrentBoForSnapping();
+            this_.loadAvoidSuperpositionBos();
+        });
     });
 
     // Affiche les modales en plein écran pour la version mobile
@@ -411,6 +419,7 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.loadInsert
     });
 
     this.checkEditionScale();
+    this.loadAvoidSuperpositionBos();
 };
 
 /**
@@ -433,6 +442,40 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.selectCurr
     this.checkEditionScale();
 };
 
+
+/**
+ * Load this.aAvoidSuperpositionsBOs
+ *
+ */
+nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.loadAvoidSuperpositionBos = function () {
+    oVmap.log('nsVmap.nsToolsManager.Insert.inserttoolController.loadAvoidSuperpositionBos');
+
+    var this_ = this;
+
+    // Types de géométries pour le calcul des jointures
+    var aActiveGeomTypes = ['POLYGON', 'MULTIPOLYGON', 'GEOMETRY', 'GEOMETRYCOLLECTION'];
+
+    // Objets métiers actifs pour la calcul des jointures
+    this.$scope_['aAvoidSuperpositionsBOs'] = [];
+
+    if (goog.isDefAndNotNull(this.$scope_['oInsertObject']['sGeomType'])) {
+
+        // Si la couche en cours d'insertion est dans aActiveGeomTypes
+        if (aActiveGeomTypes.indexOf(this.$scope_['oInsertObject']['sGeomType']) !== -1) {
+            for (var i = 0; i < this_.$scope_['aQueryableBOs'].length; i++) {
+
+                // Si la couche cible est dans aActiveGeomTypes
+                if (goog.isDefAndNotNull(this_.$scope_['aQueryableBOs'][i]['bo_geom_type'])) {
+                    if(aActiveGeomTypes.indexOf(this_.$scope_['aQueryableBOs'][i]['bo_geom_type']) !== -1){
+
+                        this.$scope_['aAvoidSuperpositionsBOs'].push(this_.$scope_['aQueryableBOs'][i]);
+                    }
+                }
+            }
+        }
+    }
+}
+
 /**
  * Vérifie que l'échelle en cours respecte les spécification de l'objet métier
  */
@@ -1068,9 +1111,11 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.startDrawi
     var this_ = this;
     this.draw_.on('drawend',
             function (evt) {
-                // Si la géométrie est un cercle, alors elle est remplacée par un polygone à 32 côtés
                 var feature = evt.feature;
+                // Si la géométrie est un cercle, alors elle est remplacée par un polygone à 32 côtés
                 feature = this_.updateCircleGeoms(feature);
+                // Évite les superpositions avec les autres couches si besoin
+                this_.avoidSuperpositions(feature);
             }, this);
 
 
@@ -1141,6 +1186,118 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.updateCirc
     return feature;
 };
 
+/**
+ * Edit the given feature to avoid superpositions with layers defined in snapOptions.avoidSuperpositions
+ * @param {ol.Feature} olFeature
+ * @returns {ol.Feature}
+ */
+nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.avoidSuperpositions = function (olFeature) {
+    oVmap.log('nsVmap.nsToolsManager.Insert.inserttoolController.avoidSuperpositions');
+
+    // Objets métiers à intersecter
+    var aSuperpositionBos = [];
+    for (var bo_id in this['snapOptions']['avoidSuperpositions']) {
+        if (this['snapOptions']['avoidSuperpositions'][bo_id] === true) {
+            aSuperpositionBos.push(bo_id);
+        }
+    }
+
+    // Remplace la géométrie par celle calculée
+    if (aSuperpositionBos.length > 0) {
+        this.setDiffGeom_(aSuperpositionBos, olFeature)
+    }
+}
+
+/**
+ * Modify the feature geometry to avoid superpositions with BOs in aSuperpositionBos
+ *
+ * @param  {string} aSuperpositionBos
+ * @param  {ol.Feature} olFeature
+ * @param  {object|undefines} opt_options
+ */
+nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.setDiffGeom_ = function (aSuperpositionBos, olFeature, opt_options) {
+    oVmap.log('nsVmap.nsToolsManager.Insert.inserttoolController.setDiffGeom_');
+
+    if (!goog.isArray(aSuperpositionBos)) {
+        return 0;
+    }
+    if (!goog.isDefAndNotNull(olFeature)) {
+        return 0;
+    }
+    if (!goog.isDefAndNotNull(opt_options)) {
+        opt_options = {
+            bo_index: 0
+        }
+    }
+
+    var this_ = this;
+    var sEWKTGeom = oVmap.getEWKTFromGeom(olFeature.getGeometry());
+
+    this.getDiffGeom_(aSuperpositionBos[opt_options.bo_index], sEWKTGeom).then(function(sNewEWKTGeom){
+
+        // Remplace la géométrie
+        olFeature.setGeometry(oVmap.getGeomFromEWKT(sNewEWKTGeom));
+
+        // Relance la fonction pour les autres objets métiers
+        opt_options.bo_index ++;
+        if (opt_options.bo_index < aSuperpositionBos.length) {
+            this_.setDiffGeom_(aSuperpositionBos, olFeature, opt_options);
+        }
+    }, function(err){
+        console.error('Cannot get the diff geom: ', err)
+    });
+
+}
+
+/**
+ * Get the diff superposition geometry
+ *
+ * @param  {string} sBoId
+ * @param  {string} sEWKTGeom
+ * @return {promise}
+ */
+nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.getDiffGeom_ = function (sBoId, sEWKTGeom) {
+    oVmap.log('nsVmap.nsToolsManager.Insert.inserttoolController.getDiffGeom_');
+
+    var deferred = this.$q_.defer();
+    ajaxRequest({
+        'method': 'POST',
+        'url': oVmap['properties']['api_url'] + '/vmap/querys/' + sBoId + '/diff_geometry',
+        'headers': {
+            'X-HTTP-Method-Override': 'GET',
+            'Accept': 'application/x-vm-json'
+        },
+        'data': {
+            'intersect_geom': sEWKTGeom
+        },
+        'scope': this.$scope_,
+        'success': function (response) {
+
+            if (!goog.isDefAndNotNull(response['data'])) {
+                deferred.reject('response.data not defined');
+                return 0;
+            }
+            if (goog.isDefAndNotNull(response['data']['errorMessage'])) {
+                deferred.reject(response['data']['errorMessage']);
+                return 0;
+            }
+            if (!goog.isDefAndNotNull(response['data'][0])) {
+                deferred.reject('response.data[0] not defined');
+                return 0;
+            }
+            if (!goog.isDefAndNotNull(response['data'][0]['diff_geom'])) {
+                deferred.reject('response.data[0].diff_geom not defined');
+                return 0;
+            }
+            deferred.resolve(response['data'][0]['diff_geom']);
+        },
+        'error': function (response) {
+            deferred.reject(response);
+        }
+    });
+    return deferred.promise;
+}
+
 /**
  * Update feature for scope.oInsertObject
  */
@@ -1478,7 +1635,17 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.getMobileB
 nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.showSnappingOptionsModal = function () {
     oVmap.log('nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.showSnappingOptionsModal');
 
+    var this_ = this;
     this['tmpSnapOptions'] = angular.copy(this['snapOptions']);
+
+    this.$scope_.$applyAsync(function(){
+        for (var i = 0; i < this_.$scope_['aQueryableBOs'].length; i++) {
+            if (!goog.isDefAndNotNull(this_['tmpSnapOptions']['avoidSuperpositions'][this_.$scope_['aQueryableBOs'][i]['bo_id']])) {
+                this_['tmpSnapOptions']['avoidSuperpositions'][this_.$scope_['aQueryableBOs'][i]['bo_id']] = false;
+            }
+        }
+    });
+
     $('#vmap-insert-snap-options-modal').modal('show');
 };
 
@@ -1597,6 +1764,10 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.loadBoVect
                     oBo['bo_snapping_loaded'] = null;
                     return 0;
                 }
+                if (!goog.isDefAndNotNull(response['data'][0])) {
+                    oBo['bo_snapping_loaded'] = null;
+                    return 0;
+                }
                 if (response['data'][0]['count'] > this_['snapOptions']['snappingObjectsLimit']) {
                     oBo['bo_snapping_loaded'] = null;
                     var text = 'Limit de points atteinte pour object ';
@@ -1609,7 +1780,8 @@ nsVmap.nsToolsManager.Insert.prototype.inserttoolController.prototype.loadBoVect
                     if (goog.isDefAndNotNull(response['data'][i]['geom'])) {
                         geom = response['data'][i]['geom'];
                         aFeatures.push(new ol.Feature({
-                            geometry: oVmap.getGeomFromEWKT(geom)
+                            geometry: oVmap.getGeomFromEWKT(geom),
+                            'bo_id': bo_id
                         }));
                     }
                 }
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/print.js b/src/module_vmap/module/javascript/app/vmap/tools/print.js
index 8c779787a04216d8ac5ca2ec60d40e2b2bd29a12..efc99e6add1af7135b89c9210efd195df339902c 100644
--- a/src/module_vmap/module/javascript/app/vmap/tools/print.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/print.js
@@ -103,6 +103,9 @@ nsVmap.nsToolsManager.Print.prototype.printController = function ($timeout, $com
      */
     $scope['modelIndex'] = 0;
 
+    $scope["managePrintZoneInProgress"] = false;
+    $scope["manageComparePrintZoneInProgress"] = false;
+
     /**
      * @public
      */
@@ -173,7 +176,12 @@ nsVmap.nsToolsManager.Print.prototype.printController = function ($timeout, $com
      * The print box object
      * @private
      */
-    this.printBox_ = new nsVmap.nsToolsManager.PrintBox();
+    this.printBox_ = new nsVmap.nsToolsManager.PrintBox({'map_object':oVmap.getMap()});
+    /**
+     * The print box object
+     * @private
+     */
+    this.printBoxCompare_ = new nsVmap.nsToolsManager.PrintBox({'map_object':oVmap.getMapCompare()});
 
     // mise à jour de l'échelle dans le forulaire d'impression lors d'un mouvement sur la carte
     this.listenScaleChanges();
@@ -197,6 +205,9 @@ nsVmap.nsToolsManager.Print.prototype.printController = function ($timeout, $com
     oVmap['scope'].$on('toggleOutTools', function () {
         if (!$('#print-select-btn').hasClass('active')) {
             this_.printBox_.hide();
+            this_.printBoxCompare_.hide();
+            $scope["managePrintZoneInProgress"] = false;
+            $scope["manageComparePrintZoneInProgress"] = false;
         }
     });
 };
@@ -352,7 +363,10 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.loadModelParmas2
     oVmap.log('nsVmap.nsToolsManager.Print.printController.loadModelParmas2');
 
     // Récupère la taille de la carte this.printedMapSize_ ainsi que le coefficient this.resizeCoeff_
-    this.setPrintedMapSize(this.template_);
+    oPrintMapSize = this.getPrintedMapSize(this.template_);
+
+    this.printedMapSize_ = oPrintMapSize.printedMapSize;
+    this.resizeCoeff_ = oPrintMapSize.resizeCoeff;
 
     // Pré-rempli le champ "Résolution"
     this['resolution'] = this.resizeCoeff_;
@@ -364,6 +378,23 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.loadModelParmas2
     this.printBox_.setSize(this.printedMapSize_);
     this.printBox_.show();
 
+    if(this.$scope_["$root"]["compare_enabled"]){
+        this.oComparePrintMapSize = this.getPrintedMapSize(this.template_,"#map1Compare","#map_image_compare");
+        if(this.oComparePrintMapSize !== 0){
+            // Pré-rempli le champ "Résolution"
+            this['resolutionCompare'] = this.oComparePrintMapSize.resizeCoeff;
+
+            // Ajuste l'échelle avec le niveau de détail
+            this['currentScaleCompare'] = oVmap.getMapCompare().getPrettyScale(oVmap.getMapCompare().getScale() / this.oComparePrintMapSize.resizeCoeff);
+
+            // Dessine un carré d'impression à chaque mouvement de la carte
+            this.printBoxCompare_.setSize(this.oComparePrintMapSize.printedMapSize);
+            this.printBoxCompare_.show();
+        } else {
+            this.printBoxCompare_.hide();
+        }
+    }
+
 };
 
 /**
@@ -398,17 +429,24 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.setTemplate = fu
 };
 
 /**
- * Set this.printedMapSize_ and this.resizeCoeff_
- * @param {object} template
+ * Get the print map size and resolution coeff
+ *
+ * @param  {type} template
+ * @param  {type} sElementMapId
+ * @param  {type} sPrintId
+ * @return {object}
  */
-nsVmap.nsToolsManager.Print.prototype.printController.prototype.setPrintedMapSize = function (template) {
-    oVmap.log('nsVmap.nsToolsManager.Print.printController.setPrintedMapSize');
+nsVmap.nsToolsManager.Print.prototype.printController.prototype.getPrintedMapSize = function (template, sElementMapId, sPrintId) {
+    oVmap.log('nsVmap.nsToolsManager.Print.printController.getPrintedMapSize');
 
-    var imageDiv = $(template).find('#map_image');
+    sPrintId = (goog.isDefAndNotNull(sPrintId)) ? sPrintId : '#map_image';
+    sElementMapId = (goog.isDefAndNotNull(sElementMapId)) ? sElementMapId : '#map1';
+
+    var imageDiv = $(template).find(sPrintId);
 
     // Vérifie la présence de '#map_image'
     if (!goog.isDef(imageDiv.get(0))) {
-        console.error('Aucune balise #map_image trouvée dans le template');
+        console.error('Aucune balise ' + sPrintId + ' trouvée dans le template');
         return 0;
     }
 
@@ -423,16 +461,19 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.setPrintedMapSiz
     $(template).remove();
 
     // Vérifie si la taille de la carte est suppérieur à la taille de l'écran
-    this.resizeCoeff_ = 1;
+    var resizeCoeff = 1;
     var tmpWidth = angular.copy(mapWidth);
     var tmpHeight = angular.copy(mapHeight);
-    while (mapWidth > ($('#map1').width()) || mapHeight > ($('#map1').height())) {
-        this.resizeCoeff_++;
-        mapWidth = tmpWidth / this.resizeCoeff_;
-        mapHeight = tmpHeight / this.resizeCoeff_;
+    while (mapWidth > ($(sElementMapId).width()) || mapHeight > ($(sElementMapId).height())) {
+        resizeCoeff++;
+        mapWidth = tmpWidth / resizeCoeff;
+        mapHeight = tmpHeight / resizeCoeff;
     }
 
-    this.printedMapSize_ = [mapWidth, mapHeight];
+    return {
+        printedMapSize: [mapWidth, mapHeight],
+        resizeCoeff: resizeCoeff
+    }
 };
 
 /**
@@ -469,13 +510,32 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.changeScale = fu
 nsVmap.nsToolsManager.Print.prototype.printController.prototype.managePrintZone = function () {
     oVmap.log('nsVmap.nsToolsManager.Print.prototype.printController.prototype.managePrintZone');
 
-    if (this['currentAction'] === 'print-modifyPrintZone') {
+    if (this['currentAction'] === 'print-modifyPrintZone' && this.$scope_['managePrintZoneInProgress']) {
         this.printBox_.unmanagePrintBox();
+        this.$scope_["managePrintZoneInProgress"] = false;
     } else {
+        this.$scope_["managePrintZoneInProgress"] = true;
         this.printBox_.managePrintBox('print-modifyPrintZone');
     }
 };
 
+/**
+ * Detach the printZone from the view and allow to translate it
+ * @export
+ */
+nsVmap.nsToolsManager.Print.prototype.printController.prototype.manageComparePrintZone = function () {
+    oVmap.log('nsVmap.nsToolsManager.Print.prototype.printController.prototype.manageComparePrintZone');
+
+    if (this['currentAction'] === 'print-modifyPrintZone' && this.$scope_["manageComparePrintZoneInProgress"]) {
+        this.printBoxCompare_.unmanagePrintBox();
+        this.$scope_["manageComparePrintZoneInProgress"] = false;
+    } else {
+        //this.printBox_.unmanagePrintBox();
+        this.$scope_["manageComparePrintZoneInProgress"] = true;
+        this.printBoxCompare_.managePrintBox('print-modifyPrintZone');
+    }
+};
+
 /**
  * Prepare the print params and launch it
  * @returns {undefined}
@@ -504,15 +564,28 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.prepareAndLaunch
     var aPopupOverlayFeatures = oVmap.getMap().getPopupOverlayFeatures().getArray();
     var aSelectionOverlayFeatures = oVmap.getMap().getSelectionOverlayFeatures().getArray();
 
-    // Lance l'impression
-    var returnPrint = this.print({
+    var oPrintOptions = {
         scope: scope,
         extent: extent,
         templateId: templateId,
         printStyleId: this.$scope_['selectedPrintstyleId'],
         resolutionCoeff: this['dpi'],
         features: goog.array.concat(aLocationOverlayFeatures, aPopupOverlayFeatures, aSelectionOverlayFeatures)
-    });
+    };
+
+    // récupération des infos pour la carte de comparaison si le mode comparaison est actif
+    if(this.$scope_['$root']["compare_enabled"]){
+        if(this.oComparePrintMapSize !== 0){
+            // Enregistre l'échelle actuelle
+            this.currentScaleCompare_ = oVmap.getMapCompare().getScale({
+                'pretty': true
+            });
+            oPrintOptions.extentCompare = this.printBoxCompare_.getExtent();
+        }
+    }
+
+    // Lance l'impression
+    var returnPrint = this.print(oPrintOptions);
 
     if (returnPrint === 1) {
         // Ferme l'outil d'impression
@@ -618,9 +691,10 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.print = function
             template.innerHTML = response['data']['data'][0]['definition'];
 
             var mapImageSize = this_.getTemplateTargetSize(template, '#map_image');
+            var mapImageSizeCompare = this_.getTemplateTargetSize(template, '#map_image_compare');
             var overviewSize = this_.getTemplateTargetSize(template, '#map_overview');
 
-            var mapsJson = this_.getMapsJsonDef({
+            var oJsonDefOptions = {
                 mapId: opt_options.mapId,
                 resolutionCoeff: opt_options.resolutionCoeff,
                 extent: opt_options.extent,
@@ -628,7 +702,15 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.print = function
                 featuresZoom: opt_options.featuresZoom,
                 mapImageSize: mapImageSize,
                 overviewSize: overviewSize
-            })
+            }
+
+            if(goog.isDefAndNotNull(opt_options.extentCompare)){
+              oJsonDefOptions.extentCompare = opt_options.extentCompare;
+              oJsonDefOptions.mapIdCompare = opt_options.mapIdCompare;
+              oJsonDefOptions.mapImageSizeCompare = mapImageSizeCompare;
+            }
+
+            var mapsJson = this_.getMapsJsonDef(oJsonDefOptions);
 
             // Récupère les infos de l'utilisateur
             this_.getUserInfos_().then(function (oUserInfos) {
@@ -707,11 +789,18 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.getMapsJsonDef =
     // mapId/mapJson
     var sMapId;
     var sMapJSON;
+    var sMapIdCompare;
+    var sMapJSONCompare;
     if (goog.isDefAndNotNull(opt_options.mapId)) {
         sMapId = opt_options.mapId;
     } else {
         sMapJSON = oVmap.getMapManager().getJSONLayersTree();
     }
+    if (goog.isDefAndNotNull(opt_options.mapIdCompare)) {
+        sMapIdCompare = opt_options.mapIdCompare;
+    } else if (this.$scope_['$root']["compare_enabled"]) {
+        sMapJSONCompare = oVmap.getMapManager().getJSONLayersTree(true);
+    }
 
     // Extent
     var aExtent = goog.isDefAndNotNull(opt_options.extent) ? opt_options.extent : [];
@@ -723,13 +812,16 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.getMapsJsonDef =
         aExtent[3] + (aExtent[3] - aExtent[1])
     ];
     var sOverviewExtent = '';
+    var sCompareExtent = '';
     for (var i = 0; i < aExtent.length; i++) {
         if (i > 0) {
             sExtent += '|';
             sOverviewExtent += '|';
+            sCompareExtent += (goog.isDefAndNotNull(opt_options.extentCompare)) ? '|' : '';
         }
         sExtent += aExtent[i];
         sOverviewExtent += aOverviewExtent[i];
+        sCompareExtent += (goog.isDefAndNotNull(opt_options.extentCompare)) ? opt_options.extentCompare[i] : '';
     }
 
     // Features
@@ -771,6 +863,15 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.getMapsJsonDef =
             'features_zoom': 400
         };
     }
+    if (goog.isDefAndNotNull(opt_options.mapImageSizeCompare) && this.$scope_.$root["compare_enabled"]) {
+        var oCompareDef = {
+            'map_id': sMapIdCompare,
+            'map_json': sMapJSONCompare,
+            'image_size': (opt_options.mapImageSizeCompare[0] * resolutionCoeff) + '|' + (opt_options.mapImageSizeCompare[1] * resolutionCoeff),
+            'resolution_coeff': resolutionCoeff,
+            'extent': sCompareExtent
+        };
+    }
 
     var oMapsJson = [];
     if (goog.isDefAndNotNull(oMapDef)) {
@@ -786,6 +887,13 @@ nsVmap.nsToolsManager.Print.prototype.printController.prototype.getMapsJsonDef =
         });
     }
 
+    if (goog.isDefAndNotNull(oCompareDef)) {
+        oMapsJson.push({
+            'target': '#map_image_compare',
+            'map_definition': oCompareDef
+        });
+    }
+
     var mapsJson = JSON.stringify(oMapsJson);
 
     return mapsJson;
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/printBox.js b/src/module_vmap/module/javascript/app/vmap/tools/printBox.js
index b359736577fd4fc861e58c471cf2f0aad568d5ae..d25f47f7a8ca5d9588d23e08f23767f1ad9d6c16 100755
--- a/src/module_vmap/module/javascript/app/vmap/tools/printBox.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/printBox.js
@@ -18,11 +18,13 @@ goog.require('ol.interaction.Translate');
 nsVmap.nsToolsManager.PrintBox = function (opt_options) {
     oVmap.log('nsVmap.nsToolsManager.PrintBox');
 
-    this.map_ = oVmap.getMap().getOLMap();
-
     // Valeurs par défaut
     opt_options = goog.isDefAndNotNull(opt_options) ? opt_options : {};
 
+    this.oMap_ = (goog.isDefAndNotNull(opt_options["map_object"])? opt_options["map_object"]: oVmap.getMap());
+
+    this.map_ = this.oMap_.getOLMap();
+
     /**
      * The print box feature
      * @private
@@ -45,7 +47,7 @@ nsVmap.nsToolsManager.PrintBox = function (opt_options) {
      * @type {ol.layer.Vector}
      * @private
      */
-    this.oOpenLayersOverlay_ = oVmap.getMap().addVectorLayer();
+    this.oOpenLayersOverlay_ = this.oMap_.addVectorLayer();
 
     /**
      * @type {ol.Collection}
@@ -110,7 +112,7 @@ nsVmap.nsToolsManager.PrintBox.prototype.managePrintBox = function (sInteraction
     this.unlistenMapMovements();
 
     // Ajoute l'interaction de déplacement de la printBox
-    oVmap.getMap().setInteraction(this.translateInteraction_, sInteractionName);
+    this.oMap_.setInteraction(this.translateInteraction_, sInteractionName);
 
 };
 
@@ -122,12 +124,23 @@ nsVmap.nsToolsManager.PrintBox.prototype.unmanagePrintBox = function () {
     oVmap.log('nsVmap.nsToolsManager.PrintBox.unmanagePrintBox');
 
     // remove l'action de modification
-    oVmap.getMap().removeActionsAndTooltips();
+    this.oMap_.removeActionsAndTooltips();
 
     this.drawPrintBox();
     this.listenMapMovements();
 };
 
+/**
+ * Cancel the printZone manage interaction and adapt the view on it
+ * @export
+ */
+nsVmap.nsToolsManager.PrintBox.prototype.unmanagePrintBoxAndLock = function () {
+    oVmap.log('nsVmap.nsToolsManager.PrintBox.unmanagePrintBox');
+
+    // remove l'action de modification
+    this.oMap_.removeActionsAndTooltips();
+};
+
 /**
  * Get the print box scale
  * @returns {Number|String}
@@ -149,7 +162,7 @@ nsVmap.nsToolsManager.PrintBox.prototype.getScale = function () {
         nearest: true
     });
 
-    var scale = oVmap.getMap().getScale();
+    var scale = this.oMap_.getScale();
 
     setTimeout(function () {
         // Retrouve la position initiale
@@ -166,13 +179,13 @@ nsVmap.nsToolsManager.PrintBox.prototype.getScale = function () {
  * @export
  */
 nsVmap.nsToolsManager.PrintBox.prototype.setScale = function (newScale) {
-    
+
     // Échelle courante
     var currentScale = this.getScale();
 
     // Calcul du delta entre l'échelle courrante et l'échelle voulue
     var deltaScale = newScale / currentScale;
-    
+
     // Mise sous forme de variables pour une meilleure compréhension
     var currentExtent = this.getExtent();
     var xmin = currentExtent[0];
@@ -185,7 +198,7 @@ nsVmap.nsToolsManager.PrintBox.prototype.setScale = function (newScale) {
     // Calcul de la nouvelle hauteur/largeur de la printBox
     var newLength = length * deltaScale;
     var newHeight = height * deltaScale;
-    
+
     // Calcul des nouvelles coordonnées en fonction du centre et des nouvelles hauteur/largeur
     var center = this.printBoxFeature_.getGeometry().getInteriorPoint().getCoordinates();
     var newXmin = center[0] - newLength / 2;
@@ -198,10 +211,10 @@ nsVmap.nsToolsManager.PrintBox.prototype.setScale = function (newScale) {
     this.printBoxFeature_ = new ol.Feature({
         geometry: box
     });
-    
+
     // Supprime l'ancienne feature
     this.oOpenLayersOverlayFeatures_.clear();
-    
+
     // Ajoute la nouvelle feature
     this.oOpenLayersOverlay_.getSource().addFeature(this.printBoxFeature_);
 };
@@ -239,7 +252,7 @@ nsVmap.nsToolsManager.PrintBox.prototype.getExtent = function () {
  */
 nsVmap.nsToolsManager.PrintBox.prototype.listenMapMovements = function () {
 
-    this.printBoxEvent_ = oVmap.getMap().setEventOnMap('precompose', this.drawPrintBox, this);
+    this.printBoxEvent_ = this.oMap_.setEventOnMap('precompose', this.drawPrintBox, this);
 };
 
 /**
@@ -286,10 +299,12 @@ nsVmap.nsToolsManager.PrintBox.prototype.createPrintBox = function (printBoxSize
     var boxWidth = printBoxSize[0];
     var boxHeight = printBoxSize[1];
 
-    var x1 = $('#map1').width() / 2 - boxWidth / 2;
-    var x2 = $('#map1').width() / 2 + boxWidth / 2;
-    var y1 = $('#map1').height() / 2 - boxHeight / 2;
-    var y2 = $('#map1').height() / 2 + boxHeight / 2;
+    var sMapComponentId = this.map_.getViewport().getAttribute('id');
+
+    var x1 = $('#' + sMapComponentId).width() / 2 - boxWidth / 2;
+    var x2 = $('#' + sMapComponentId).width() / 2 + boxWidth / 2;
+    var y1 = $('#' + sMapComponentId).height() / 2 - boxHeight / 2;
+    var y2 = $('#' + sMapComponentId).height() / 2 + boxHeight / 2;
 
     var point1 = [x1, y2];
     var point3 = [x2, y1];
@@ -306,4 +321,4 @@ nsVmap.nsToolsManager.PrintBox.prototype.createPrintBox = function (printBoxSize
     boxFeature.set('pixelExtent', [x1, y1, x2, y2]);
 
     return boxFeature;
-};
\ No newline at end of file
+};
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/select/select.js b/src/module_vmap/module/javascript/app/vmap/tools/select/select.js
index 6a7eddf0e1b15822a8732b90e569e4e05093d0fd..9c89bc22cbe78198752e73c76846568ace3d2d68 100755
--- a/src/module_vmap/module/javascript/app/vmap/tools/select/select.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/select/select.js
@@ -366,6 +366,7 @@ nsVmap.nsToolsManager.Select.prototype.selectController = function ($scope, $tim
         this['snapOptions']['mode'] = oVmap['properties']['snapping']['defaut_snapp_mode'];
         this['snapOptions']['limit'] = oVmap['properties']['snapping']['defaut_limit'];
         this['snapOptions']['visible'] = oVmap['properties']['snapping']['defaut_visibility'];
+        this['snapOptions']['avoidSuperpositions'] = {};
     }
 
     /**
@@ -373,6 +374,16 @@ nsVmap.nsToolsManager.Select.prototype.selectController = function ($scope, $tim
      */
     this['tmpSnapOptions'] = angular.copy(this['snapOptions']);
 
+    /**
+     * Queryable Business Objects
+     */
+    this['aQueryableBOs'] = [];
+
+    /**
+    * Business objects avaliable for avoiding superpositions
+    */
+    $scope['aAvoidSuperpositionsBOs'] = [];
+
     /**
      * Tree resulting the various GetFeatureInfo requests
      */
@@ -523,10 +534,31 @@ nsVmap.nsToolsManager.Select.prototype.selectController = function ($scope, $tim
         features: this.oOverlayFeatures_
     });
 
-    this.modify_.on('modifyend', function () {
+    this.modify_.on('modifyend', function (evt) {
+
+        // Récupère la feature ajoutée
+        var aFeatures = evt.features.getArray();
+
+        // Évite les superpositions avec les autres couches si besoin
+        var j = 0;
+        for (var i = 0; i < aFeatures.length; i++) {
+            this_.avoidSuperpositions(aFeatures[i]).then(function(){
+                j++;
+                if (!j < aFeatures.length) {
+                    setTimeout(function () {
+                        this_.putFeaturesOnTheElement(this_.oOverlayFeatures_.getArray());
+                    });
+                }
+            });
+        }
+
+        // Cas où avoidSuperpositions n'ait pas effectué de callback
         setTimeout(function () {
-            this_.putFeaturesOnTheElement(this_.oOverlayFeatures_.getArray());
-        });
+            if (j === 0) {
+                console.error('avoidSuperpositions never sents callback');
+                this_.putFeaturesOnTheElement(this_.oOverlayFeatures_.getArray());
+            }
+        }, 3000);
     });
 
     /**
@@ -685,6 +717,39 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.loadQueryableB
     });
 };
 
+/**
+ * Load this.aAvoidSuperpositionsBOs
+ *
+ */
+nsVmap.nsToolsManager.Select.prototype.selectController.prototype.loadAvoidSuperpositionBos = function () {
+    oVmap.log('nsVmap.nsToolsManager.Select.selectController.loadAvoidSuperpositionBos');
+
+    var this_ = this;
+
+    // Types de géométries pour le calcul des jointures
+    var aActiveGeomTypes = ['POLYGON', 'MULTIPOLYGON', 'GEOMETRY', 'GEOMETRYCOLLECTION'];
+
+    // Objets métiers actifs pour la calcul des jointures
+    this.$scope_['aAvoidSuperpositionsBOs'] = [];
+
+    if (goog.isDefAndNotNull(this['editableFeatureType'])) {
+
+        // Si la couche en cours d'insertion est dans aActiveGeomTypes
+        if (aActiveGeomTypes.indexOf(this['editableFeatureType']) !== -1) {
+            for (var i = 0; i < this['aQueryableBOs'].length; i++) {
+
+                // Si la couche cible est dans aActiveGeomTypes
+                if (goog.isDefAndNotNull(this['aQueryableBOs'][i]['bo_geom_type'])) {
+                    if(aActiveGeomTypes.indexOf(this['aQueryableBOs'][i]['bo_geom_type']) !== -1){
+
+                        this.$scope_['aAvoidSuperpositionsBOs'].push(this['aQueryableBOs'][i]);
+                    }
+                }
+            }
+        }
+    }
+}
+
 /**
  * Vérifie que l'échelle en cours respecte les spécification de l'objet métier
  */
@@ -1880,6 +1945,9 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.editFeature =
         // Affiche la palette de modification
         $('#basictools-select-modify-palette').show();
 
+        // Chage le liste des BO intersectables par calcul de polygones jointifs
+        this_.loadAvoidSuperpositionBos();
+
         // Timeout car lors du toggleOutTools, clearOverlays est lancé
         setTimeout(function () {
             // Ajoute la/les feature(s)
@@ -2126,12 +2194,160 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.startDrawing =
                 this_.oOverlayLayer_.getSource().addFeature(feature);
             }
 
+            // Évite les superpositions avec les autres couches si besoin
+            this_.avoidSuperpositions(feature);
+
             // Ajoute les géométries en mode multi ou simple à editableSelection.olFeature
             this_.putFeaturesOnTheElement(this_.oOverlayFeatures_.getArray());
         });
     }, this);
 };
 
+/**
+ * Edit the given feature to avoid superpositions with layers defined in snapOptions.avoidSuperpositions
+ * @param {ol.Feature} olFeature
+ * @returns {ol.Feature}
+ */
+nsVmap.nsToolsManager.Select.prototype.selectController.prototype.avoidSuperpositions = function (olFeature) {
+    oVmap.log('nsVmap.nsToolsManager.Select.selectController.avoidSuperpositions');
+
+    var deferred = this.$q_.defer();
+
+    // Objets métiers à intersecter
+    var aSuperpositionBos = [];
+    for (var bo_id in this['snapOptions']['avoidSuperpositions']) {
+        if (this['snapOptions']['avoidSuperpositions'][bo_id] === true) {
+            aSuperpositionBos.push(bo_id);
+        }
+    }
+
+    // Remplace la géométrie par celle calculée
+    if (aSuperpositionBos.length > 0) {
+        this.setDiffGeom_(aSuperpositionBos, olFeature).then(function(olFeature){
+            deferred.resolve(olFeature);
+        });
+    } else {
+        deferred.resolve(olFeature);
+    }
+
+    return deferred.promise;
+}
+
+/**
+ * Modify the feature geometry to avoid superpositions with BOs in aSuperpositionBos
+ *
+ * @param  {string} aSuperpositionBos
+ * @param  {ol.Feature} olFeature
+ * @param  {object|undefines} opt_options
+ */
+nsVmap.nsToolsManager.Select.prototype.selectController.prototype.setDiffGeom_ = function (aSuperpositionBos, olFeature, opt_options) {
+    oVmap.log('nsVmap.nsToolsManager.Select.selectController.setDiffGeom_');
+
+    if (!goog.isArray(aSuperpositionBos)) {
+        return 0;
+    }
+    if (!goog.isDefAndNotNull(olFeature)) {
+        return 0;
+    }
+    if (!goog.isDefAndNotNull(opt_options)) {
+        opt_options = {
+            bo_index: 0
+        }
+    }
+
+    var this_ = this;
+    var deferred = this.$q_.defer();
+    var sEWKTGeom = oVmap.getEWKTFromGeom(olFeature.getGeometry());
+
+    this.getDiffGeom_(aSuperpositionBos[opt_options.bo_index], sEWKTGeom).then(function(sNewEWKTGeom){
+
+        // Remplace la géométrie
+        olFeature.setGeometry(oVmap.getGeomFromEWKT(sNewEWKTGeom));
+
+        // Relance la fonction pour les autres objets métiers
+        opt_options.bo_index ++;
+        if (opt_options.bo_index < aSuperpositionBos.length) {
+            this_.setDiffGeom_(aSuperpositionBos, olFeature, opt_options).then(function(){
+                deferred.resolve(olFeature);
+            }, function(error){
+                console.error(error);
+            });
+        } else {
+            deferred.resolve(olFeature);
+        }
+    }, function(err){
+        console.error('Cannot get the diff geom: ', err)
+    });
+
+    return deferred.promise;
+}
+
+/**
+ * Get the diff superposition geometry
+ *
+ * @param  {string} sBoId
+ * @param  {string} sEWKTGeom
+ * @return {promise}
+ */
+nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getDiffGeom_ = function (sBoId, sEWKTGeom) {
+    oVmap.log('nsVmap.nsToolsManager.Select.selectController.getDiffGeom_');
+
+    var oParams = {
+        'intersect_geom': sEWKTGeom
+    };
+
+    // Filtre pour ne pas s'éviter lui même
+    if (goog.isDefAndNotNull(this['editableSelection'])) {
+        if (this['editableSelection']['bo_type'] === sBoId) {
+            if (goog.isDefAndNotNull(this['editableSelection']['bo_id_field']) &&
+                goog.isDefAndNotNull(this['editableSelection']['bo_id_value'])) {
+
+                oParams['filter'] = {
+                    'column': this['editableSelection']['bo_id_field'],
+                    'compare_operator': '!=',
+                    'value': this['editableSelection']['bo_id_value']
+                }
+            }
+        }
+    }
+
+    var deferred = this.$q_.defer();
+    ajaxRequest({
+        'method': 'POST',
+        'url': oVmap['properties']['api_url'] + '/vmap/querys/' + sBoId + '/diff_geometry',
+        'headers': {
+            'X-HTTP-Method-Override': 'GET',
+            'Accept': 'application/x-vm-json'
+        },
+        'data': oParams,
+        'scope': this.$scope_,
+        'success': function (response) {
+
+            if (!goog.isDefAndNotNull(response['data'])) {
+                deferred.reject('response.data not defined');
+                return 0;
+            }
+            if (goog.isDefAndNotNull(response['data']['errorMessage'])) {
+                deferred.reject(response['data']['errorMessage']);
+                return 0;
+            }
+            if (!goog.isDefAndNotNull(response['data'][0])) {
+                deferred.reject('response.data[0] not defined');
+                return 0;
+            }
+            if (!goog.isDefAndNotNull(response['data'][0]['diff_geom'])) {
+                deferred.reject('response.data[0].diff_geom not defined');
+                return 0;
+            }
+            deferred.resolve(response['data'][0]['diff_geom']);
+        },
+        'error': function (response) {
+            deferred.reject(response);
+        }
+    });
+    return deferred.promise;
+}
+
 /**
  * Put the array of features passed on aFeatures on editableSelection.olFeature with MULTI... form
  * @param {array} aFeatures
@@ -2363,7 +2579,17 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.finishEdition
 nsVmap.nsToolsManager.Select.prototype.selectController.prototype.showSnappingOptionsModal = function () {
     oVmap.log('nsVmap.nsToolsManager.Select.prototype.selectController.prototype.showSnappingOptionsModal');
 
+    var this_ = this;
     this['tmpSnapOptions'] = angular.copy(this['snapOptions']);
+
+    this.$scope_.$applyAsync(function(){
+        for (var i = 0; i < this_['aQueryableBOs'].length; i++) {
+            if (!goog.isDefAndNotNull(this_['tmpSnapOptions']['avoidSuperpositions'][this_['aQueryableBOs'][i]['bo_id']])) {
+                this_['tmpSnapOptions']['avoidSuperpositions'][this_['aQueryableBOs'][i]['bo_id']] = false;
+            }
+        }
+    });
+
     $('#vmap-select-snap-options-modal').modal('show');
 };
 
@@ -2477,6 +2703,10 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.loadBoVectorSn
                     oBo['bo_snapping_loaded'] = null;
                     return 0;
                 }
+                if (!goog.isDefAndNotNull(response['data'][0])) {
+                    oBo['bo_snapping_loaded'] = null;
+                    return 0;
+                }
                 if (response['data'][0]['count'] > this_['snapOptions']['snappingObjectsLimit']) {
                     oBo['bo_snapping_loaded'] = null;
                     var text = 'Limit de points atteinte pour object ';
@@ -2489,7 +2719,8 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.loadBoVectorSn
                     if (goog.isDefAndNotNull(response['data'][i]['geom'])) {
                         geom = response['data'][i]['geom'];
                         aFeatures.push(new ol.Feature({
-                            geometry: oVmap.getGeomFromEWKT(geom)
+                            geometry: oVmap.getGeomFromEWKT(geom),
+                            'bo_id': bo_id
                         }));
                     }
                 }
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/toolsmanager.js b/src/module_vmap/module/javascript/app/vmap/tools/toolsmanager.js
index ba4c644aea4d99f191adc967b8a5f8d78f45a29a..1b6a247c6b746f13abf5c4fa6ff32e759973f169 100755
--- a/src/module_vmap/module/javascript/app/vmap/tools/toolsmanager.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/toolsmanager.js
@@ -143,13 +143,18 @@ nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsContainerDirective = funct
 
 /**
  * Basic tools Controller
+ * @param {object} $scope
  * @export
+ * @ngInject
  * @constructor
  */
-nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsController = function () {
+nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsController = function ($scope) {
     oVmap.log("nsVmap.nsToolsManager.BasicTools.prototype.vmapToolsController");
 
     this['oToolsTree'] = oVmap.getToolsManager().getToolsTree();
+
+    $scope.$root["bLoadVmapModule"] = goog.isDefAndNotNull(this['oToolsTree']);
+
     this['openedTool'] = '_';
 };
 
@@ -176,7 +181,7 @@ nsVmap.nsToolsManager.ToolsManager.prototype.loadSyncToolsTree = function () {
             oToolsTree = data['usermodules'];
         }
     });
-    
+
     return oToolsTree;
 };
 
@@ -225,4 +230,4 @@ nsVmap.nsToolsManager.ToolsManager.prototype.getTool = function (tool) {
 // Définit la directive et le controller
 oVmap.module.directive('appVmaptools', nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsDirective);
 oVmap.module.directive('toolsContainer', nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsContainerDirective);
-oVmap.module.controller('AppVmaptoolsController', nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsController);
\ No newline at end of file
+oVmap.module.controller('AppVmaptoolsController', nsVmap.nsToolsManager.ToolsManager.prototype.vmapToolsController);
diff --git a/src/module_vmap/module/javascript/app/vmap/tools/urlexporter.js b/src/module_vmap/module/javascript/app/vmap/tools/urlexporter.js
index 85e757f8f70c2bac1538b099482fd06940cec290..d89684f26f381a40125ee0d52a88f24eaa559637 100644
--- a/src/module_vmap/module/javascript/app/vmap/tools/urlexporter.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/urlexporter.js
@@ -76,16 +76,6 @@ nsVmap.nsToolsManager.Urlexporter.prototype.urlExporterController = function ($s
 
     this["urlConstructor"]();
 
-    // Affiche les modales en plein écran pour la version mobile
-    //if (oVmap['properties']['is_mobile']) {
-    //    $element.find('.modal').on('shown.bs.modal', function () {
-    //        $('.modal-backdrop.fade.in').hide();
-    //        $('.modal.fade.in').find('.modal-dialog').addClass('mobile-full-modal');
-    //    });
-    //}
-
-    console.log(this['properties']);
-
     // recalcule l'url quand on change de carte
     oVmap['scope'].$on('mapChanged', function () {
         this_["urlConstructor"]();
@@ -135,6 +125,27 @@ nsVmap.nsToolsManager.Urlexporter.prototype.urlExporterController.prototype.urlC
     this["urlToExport"] = sUrl;
 };
 
+
+/**
+ * Copy the generated URL on the clipboard
+ *
+ * @export
+ */
+nsVmap.nsToolsManager.Urlexporter.prototype.urlExporterController.prototype.copyUrl = function () {
+    oVmap.log("nsVmap.nsToolsManager.Urlexporter.urlExporterController.copyUrl");
+
+    /* Get the text field */
+    var copyText = document.getElementById("urlExporterField");
+
+    /* Select the text field */
+    copyText.select();
+
+    /* Copy the text inside the text field */
+    document.execCommand("copy");
+
+    $.notify('Copié', 'success');
+}
+
 // Définit la directive et le controller
 oVmap.module.directive('appUrlExporter', nsVmap.nsToolsManager.Urlexporter.prototype.urlExporterDirective);
-oVmap.module.controller('AppUrlExporterController', nsVmap.nsToolsManager.Urlexporter.prototype.urlExporterController);
\ No newline at end of file
+oVmap.module.controller('AppUrlExporterController', nsVmap.nsToolsManager.Urlexporter.prototype.urlExporterController);
diff --git a/src/module_vmap/module/javascript/app/vmap/vmap.js b/src/module_vmap/module/javascript/app/vmap/vmap.js
index 48dbc1bacdb92c117848b877817f120614ccbc71..f178a8c8318359837bd33d27463450bfe7744ea8 100644
--- a/src/module_vmap/module/javascript/app/vmap/vmap.js
+++ b/src/module_vmap/module/javascript/app/vmap/vmap.js
@@ -97,6 +97,13 @@ oVmap.properties = {};
  */
 oVmap.oMap_ = {};
 
+
+/**
+ * Objet which contains the mapComapre
+ * @type {nsVmap.MapCompare}
+ * @private
+ */
+oVmap.oMapCompare_ = {};
 /**
  * Objet which contains the layers tools (on the left band)
  * @type {nsVmap.nsMapManager.MapManager}
@@ -196,6 +203,7 @@ oVmap.init = function () {
 
     // Instenciation des objects Vmap
     oVmap.oMap_ = new nsVmap.Map();
+    oVmap.oMapCompare_ = new nsVmap.MapCompare();
     oVmap.oMapManager_ = new nsVmap.nsMapManager.MapManager();
     oVmap.oToolsManager_ = new nsVmap.nsToolsManager.ToolsManager();
 
@@ -283,6 +291,12 @@ oVmap.vmapController = function ($sanitize) {
      * @api stable
      */
     this.map = this['map'] = oVmap.getMap().getOLMap();
+    /**
+     * The OpenLayers map
+     * @type {ol.Map}
+     * @api stable
+     */
+    this.mapCompare = this['mapCompare'] = oVmap.getMapCompare().getOLMap();
 
     /**
      * The current action on map
@@ -362,6 +376,16 @@ oVmap.getMap = function () {
     return this.oMap_;
 };
 
+/**
+ * nsVmap.oMapCompare_ getter
+ * @return {nsVmap.MapCompare} Map to use to compare
+ * @export
+ * @api experimental
+ */
+oVmap.getMapCompare = function () {
+    return this.oMapCompare_;
+};
+
 /**
  * nsVmap.oMapManager_ getter
  * @return {nsVmap.nsMapManager.MapManager} Tools fo layers
@@ -719,6 +743,8 @@ oVmap.resizeLayerTools = function (animate) {
 
     if (goog.isDef(angular.element($('#olMap')).scope()))
         angular.element($('#olMap')).scope()['ctrl'].startAnimation();
+    if (goog.isDef(angular.element($('#olMapCompare')).scope()))
+        angular.element($('#olMapCompare')).scope()['ctrl'].startAnimation();
 
     var aItems = ["layertree", "layersorder", "maplegendcontainer"];
     var iMarge = 0;
@@ -851,6 +877,7 @@ oVmap.printElem = function (elem) {
  */
 oVmap.maxResizeBottomBar = function () {
     angular.element($('#olMap')).scope()['ctrl'].startAnimation();
+    angular.element($('#olMapCompare')).scope()['ctrl'].startAnimation();
 
     $(".open-more-selection-info").toggleClass("reverse");
 
@@ -869,13 +896,15 @@ oVmap.maxResizeBottomBar = function () {
  */
 oVmap.minResizeBottomBar = function () {
     angular.element($('#olMap')).scope()['ctrl'].startAnimation();
-
+    angular.element($('#olMapCompare')).scope()['ctrl'].startAnimation();
+    
     if ($("#map-container").hasClass("open2")) {
         $("#map-container").removeClass("open2");
         $("#bottombar").removeClass("open2");
         $(".open-more-selection-info").removeClass("reverse");
     } else if ($("#map-container").hasClass("open")) {
         $("#map-container").addClass("minus");
+        $("#map-container-compare").addClass("minus");
     }
 };
 
diff --git a/src/module_vmap/module/lang/lang-en.json b/src/module_vmap/module/lang/lang-en.json
index fc1484e29b1d7924daf36b156634486aca812d54..29d2d9f92d85c94d9d0f1e4a057bb501cf571635 100644
--- a/src/module_vmap/module/lang/lang-en.json
+++ b/src/module_vmap/module/lang/lang-en.json
@@ -287,7 +287,12 @@
     "FORM_ENABLE_GETFEATUREINFO_CONFIGURATION_VMAP_CONFIG": "Enable GetFeatureInfo selection",
     "FORM_SELECTION_BUFFER_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Buffer (en mm sur l'écran)",
     "FORM_SELECTION_MAX_SCALE_BUFFER_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Buffer maximum (en mètres sur le terrain)",
-    "TITLE_SNAPPING_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Default snapping options",
+    "TITLE_SNAPPING_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Snapping options",
+    "FORM_SNAPPING_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Manimum limit of points per object",
+    "FORM_SNAPPING_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Snapping tolerance (in pixels)",
+    "FORM_SNAPPING_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Default snapping type",
+    "FORM_SNAPPING_VISIBILITY_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Selected objects visibility",
+    "FORM_SNAPPING_AVOID_SUPERPOSITIONS_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Avoid superposition",
     "FORM_SNAPPING_DEFAUT_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Manimum limit of points per object",
     "FORM_SNAPPING_DEFAUT_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Snapping tolerance (in pixels)",
     "FORM_SNAPPING_DEFAUT_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Default snapping type",
diff --git a/src/module_vmap/module/lang/lang-fr.json b/src/module_vmap/module/lang/lang-fr.json
index 970eebf515a273666fd84369acf99d6700229a7a..82fca25d0f2fa89bab33f3cd82e694948c3b78cc 100644
--- a/src/module_vmap/module/lang/lang-fr.json
+++ b/src/module_vmap/module/lang/lang-fr.json
@@ -287,7 +287,12 @@
     "FORM_ENABLE_GETFEATUREINFO_CONFIGURATION_VMAP_CONFIG": "Interrogation par GetFeatureInfo",
     "FORM_SELECTION_BUFFER_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Buffer de sélection (en mm sur l'écran)",
     "FORM_SELECTION_MAX_SCALE_BUFFER_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Buffer maximum (en mètres sur le terrain)",
-    "TITLE_SNAPPING_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Options d'accrochage par défaut",
+    "TITLE_SNAPPING_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Options d'accrochage",
+    "FORM_SNAPPING_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Limite de points accrochables",
+    "FORM_SNAPPING_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Tolérance d'accrochage (pixels)",
+    "FORM_SNAPPING_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Type d'accrochage",
+    "FORM_SNAPPING_VISIBILITY_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Visibilité des zones d'accrochage",
+    "FORM_SNAPPING_AVOID_SUPERPOSITIONS_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Eviter les superpositions",
     "FORM_SNAPPING_DEFAUT_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Limite de points accrochables",
     "FORM_SNAPPING_DEFAUT_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Tolérance d'accrochage (pixels)",
     "FORM_SNAPPING_DEFAUT_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG": "Type d'accrochage",
diff --git a/src/module_vmap/module/template/layers/mapmodal/maplistlitle.html b/src/module_vmap/module/template/layers/mapmodal/maplistlitle.html
index 2089b99cf5622ae5d17850d76b84c3b77b3102f1..e2ff1e2f60b3b953a96db0e5bdbc0d59d69f50ab 100644
--- a/src/module_vmap/module/template/layers/mapmodal/maplistlitle.html
+++ b/src/module_vmap/module/template/layers/mapmodal/maplistlitle.html
@@ -32,6 +32,7 @@
                 <div ng-repeat="map in oTheme.maps| orderBy: 'name'">
                     <div ng-if="($index + 1) % 4 === 0" class="row">
                         <div url="{{map.url}}"
+                             ng-if="!compare"
                              title="{{map.description}}"
                              class="col-md-3 margin-10 pointer opacity-hover underline-hover maplist-map"
                              style="text-align: center; font-size: 12px;"
@@ -43,8 +44,21 @@
                                 <span>{{map.name}}</span>
                             </div>
                         </div>
+                        <div url="{{map.url}}"
+                             ng-if="compare"
+                             title="{{map.description}}"
+                             class="col-md-6 margin-10 pointer opacity-hover underline-hover maplist-map"
+                             style="text-align: center; font-size: 12px;"
+                             onclick="oVmap.getMapManager().loadCompareMap(this)"
+                             data-dismiss="modal">
+
+                            <div onclick="$('#maplistlitle-container').removeClass('open')" ng-class="{'border-black': map.compare === true}" style="overflow:hidden" ng-attr-title="{{map.description}}">
+                                <div class="img-map" style="background-image: url('{{map.thumbnail}}')"></div>
+                                <span>{{map.name}}</span>
+                            </div>
+                        </div>
                     </div>
-                    <div ng-if="($index + 1) % 4 !== 0"
+                    <div ng-if="($index + 1) % 4 !== 0 && !compare"
                          url="{{map.url}}"
                          title="{{map.description}}"
                          class="col-md-3 margin-10 pointer opacity-hover underline-hover maplist-map"
@@ -57,6 +71,19 @@
                             <span>{{map.name}}</span>
                         </div>
                     </div>
+                    <div ng-if="($index + 1) % 4 !== 0 && compare"
+                         url="{{map.url}}"
+                         title="{{map.description}}"
+                         class="col-md-6 margin-10 pointer opacity-hover underline-hover maplist-map"
+                         style="text-align: center; font-size: 12px;"
+                         onclick="oVmap.getMapManager().loadCompareMap(this)"
+                         data-dismiss="modal">
+
+                        <div onclick="$('#maplistlitle-container').removeClass('open')" ng-class="{'border-black': map.compare === true}" style="overflow:hidden" ng-attr-title="{{map.description}}">
+                            <div class="img-map" style="background-image: url('{{map.thumbnail}}')"></div>
+                            <span>{{map.name}}</span>
+                        </div>
+                    </div>
                 </div>
             </div>
         </div>
diff --git a/src/module_vmap/module/template/tools/basictools.html b/src/module_vmap/module/template/tools/basictools.html
index e85c74762d60d92d19a6b560d5811b7a178fad98..0321871288835fc992af7d5daaf74aba86e102d4 100644
--- a/src/module_vmap/module/template/tools/basictools.html
+++ b/src/module_vmap/module/template/tools/basictools.html
@@ -8,9 +8,9 @@
                 <div>
                     <li role="presentation" style="position: inherit" class="basic-tools-dropdown">
                         <a class="basic-tools-element pointer"
-                           title="Générateur d'URL"
+                           title="Lien vers la carte en cours"
                            onclick="oVmap.getToolsManager().getBasicTools().toggleTool(this)">
-                            <span class="icon-at" aria-hidden="true"></span>
+                            <span class="fa fa-link" aria-hidden="true"></span>
                         </a>
                         <div app-url-exporter app-lang="ctrl.lang" app-map="ctrl.map"
                              id="basic-tools-dropdown-urlexporter"
@@ -19,6 +19,22 @@
                         </div>
                     </li>
                 </div>
+                <!-- Outil de comparaison -->
+                <div>
+                    <li role="presentation" style="position: inherit" class="basic-tools-dropdown">
+                        <a class="basic-tools-element pointer"
+                           id="map-compare-tool-btn"
+                           title="Comparaison de carte"
+                           onclick="oVmap.getToolsManager().getBasicTools().toggleTool(this)"
+                           ng-class="{'active2':$root.compare_enabled}">
+                            <span class="icon-mirror" aria-hidden="true"></span>
+                        </a>
+                        <div app-compare-mode app-lang="ctrl.lang" app-map="ctrl.map"
+                             id="basic-tools-dropdown-comapremode"
+                             class="dropdown-menu basic-tools-dropdown-element no-padding">
+                        </div>
+                    </li>
+                </div>
                 <!-- Login de l'utilisateur -->
                 <div class="right">
                     <li role="presentation" style="position: inherit" class="basic-tools-dropdown">
@@ -58,7 +74,7 @@
                         </a>
                         <div app-print app-lang="ctrl.lang" app-map="ctrl.map" app-action="ctrl.currentAction"
                              id="basic-tools-dropdown-print-content"
-                             class="dropdown-menu basic-tools-dropdown-element basic-tools-dropdown-print-content">		
+                             class="dropdown-menu basic-tools-dropdown-element basic-tools-dropdown-print-content">
                         </div>
                     </li>
                 </div>
@@ -66,13 +82,13 @@
                 <div class="right">
                     <li role="presentation" style="position: inherit" class="basic-tools-dropdown">
                         <a class="basic-tools-element pointer"
-                           id="basic-tools-dropdown-insert-btn" 
+                           id="basic-tools-dropdown-insert-btn"
                            title="Insertion"
                            onclick="oVmap.getToolsManager().getBasicTools().toggleTool(this)">
                             <span class="icon-add-feature" aria-hidden="true"></span>
                         </a>
                         <div app-insert app-lang="ctrl.lang" app-map="ctrl.map" app-action="ctrl.currentAction"
-                             id="basic-tools-dropdown-insert-content" 
+                             id="basic-tools-dropdown-insert-content"
                              class="dropdown-menu basic-tools-dropdown-element basic-tools-dropdown-select-content">
                         </div>
                     </li>
@@ -96,4 +112,4 @@
             </ul>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/module_vmap/module/template/tools/comparemapmanager.html b/src/module_vmap/module/template/tools/comparemapmanager.html
new file mode 100644
index 0000000000000000000000000000000000000000..5400040928382b75fee2971115575455e96f07c6
--- /dev/null
+++ b/src/module_vmap/module/template/tools/comparemapmanager.html
@@ -0,0 +1,23 @@
+<!--Mode compare-->
+<div class="row margin-sides-0 no-padding">
+    <div class="margin-sides-20">
+        <div>
+            <div class="checkbox checkbox-info checkbox-inline checkbox_margin">
+                <input id="useCompareModeCheckbox"
+                        type="checkbox"
+                        style="cursor:pointer;"
+                        title=">Activer / Désactiver le mode comparaison"
+                        ng-model="ctrl.useCompareMode">
+                <label for="useCompareModeCheckbox"
+                       style="cursor:pointer"
+                       title="Activer / Désactiver le mode comparaison">
+                    Activer / Désactiver le mode comparaison
+                </label>
+            </div>
+        </div>
+    </div>
+    <div ng-show="ctrl.useCompareMode" class="col-md-12"><hr></div>
+    <div ng-show="ctrl.useCompareMode" class="col-md-12 no-padding">
+        <app-maplistlitle app-lang="ctrl.lang" app-maplistlitle-map="ctrl.map" data-compare="true"></app-maplistlitle>
+    </div>
+</div>
diff --git a/src/module_vmap/module/template/tools/insert.html b/src/module_vmap/module/template/tools/insert.html
index 8011c69fe13be35cb5aa0684448a4108da9abb2b..b18ed5994bdc1bfbf72020ce20aae6262f22d3be 100644
--- a/src/module_vmap/module/template/tools/insert.html
+++ b/src/module_vmap/module/template/tools/insert.html
@@ -242,32 +242,69 @@
                 <h4 class="modal-title" data-translate="TITLE_SNAPPING_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h4>
             </div>
             <div class="modal-body modal-body-big-with-footer-3 font-12">
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <select class="form-control"
-                            ng-model="ctrl.tmpSnapOptions.mode">
-                        <option value="segment_edge_node" data-translate="FORM_SNAPPING_METHOD_SEN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
-                        <option value="edge_node" data-translate="FORM_SNAPPING_METHOD_EN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
-                        <option value="node" data-translate="FORM_SNAPPING_METHOD_N_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
-                    </select>
-                </div>
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.tolerance">
-                </div>
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.limit">
+                <div class="row">
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <select class="form-control"
+                                ng-model="ctrl.tmpSnapOptions.mode">
+                            <option value="segment_edge_node" data-translate="FORM_SNAPPING_METHOD_SEN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
+                            <option value="edge_node" data-translate="FORM_SNAPPING_METHOD_EN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
+                            <option value="node" data-translate="FORM_SNAPPING_METHOD_N_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
+                        </select>
+                    </div>
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.tolerance">
+                    </div>
                 </div>
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_VISIBILITY_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <div class="radio radio-inline">
-                        <input type="radio" name="vmap_insert_snap_visible" id="vmap_insert_snap_visible_1" ng-model="ctrl.tmpSnapOptions.visible" ng-value="true">
-                        <label for="vmap_insert_snap_visible_1">Oui</label>
+                <div class="row">
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.limit">
                     </div>
-                    <div class="radio radio-inline">
-                        <input type="radio" name="vmap_insert_snap_visible" id="vmap_insert_snap_visible_2" ng-model="ctrl.tmpSnapOptions.visible" ng-value="false">
-                        <label for="vmap_insert_snap_visible_2">Non</label>
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_VISIBILITY_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <div class="radio radio-inline">
+                            <input type="radio" name="vmap_insert_snap_visible" id="vmap_insert_snap_visible_1" ng-model="ctrl.tmpSnapOptions.visible" ng-value="true">
+                            <label for="vmap_insert_snap_visible_1">Oui</label>
+                        </div>
+                        <div class="radio radio-inline">
+                            <input type="radio" name="vmap_insert_snap_visible" id="vmap_insert_snap_visible_2" ng-model="ctrl.tmpSnapOptions.visible" ng-value="false">
+                            <label for="vmap_insert_snap_visible_2">Non</label>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="col-sm-6" ng-show="aAvoidSuperpositionsBOs.length > 0">
+                        <div class="row">
+                            <div class="col-sm-12 text-right">
+                                <h5 data-translate="FORM_SNAPPING_AVOID_SUPERPOSITIONS_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                            </div>
+                        </div>
+                        <div class="row"
+                                ng-repeat="bo in aAvoidSuperpositionsBOs">
+                            <div class="col-sm-5 text-right">
+                                <label>{{bo.bo_title}}</label>
+                            </div>
+                            <div class="col-sm-7 text-right">
+                                <div class="radio radio-inline">
+                                    <input type="radio"
+                                            name="vmap_insert_snap_avoid_superpositions_{{$index}}"
+                                            id="vmap_insert_snap_avoid_superpositions_1_{{$index}}"
+                                            ng-model="ctrl.tmpSnapOptions.avoidSuperpositions[bo.bo_id]"
+                                            ng-value="true">
+                                    <label for="vmap_insert_snap_avoid_superpositions_1_{{$index}}">Oui</label>
+                                </div>
+                                <div class="radio radio-inline">
+                                    <input  type="radio"
+                                            name="vmap_insert_snap_avoid_superpositions_{{$index}}"
+                                            id="vmap_insert_snap_avoid_superpositions_2_{{$index}}"
+                                            ng-model="ctrl.tmpSnapOptions.avoidSuperpositions[bo.bo_id]"
+                                            ng-value="false">
+                                    <label for="vmap_insert_snap_avoid_superpositions_2_{{$index}}">Non</label>
+                                </div>
+                            </div>
+                        </div>
                     </div>
                 </div>
             </div>
diff --git a/src/module_vmap/module/template/tools/print.html b/src/module_vmap/module/template/tools/print.html
index 0a1fd62b4dcf92147ce7b543f37d661637c5f70c..330a8b9c2733511e33358d8d02c6e41a6463122a 100644
--- a/src/module_vmap/module/template/tools/print.html
+++ b/src/module_vmap/module/template/tools/print.html
@@ -53,10 +53,18 @@
         </select>
 
         <button type="button"
+                title="Modification de la zone d'impression sur la carte"
                 class="btn btn-info btn-sm"
                 style="margin-top: 10px"
-                ng-class="{'active': ctrl.currentAction === 'print-modifyPrintZone'}"
+                ng-class="{'active': managePrintZoneInProgress}"
                 ng-click="ctrl.managePrintZone()"><span class="glyphicon glyphicon-move"></span></button>
+       <button type="button"
+               title="Modification de la zone d'impression sur la carte de comparaison"
+               ng-show="$root.compare_enabled"
+               class="btn btn-info btn-sm"
+               style="margin-top: 10px"
+               ng-class="{'active': manageComparePrintZoneInProgress}"
+               ng-click="ctrl.manageComparePrintZone()"><span class="glyphicon glyphicon-move"></span></button>
 
         <button type="submit"
                 class="btn btn-info btn-sm"
diff --git a/src/module_vmap/module/template/tools/select.html b/src/module_vmap/module/template/tools/select.html
index 420c5b37e81360aa9fd3fcd128e1d46bb3f5e001..24ae5ca8505ff719e24f57588e36d5e262265c44 100644
--- a/src/module_vmap/module/template/tools/select.html
+++ b/src/module_vmap/module/template/tools/select.html
@@ -290,32 +290,69 @@
                 <h4 class="modal-title" data-translate="TITLE_SNAPPING_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h4>
             </div>
             <div class="modal-body modal-body-big-with-footer-3 font-12">
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <select class="form-control"
-                            ng-model="ctrl.tmpSnapOptions.mode">
-                        <option value="segment_edge_node" data-translate="FORM_SNAPPING_METHOD_SEN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
-                        <option value="edge_node" data-translate="FORM_SNAPPING_METHOD_EN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
-                        <option value="node" data-translate="FORM_SNAPPING_METHOD_N_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
-                    </select>
-                </div>
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.tolerance">
-                </div>
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.limit">
+                <div class="row">
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_TYPE_ACC_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <select class="form-control"
+                                ng-model="ctrl.tmpSnapOptions.mode">
+                            <option value="segment_edge_node" data-translate="FORM_SNAPPING_METHOD_SEN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
+                            <option value="edge_node" data-translate="FORM_SNAPPING_METHOD_EN_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
+                            <option value="node" data-translate="FORM_SNAPPING_METHOD_N_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></option>
+                        </select>
+                    </div>
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_TOLERANCE_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.tolerance">
+                    </div>
                 </div>
-                <div class="col-sm-6">
-                    <h5 data-translate="FORM_SNAPPING_DEFAUT_VISIBILITY_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
-                    <div class="radio radio-inline">
-                        <input type="radio" name="vmap_select_snap_visible" id="vmap_select_snap_visible_1" ng-model="ctrl.tmpSnapOptions.visible" ng-value="true">
-                        <label for="vmap_select_snap_visible_1">Oui</label>
+                <div class="row">
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_LIMIT_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <input type="number" class="form-control" ng-model="ctrl.tmpSnapOptions.limit">
                     </div>
-                    <div class="radio radio-inline">
-                        <input type="radio" name="vmap_select_snap_visible" id="vmap_select_snap_visible_2" ng-model="ctrl.tmpSnapOptions.visible" ng-value="false">
-                        <label for="vmap_select_snap_visible_2">Non</label>
+                    <div class="col-sm-6">
+                        <h5 data-translate="FORM_SNAPPING_VISIBILITY_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                        <div class="radio radio-inline">
+                            <input type="radio" name="vmap_select_snap_visible" id="vmap_select_snap_visible_1" ng-model="ctrl.tmpSnapOptions.visible" ng-value="true">
+                            <label for="vmap_select_snap_visible_1">Oui</label>
+                        </div>
+                        <div class="radio radio-inline">
+                            <input type="radio" name="vmap_select_snap_visible" id="vmap_select_snap_visible_2" ng-model="ctrl.tmpSnapOptions.visible" ng-value="false">
+                            <label for="vmap_select_snap_visible_2">Non</label>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="col-sm-6" ng-show="aAvoidSuperpositionsBOs.length > 0">
+                        <div class="row">
+                            <div class="col-sm-12 text-right">
+                                <h5 data-translate="FORM_SNAPPING_AVOID_SUPERPOSITIONS_CONFIGURATION_CONFIGURATION_VMAP_CONFIG"></h5>
+                            </div>
+                        </div>
+                        <div class="row"
+                                ng-repeat="bo in aAvoidSuperpositionsBOs">
+                            <div class="col-sm-5 text-right">
+                                <label>{{bo.bo_title}}</label>
+                            </div>
+                            <div class="col-sm-7 text-right">
+                                <div class="radio radio-inline">
+                                    <input type="radio"
+                                            name="vmap_select_snap_avoid_superpositions_{{$index}}"
+                                            id="vmap_select_snap_avoid_superpositions_1_{{$index}}"
+                                            ng-model="ctrl.tmpSnapOptions.avoidSuperpositions[bo.bo_id]"
+                                            ng-value="true">
+                                    <label for="vmap_select_snap_avoid_superpositions_1_{{$index}}">Oui</label>
+                                </div>
+                                <div class="radio radio-inline">
+                                    <input  type="radio"
+                                            name="vmap_select_snap_avoid_superpositions_{{$index}}"
+                                            id="vmap_select_snap_avoid_superpositions_2_{{$index}}"
+                                            ng-model="ctrl.tmpSnapOptions.avoidSuperpositions[bo.bo_id]"
+                                            ng-value="false">
+                                    <label for="vmap_select_snap_avoid_superpositions_2_{{$index}}">Non</label>
+                                </div>
+                            </div>
+                        </div>
                     </div>
                 </div>
             </div>
diff --git a/src/module_vmap/module/template/tools/urlexporter.html b/src/module_vmap/module/template/tools/urlexporter.html
index 8219c05115135bb301def37dcd88452878d5a06b..c10845a6e2310f0b48ee40f6479e40e21372608f 100644
--- a/src/module_vmap/module/template/tools/urlexporter.html
+++ b/src/module_vmap/module/template/tools/urlexporter.html
@@ -1,11 +1,30 @@
 <!--UrlExporter-->
 <div class="row margin-sides-0 margin-10">
-    <div class="col-md-3" ng-show="ctrl.properties.allow_public_connection">
-        <input type="checkbox" ng-model="ctrl.usePublicToken" id="publicAccountCheckbox">
-        <label for="publicAccountCheckbox" class="control-label">Public</label>
-    </div>          
-    <div class="" ng-class="{'col-md-9' : ctrl.properties.allow_public_connection, 'col-md-12': !ctrl.properties.allow_public_connection}">
-        <label for="urlExporterField" class="control-label">URL</label>
-        <input type="text" class="form-control" ng-model="ctrl.urlToExport" id="urlExporterField">
+    <div class="col-md-12">
+        <div class="left">
+            <label for="urlExporterField" class="control-label">Lien vers la carte en cours</label>
+        </div>
+        <div class="right" ng-if="ctrl.properties.allow_public_connection">
+            <div class="checkbox checkbox-info checkbox-inline">
+                <input id="publicAccountCheckbox"
+                        type="checkbox"
+                        style="cursor:pointer;"
+                        title=">Activer / Désactiver le mode public"
+                        ng-model="ctrl.usePublicToken">
+                <label for="publicAccountCheckbox"
+                       style="cursor:pointer"
+                       title="Activer / Désactiver le mode public">
+                    Public
+                </label>
+            </div>
+        </div>
     </div>
-</div>
\ No newline at end of file
+    <div class="col-md-12">
+        <div class="input-group">
+            <input type="text" class="form-control" ng-model="ctrl.urlToExport" id="urlExporterField">
+            <span class="input-group-btn">
+                <button type="button" class="btn btn-default" ng-click="ctrl.copyUrl()"><span class="icon-copy"></span></button>
+            </span>
+        </div>
+    </div>
+</div>
diff --git a/src/module_vmap/module/template/vmap.html b/src/module_vmap/module/template/vmap.html
index 358cdd8b6ca49e2c506b886d9a79c2683830b5cb..0b1b12f973b55e61a0408e13faf08923522ef702 100755
--- a/src/module_vmap/module/template/vmap.html
+++ b/src/module_vmap/module/template/vmap.html
@@ -4,7 +4,7 @@
     <div ng-if="!$root.is_mobile" id="left-sidebar" ng-class="vmapCtrl.left_open ? 'open' : ''">
         <div id="maplistlitle-container" class="dropdown">
             <!--voir dans maplistlitle.js pour l'evenement de fermeture de la dropdown-->
-            <button id="maplistlitle-button" class="btn btn-success dropdown-toggle btn-map-manager" 
+            <button id="maplistlitle-button" class="btn btn-success dropdown-toggle btn-map-manager"
                     type="button"
                     onclick="$('#maplistlitle-container').toggleClass('open')">
                 <span class="icon-map left" style="font-size: 30px"></span>
@@ -13,19 +13,19 @@
                     <span class="caret"></span>
                 </span>
             </button>
-            
-            
+
+
             <div id="dropdownMenuMaps" class="dropdown-menu map-list-litle-panel">
 
                 <app-maplistlitle app-lang="ctrl.lang" app-maplistlitle-map="ctrl.map"></app-maplistlitle>
 
                 <div id="map-manager-button-container" style="text-align: center">
-                    <button id="map-manager-button" 
-                            type="button" 
+                    <button id="map-manager-button"
+                            type="button"
                             class="btn btn-success btn-sm btn-modal margin-10"
                             onclick="oVmap.simuleClick('btn-reload-myMap'); $('#mapModalManager').modal('show'); $('#dropdownMenuMaps').dropdown('toggle')">
                         GESTION DES CARTES
-                    </button> 
+                    </button>
                 </div>
             </div>
         </div>
@@ -33,7 +33,7 @@
         <div app-layertree app-map="vmapCtrl.map" app-proj="vmapCtrl.proj" app-lang="vmapCtrl.lang" id="app-layertree"></div>
         <div app-layersorder app-map="vmapCtrl.map" app-proj="vmapCtrl.proj" app-lang="vmapCtrl.lang" id="app-layersorder"></div>
         <div app-maplegend app-map="vmapCtrl.map" app-proj="vmapCtrl.proj" app-lang="vmapCtrl.lang" id="app-maplegend"></div>
-        <div id="LayersDiv"></div> 
+        <div id="LayersDiv"></div>
 
         <!-- Map Modal -->
         <div class="modal fade" id="mapModalManager" role="dialog">
@@ -48,12 +48,19 @@
     <div ng-if="!$root.is_mobile" id="opener-sidebar" ng-click="vmapCtrl.left_open = !vmapCtrl.left_open" onclick="oVmap.resizeLayerTools(false); oVmap.getToolsManager().getBasicTools().toggleOutTools();">
         <div class="layer-tools-btn shadow-hover icon-tree" ng-class="vmapCtrl.left_open ? 'open' : ''" data-original-title="Couches et cartes"></div>
     </div>
-    
+
     <!-- Carte -->
-    <div id="map-container" ng-class="ctrl.bottom_open ? 'open' : ''">
+    <div id="map-container"
+         ng-class="{'open' : ctrl.bottom_open,'half' : compare_enabled, 'right-module-bar-present' : bLoadVmapModule, 'left-map-manager-open' : vmapCtrl.left_open, 'right-module-manager-open' : vmapCtrl.right_open}">
         <app-map app-map="vmapCtrl.map" app-action="vmapCtrl.currentAction"></app-map>
     </div>
 
+    <!-- Carte Compare -->
+    <div  ng-show="compare_enabled" id="map-container-compare"
+          ng-class="{'open' : ctrl.bottom_open,'half' : compare_enabled, 'right-module-bar-present' : bLoadVmapModule, 'left-map-manager-open' : vmapCtrl.left_open, 'right-module-manager-open' : vmapCtrl.right_open}">
+        <app-map-compare app-map="vmapCtrl.mapCompare" app-action="vmapCtrl.currentAction" style="display:block; width:100%; height:100%;"></app-map-compare>
+    </div>
+
     <!-- Bandeau de selection -->
     <div id="opener-bottombar" class="list-group-item active">
         <div id="opener-bottombar-1" class="open-selection-info" ng-click="ctrl.bottom_open = !ctrl.bottom_open" onclick="oVmap.minResizeBottomBar()"></div>
@@ -63,7 +70,3 @@
         <div id="info-container" app-infocontainer app-infocontainer-lang="vmapCtrl.lang" app-infos="vmapCtrl.infos"></div>
     </div>
 </div>
-
-
-
-
diff --git a/src/module_vmap/web_service/ws/BusinessObjects.class.inc b/src/module_vmap/web_service/ws/BusinessObjects.class.inc
index 413f93e43ebbc728cbc4600f84d2cc8d85d05249..fa7ca58d1eaf4d159d82c3498a6c75caf20b1d79 100755
--- a/src/module_vmap/web_service/ws/BusinessObjects.class.inc
+++ b/src/module_vmap/web_service/ws/BusinessObjects.class.inc
@@ -697,10 +697,6 @@ class BusinessObjects extends Vmap {
             $sFileContents .= $aFileContents[$i] . ' ';
         }
 
-//        // Travail sur chacune des requêtes du fichier
-//        $aFileContents = explode(';', $sFileContents);
-//        $aFileContents = $this->cleanDataModelFileArray($aFileContents);
-
         return $sFileContents;
     }
 
@@ -1318,7 +1314,7 @@ class BusinessObjects extends Vmap {
                         fclose($pFile);
                     }
 
-                    if ($this->aValues["Js"] != "") {
+                    if (isset($this->aValues["Js"])) {
                         $pFileJS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.js', 'w+');
                         if (fwrite($pFileJS, $this->aValues["Js"]) == FALSE) {
                             writeToErrorLog('ERROR: ' . $sFormName . '.js save failed');
@@ -1326,7 +1322,7 @@ class BusinessObjects extends Vmap {
                         fclose($pFileJS);
                     }
 
-                    if ($this->aValues["Css"] != "") {
+                    if (isset($this->aValues["Css"])) {
                         $pFileCSS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.css', 'w+');
                         if (fwrite($pFileCSS, $this->aValues["Css"]) == FALSE) {
                             writeToErrorLog('ERROR: ' . $sFormName . '.css save failed');
@@ -1370,6 +1366,26 @@ class BusinessObjects extends Vmap {
                     @unlink($sDirPath . "/forms/default.json");
                     $aFields = explode("|", $this->aValues['field']);
                     $this->generateBusinessObjectForm($sBusinessObjectId, $sFormName, $aFields, $this->aValues['label']);
+                    break;
+                case "Published_Delete":
+
+                    if (file_exists($sDirPath . "/forms/published.json")) {
+                        @unlink($sDirPath . "/forms/published.json");
+                    }
+                    if (file_exists($sDirPath . "/forms/ressources/published.js")) {
+                        @unlink($sDirPath . "/forms/ressources/published.js");
+                    }
+                    if (file_exists($sDirPath . "/forms/ressources/published.css")) {
+                        @unlink($sDirPath . "/forms/ressources/published.css");
+                    }
+
+                    break;
+                case "Delete_JS":
+
+                    if (file_exists($sDirPath . "/forms/ressources/" . $sFormName . ".js")) {
+                        @unlink($sDirPath . "/forms/ressources/" . $sFormName . ".js");
+                    }
+
                     break;
             }
         }
diff --git a/src/module_vmap/web_service/ws/Querys.class.inc b/src/module_vmap/web_service/ws/Querys.class.inc
index a5e4b7deed246263e5d67a6856fb62af7d503fa9..3aed39da27e23ba5bbe1615d9fa027c6127d5f48 100644
--- a/src/module_vmap/web_service/ws/Querys.class.inc
+++ b/src/module_vmap/web_service/ws/Querys.class.inc
@@ -515,14 +515,54 @@ class Querys extends Vmap {
      *     )
      *  )
      */
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/diff_geometry",
+     *   tags={"Querys"},
+     *   summary="Get business object form querys",
+     *   description="Get the difference geom between intersect_geom and the BO using st_difference",
+     *   operationId="GET",
+     *   produces={"application/json", "application/x-vm-json"},
+     *  @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="path",
+     *     description="business object id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="intersect_geom",
+     *     in="query",
+     *     description="EWKT intersect geometry",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
 
     /**
      * get Querys
      * @return  Querys
      */
     function GET($bOnlyReturnStatus = FALSE) {
-        if (isset($this->aPath[3]) && ($this->aPath[3] == 'geometry')) {
-            return $this->getBoGeomsFromIntersect($this->aPath[2]);
+        if (($this->aPath[3] == 'geometry') || ($this->aPath[3] == 'diff_geometry')) {
+            if (($this->aPath[3] == 'geometry')) {
+                return $this->getBoGeomsFromIntersect($this->aPath[2]);
+            }
+            if (($this->aPath[3] == 'diff_geometry')) {
+                return $this->getBoDiffGeomFromIntersect($this->aPath[2]);
+            }
         } else if (isset($this->aPath[3])) {
             return $this->queryBusinessObject($this->aPath[3]);
         } else {
@@ -597,7 +637,6 @@ class Querys extends Vmap {
 
         // Valeurs par défaut
         $intersect_column = empty($intersect_column) ? $geom_column : $intersect_column;
-//        $intersect_buffer = empty($intersect_buffer) ? 0.01 : $intersect_buffer;
         $geom_field = empty($geom_field) ? $intersect_column : $geom_field;
         $get_geom = empty($geom_field) || empty($get_geom) ? false : $get_geom;
         $use_intersect = empty($intersect_geom) || empty($intersect_column) ? false : true;
@@ -1205,6 +1244,121 @@ class Querys extends Vmap {
         }
     }
 
+    /**
+     * Get the difference geometry with a business object intersecting intersect_geom
+     */
+    function getBoDiffGeomFromIntersect($sBusinessObjectId) {
+
+        if (!empty($this->oConnection->oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $this->oConnection->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+        if (empty($sBusinessObjectId) || empty($this->aValues['intersect_geom'])) {
+            $oError = new VitisError(0, 'Parameters business_object_id, intersect_geom required');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+
+        // Objet BusinessObject correspondant
+        $aPath = array('vmap', 'businessobjects', $sBusinessObjectId);
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => 'application/json',
+            'sEncoding' => 'UTF-8',
+            'sSourceEncoding' => 'UTF-8',
+            'my_vitis_id' => $sBusinessObjectId,
+            'module' => 'vmap',
+        );
+        $oBusinessObject = new BusinessObject($aPath, $aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        // Vérifie l'éxistance de l'objet métier
+        if (empty($oBusinessObject->aFields['business_object_id'])) {
+            $oError = new VitisError(0, 'Business object ' . $sBusinessObjectId . ' not founded');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+
+        // Paramètres retenus dans l'url
+        $sSchema = $oBusinessObject->aFields['schema'];
+        $sTable = $oBusinessObject->aFields['table'];
+        $sIntersectGeom = $this->aValues['intersect_geom'];
+        $sInputFilter = $this->aValues['filter'];
+
+        // Paramètres retenus dans le business object
+        $sGeomColumn = $oBusinessObject->aFields['geom_column'];
+        $sDatabase = $oBusinessObject->aFields['database'];
+
+        // Base de données
+        if (!empty($sDatabase) && $sDatabase != $this->oConnection->oBd->base) {
+            $this->oConnection->oBd = new Vm($this->oConnection->oBd->login, $this->oConnection->oBd->mdp, $sDatabase, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        // Projection de la colonne intersectée
+        $iColumnProj = $this->oConnection->oBd->getColumnSRID($sSchema, $sTable, $sGeomColumn);
+        if (empty($iColumnProj)) {
+            $iColumnProj = '2154';
+        }
+
+        // Paramètres de la requête
+        $aParams = array();
+        $aParams['sSchema'] = array('value' => $sSchema, 'type' => 'schema_name');
+        $aParams['sTable'] = array('value' => $sTable, 'type' => 'table_name');
+        $aParams['sGeomColumn'] = array('value' => $sGeomColumn, 'type' => 'column_name');
+        $aParams['sIntersectGeom'] = array('value' => $sIntersectGeom, 'type' => 'geometry');
+
+        // Filtre
+        $aFilter = array(
+            'column' => $sGeomColumn,
+            'compare_operator' => 'intersect',
+            'compare_operator_options' => array(
+                'source_proj' => $iColumnProj,
+            ),
+            'value' => $sIntersectGeom
+        );
+
+        if (!empty($sInputFilter)) {
+            $aFilter = $this->addFilterOperator($sInputFilter, $aFilter);
+        }
+
+        $aDecodedFilter = $this->decodeJSONFilter($aFilter, $sSchema, $sTable);
+
+        $sSecuredFilter = $aDecodedFilter['request'];
+        foreach ($aDecodedFilter['params'] as $key => $value) {
+            $aParams[$key] = $value;
+        }
+
+        $sSql = '
+            WITH geoms AS (
+                SELECT (ST_Dump(st_difference(
+            				ST_GeomFromEWKT([sIntersectGeom]),
+            				ST_Union([sGeomColumn])
+            			))).geom AS geom
+                FROM [sSchema].[sTable] WHERE ' . $sSecuredFilter . '
+            )
+            SELECT ST_AsEWKT(geom) as diff_geom
+            FROM geoms
+            ORDER BY ST_Area(geom) DESC
+            LIMIT 1
+        ';
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+        if ($this->oConnection->oBd->enErreur()) {
+            $aXmlRacineAttribute['status'] = 0;
+            writeToErrorLog($this->oConnection->oBd->getBDMessage());
+            return json_encode(array('errorMessage' => 'Error while calculating diff geom'));
+        } else {
+            $aResult = $this->oConnection->oBd->getResultTableAssoc($oResult);
+            return json_encode($aResult);
+        }
+    }
+
     /**
      * @SWG\Put(path="/querys/{business_object_id}",
      *   tags={"Querys"},
diff --git a/src/vitis/client/javascript/app/controllers/htmlFormCtrl.js b/src/vitis/client/javascript/app/controllers/htmlFormCtrl.js
old mode 100755
new mode 100644
diff --git a/src/vitis/client/javascript/app/controllers/initCtrl.js b/src/vitis/client/javascript/app/controllers/initCtrl.js
old mode 100755
new mode 100644
index 48855c56c2092018d46d95c1faa98e94bc383767..70431eefb04a8ac083d1575ba2a078ca0641527f
--- a/src/vitis/client/javascript/app/controllers/initCtrl.js
+++ b/src/vitis/client/javascript/app/controllers/initCtrl.js
@@ -20,6 +20,7 @@ goog.require("vitis.modules.main");
 vitisApp.initCtrl = function ($scope, $log, $q, envSrvc, sessionSrvc, propertiesSrvc, userSrvc, $translate) {
     // Informe l'application que le contrôleur a été chargée.
     vitisApp.broadcast('appInitCtrlLoaded');
+
     /**
      * getMainTemplateUrl function.
      * Change le template de l'élément principal de l'application.
@@ -98,6 +99,43 @@ vitisApp.initCtrl = function ($scope, $log, $q, envSrvc, sessionSrvc, properties
         });
     };
 
+
+    /**
+     * connectFromUrl function.
+     * Connexion à l'application avec les identifiants passés dans l'url.
+     * @param {string} oConnexionId Identifiants de connexion
+     **/
+    $scope.$root["connectWithTokenUrl"] = function () {
+        $log.info("connectFromUrl");
+        // Demande de token pour l'utilisateur.
+        ajaxRequest({
+            "method": "POST",
+            "url": oClientProperties["web_server_name"] + "/" + oClientProperties["services_alias"] + "/" + sessionSrvc["web_service"] + "/" + sessionSrvc["web_service_controller"],
+            "scope": $scope,
+            "success": function (response) {
+                if (response["data"]["status"] == 1) {
+                    // Cache le message d'erreur.
+                    //$scope["hideErrorAlert"]();
+                    // Sauve les données du token.
+                    //sessionSrvc["token"] = oUrlParams['token'];
+                    sessionSrvc["validity_date"] = response["data"]["validity_date"];
+                    sessionStorage["session_token"] = sessionSrvc["token"];
+                    // Sauve les données de l'utilisateur.
+                    userSrvc["login"] = response["data"]["user"];
+                    userSrvc["id"] = parseInt(response["data"]["user_id"]);
+                    userSrvc["privileges"] = response["data"]["privileges"];
+                    sessionStorage["user_login"] = response["data"]["user"];
+                    sessionStorage["user_id"] = userSrvc["id"];
+                    sessionStorage["privileges"] = userSrvc["privileges"];
+                    sessionSrvc["saveSessionToLocalStorage"]();
+                    //
+                    deferred.resolve();
+                } else
+                    sessionSrvc["disconnect"]();
+            }
+        });
+    };
+
     // Sauve le nom de l'application (pour les modes de l'utilisateur)
     //sessionStorage["application"] = document.location.pathname.split("/").pop();
 
@@ -114,6 +152,14 @@ vitisApp.initCtrl = function ($scope, $log, $q, envSrvc, sessionSrvc, properties
     var deferred = $q.defer();
     var promise = deferred.promise;
 
+    if (goog.isDefAndNotNull(oUrlParams['token'])){
+        sessionStorage['session_token'] = oUrlParams['token'];
+        sessionSrvc["token"] = oUrlParams['token'];
+        sessionSrvc["saveSessionToLocalStorage"]();
+        $scope.$root["connectWithTokenUrl"]();
+    } else
+        deferred.resolve();
+
     // Connexion avec les identifiants passés dans l'url (si le cookie avec le token n'existe pas).
     var aUrlParamsKeys = Object.keys(oUrlParams);
     if (sessionSrvc["getAppLocalStorageItem"]("session_token") === null && aUrlParamsKeys.indexOf("login") !== -1 && aUrlParamsKeys.indexOf("password") !== -1)
diff --git a/src/vitis/client/javascript/app/controllers/loginCtrl.js b/src/vitis/client/javascript/app/controllers/loginCtrl.js
index 4e6e14618cdf92462865f9f573dbee866c13f221..a5456b97fd5b71d25c13cb4c0405b816fa331263 100644
--- a/src/vitis/client/javascript/app/controllers/loginCtrl.js
+++ b/src/vitis/client/javascript/app/controllers/loginCtrl.js
@@ -432,6 +432,7 @@ vitisApp.loginCtrl = function ($scope, $translate, $rootScope, $q, sessionSrvc,
                                 $translate([sConnectionErrorMessage]).then(function (translations) {
                                     sConnectionErrorMessage = translations[sConnectionErrorMessage];
                                     $scope["showErrorAlert"](sConnectionErrorMessage.replace('[IPAddress]', ipAddress));
+                        deferred.reject();
                                     sConnectionErrorMessage = undefined;
                                     deferred.reject();
                                 });
@@ -440,6 +441,12 @@ vitisApp.loginCtrl = function ($scope, $translate, $rootScope, $q, sessionSrvc,
                             case 18:
                                 sConnectionErrorMessage = "FORM_LOGIN_CONNECTION_ERROR_MISSING_PRIVILEGES";
                                 break;
+                            // Base de données injoignable.
+                            case 19:
+                                sConnectionErrorMessage = "FORM_LOGIN_CONNECTION_ERROR_UNREACHABLE_DATABASE";
+                                $scope["showErrorAlert"](sConnectionErrorMessage);
+                                deferred.reject();
+                                break;
                             default:
                                 sConnectionErrorMessage = "FORM_LOGIN_CONNECTION_ERROR";
                         }
diff --git a/src/vitis/client/javascript/app/script_client.js b/src/vitis/client/javascript/app/script_client.js
index 1f56beac66fa8b60adbae277624b4c216d4d7af5..02bda1b163d823f778c284e186dd91a290c803f2 100644
--- a/src/vitis/client/javascript/app/script_client.js
+++ b/src/vitis/client/javascript/app/script_client.js
@@ -1725,4 +1725,34 @@ vitisApp.on('appInitCtrlLoaded', function () {
         }
     });
     vitisApp.module.directive("appHideColumn", vitisApp.appHideColumn);
+    
+    /**
+     * addAjaxLoaderToElement function.
+     * Ajoute un loader Ajax à côté d'un élément HTML.
+     * @param {string} sElementId Id de l'élément html.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["addAjaxLoaderToElement"] = function (sElementId) {
+        $log.info("addAjaxLoaderToElement");
+        var oElem = document.getElementById(sElementId);
+        if (oElem !== null) {
+            var oAjaxLoaderElem = document.createElement('span');
+            oAjaxLoaderElem.className = "icon-refresh form-glyphicon-refresh-animate";
+            oElem.parentNode.appendChild(oAjaxLoaderElem);
+        }
+    };
+    
+    /**
+     * removeAjaxLoaderFromElement function.
+     * Supprime un loader Ajax placé à côté d'un élément HTML.
+     * @param {string} sElementId Id de l'élément html.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["removeAjaxLoaderFromElement"] = function (sElementId) {
+        $log.info("removeAjaxLoaderFromElement");
+        var oElem = document.getElementById(sElementId);
+        if (oElem !== null) {
+            var oAjaxLoaderElem = oElem.parentNode.querySelector(".form-glyphicon-refresh-animate");
+            if (oAjaxLoaderElem !== null)
+                oElem.parentNode.removeChild(oAjaxLoaderElem);
+        }
+    };
 });
diff --git a/src/vitis/client/javascript/externs/formReader/formReaderCtrl.js b/src/vitis/client/javascript/externs/formReader/formReaderCtrl.js
old mode 100755
new mode 100644
diff --git a/src/vitis/client/javascript/externs/formReader/formReaderDrtv.js b/src/vitis/client/javascript/externs/formReader/formReaderDrtv.js
index 48e7a37a22b78e1f1154bcaec9471d51e4a1c3a5..6634f5d412bfaf450ee68f68effbc48cfdb46c43 100644
--- a/src/vitis/client/javascript/externs/formReader/formReaderDrtv.js
+++ b/src/vitis/client/javascript/externs/formReader/formReaderDrtv.js
@@ -2156,8 +2156,8 @@ formReader.appSubformGridDrtv = function ($timeout, $translate, propertiesSrvc,
 
                                     // Récupère lélément en sélectionné
                                     formReaderService['getWebServiceData'](oFormWebService).then(function (aResult) {
+
                                         var oSubformDefinition = aResult[0]['bo_json_form'];
-                                        var sSubformJSDefinition = aResult[0]['bo_json_form_js'];
                                         var oSubformValues = {};
                                         var sModalId = 'formreader_' + scope['sFormUniqueName'] + '_grid_subform_modal';
 
@@ -2224,7 +2224,7 @@ formReader.appSubformGridDrtv = function ($timeout, $translate, propertiesSrvc,
                                             }
                                         });
 
-                                        formReaderService['showModalSubform'](sModalId, oSubformScope, oSubformDefinition, sSubformDefinitionName, oSubformValues, sSubformJSDefinition);
+                                        formReaderService['showModalSubform'](sModalId, oSubformScope, oSubformDefinition, sSubformDefinitionName, oSubformValues);
                                     });
                                 };
 
@@ -2252,7 +2252,6 @@ formReader.appSubformGridDrtv = function ($timeout, $translate, propertiesSrvc,
                         };
                         var sModalId = 'formreader_' + scope['sFormUniqueName'] + '_grid_subform_modal';
                         var oSubformDefinition = oBusinessObject['json_form'][0];
-                        var sSubformJSDefinition = oBusinessObject['json_form_js'];
                         var sSubformDefinitionName = 'insert';
 
                         // Grise le champ contenant la valeur du parent
@@ -2294,7 +2293,7 @@ formReader.appSubformGridDrtv = function ($timeout, $translate, propertiesSrvc,
                                 });
                             });
                         };
-                        formReaderService['showModalSubform'](sModalId, oSubformScope, oSubformDefinition, sSubformDefinitionName, oSubformValues, sSubformJSDefinition);
+                        formReaderService['showModalSubform'](sModalId, oSubformScope, oSubformDefinition, sSubformDefinitionName, oSubformValues);
                     };
 
                     /**
diff --git a/src/vitis/client/javascript/externs/formReader/formReaderSrvc.js b/src/vitis/client/javascript/externs/formReader/formReaderSrvc.js
index 613652f9c35ccf385e3b72c1c26432d8e0e8a09f..6ca6ef291e6a45bdf3b6298b998729bd7abddef5 100644
--- a/src/vitis/client/javascript/externs/formReader/formReaderSrvc.js
+++ b/src/vitis/client/javascript/externs/formReader/formReaderSrvc.js
@@ -1230,15 +1230,15 @@ formReader.formReaderService = function ($translate, $rootScope, $q, $log, $time
          * @param {object} oSubformDefinition
          * @param {object} oSubformDefinitionName
          * @param {object} oSubformValues
-         * @param {string|null} sSubformJSDefinition
          */
-        "showModalSubform": function (sModalId, oSubformScope, oSubformDefinition, oSubformDefinitionName, oSubformValues, sSubformJSDefinition) {
+        "showModalSubform": function (sModalId, oSubformScope, oSubformDefinition, oSubformDefinitionName, oSubformValues) {
             $log.log("showModalSubform");
 
             var sToken = this['sToken'];
             var oProperties = this['oProperties'];
 
-            var loadForm = function(){
+            if (goog.isDefAndNotNull(oSubformScope['loadSubForm'])) {
+
                 oSubformScope['loadSubForm']({
                     'sFormDefinitionName': oSubformDefinitionName,
                     'oFormDefinition': oSubformDefinition,
@@ -1246,30 +1246,6 @@ formReader.formReaderService = function ($translate, $rootScope, $q, $log, $time
                     'oProperties': oProperties,
                     'sToken': sToken
                 });
-            }
-
-            if (goog.isDefAndNotNull(oSubformScope['loadSubForm'])) {
-
-                if (goog.isDefAndNotNull(sSubformJSDefinition)) {
-                    var sUrl = sSubformJSDefinition;
-                    oVmap.log("initHtmlForm : javascript assoc. to : " + sUrl);
-                    loadExternalJs([sUrl], {
-                        "callback": function () {
-                            loadForm();
-                            try {
-                                if (goog.isDef(constructor_form)) {
-                                    constructor_form(oSubformScope, sUrl);
-                                }
-                            } catch (e) {
-                                oVmap.log("constructor_form does not exist");
-                            }
-                        },
-                        "async": true,
-                        "scriptInBody": true
-                    });
-                } else {
-                    loadForm();
-                }
 
                 $('#' + sModalId).modal('show');
             }
diff --git a/src/vitis/client/javascript/externs/studio/javascript/app/JsonLoader.js b/src/vitis/client/javascript/externs/studio/javascript/app/JsonLoader.js
index 8dd8de6819f10497d896707cbf05e14121fe00c2..ff0407e2f3e53237b80d512f0db73df6ba0b45f2 100755
--- a/src/vitis/client/javascript/externs/studio/javascript/app/JsonLoader.js
+++ b/src/vitis/client/javascript/externs/studio/javascript/app/JsonLoader.js
@@ -248,7 +248,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.requestToJson = functi
                             cmd = "Perso_Reset";
                             break;
                     }
-                    this_.putRequest(cmd, undefined, function (data) {
+                    this_.putRequest(cmd, this_.$scope_["FormSelected"], undefined, function (data) {
 
                         // Cas d'erreur du put
                         if (goog.isDefAndNotNull(data['errorMessage'])) {
@@ -584,18 +584,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.save = function (succe
     oVFB.unselectAll();
     tmp = oVFB.cleanFormToSave(tmp);
 
-    /*if ($("#boolean-JS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = false;
-     }
-
-     if ($("#boolean-CSS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = false;
-     }*/
-
     if (this['applicationName'] === 'gtf') {
         tmp[this_.$rootScope_["selected_form_type"]]["name"] = "WSubform";
         tmp["display"] = tmp[this_.$rootScope_["selected_form_type"]];
@@ -623,7 +611,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.save = function (succe
     oVFB.valid = this.isValid(tmp);
 
     if (oVFB.valid && tmp !== null) {
-        this_.putRequest("Perso_Save", data, success, error);
+        this_.putRequest("Perso_Save", this_.$scope_["FormSelected"], data, success, error);
     } else {
         $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Validation_Error"] + ': ' + oVFB.aNotValid, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
     }
@@ -646,18 +634,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.publish = function ()
     // Supprime les elements selectionnés
     oVFB.unselectAll();
 
-    /*if ($("#boolean-JS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = false;
-     }
-
-     if ($("#boolean-CSS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = false;
-     }*/
-
     if (this['applicationName'] === 'gtf') {
         tmp[this_.$rootScope_["selected_form_type"]]["name"] = "WSubform";
         tmp["display"] = tmp[this_.$rootScope_["selected_form_type"]];
@@ -669,7 +645,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.publish = function ()
     data.append("Css", oVFB.getCss());
 
     var success = function () {
-//        $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["SaveData"], {"className": "success", "autoHideDelay": oVFB.TimeNotify_});
         var data = "";
         var success = function () {
             this_.requestToJson();
@@ -679,17 +654,16 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.publish = function ()
             $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Publish_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
         };
 
-        this_.putRequest(this_.$scope_["FormSelected"] + "_Published", data, success, error);
+        this_.putRequest(this_.$scope_["FormSelected"] + "_Published", this_.$scope_["FormSelected"], data, success, error);
     };
     var error = function (data, status) {
         $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["SaveData_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
     };
     if (oVFB.valid) {
         if (this_.$scope_["FormSelected"] != "Default") {
-            this_.putRequest("Perso_Save", data, success, error);
+            this_.putRequest("Perso_Save", this_.$scope_["FormSelected"], data, success, error);
         } else {
-            this_.putRequest("Default_Published", data, success, error);
-
+            this_.putRequest("Default_Published", this_.$scope_["FormSelected"], data, success, error);
         }
     } else {
         $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Validation_Error"], {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
@@ -763,7 +737,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.reset = function () {
                 var error = function (data, status) {
                     $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Reset_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
                 };
-                this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", data, success, error);
+                this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", this_.$scope_["FormSelected"], data, success, error);
             }
         }
     });
@@ -771,14 +745,63 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.reset = function () {
     oVFB.studioMainController.prototype.moveBootboxModalToStudioContainer(oModal);
 };
 
+/**
+ * Remove the published form on the server
+ *
+ * @export
+ */
+nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.deletePublishedForm = function () {
+    oVFB.log('nsVFB.JsonLoader.jsonLoaderController.deletePublishedForm');
+
+    var this_ = this;
+    var oModal = bootbox.confirm('<h4>' + this["text"]["InfoBulle"]["Published"]["DeletePublishedForm"] + ' ?</h4>', function (result) {
+        if (result === true) {
+            var data = "";
+            var success = function () {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete"], {"className": "success", "autoHideDelay": oVFB.TimeNotify_});
+                this_.requestToJson();
+            };
+            var error = function (data, status) {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
+            };
+            this_.putRequest('Published_Delete', 'Published', data, success, error);
+        }
+    });
+}
+
+/**
+ * Remove the form JS on the server
+ *
+ * @export
+ */
+nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.deleteJS = function () {
+    oVFB.log('nsVFB.JsonLoader.jsonLoaderController.deleteJS');
+
+    var this_ = this;
+    var oModal = bootbox.confirm('<h4>' + this["text"]["InfoBulle"]["Perso"]["Delete_JS"] + ' ?</h4>', function (result) {
+        if (result === true) {
+            var data = "";
+            var success = function () {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete_JS"], {"className": "success", "autoHideDelay": oVFB.TimeNotify_});
+                this_.requestToJson();
+            };
+            var error = function (data, status) {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete_JS_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
+            };
+            this_.putRequest('Delete_JS', this_.$scope_["FormSelected"], data, success, error);
+        }
+    });
+}
+
 /**
  * Make a put request on the server
  * @param {string} cmd command to load (Perso_Save, Perso_Published, Default_Published, Perso_Reset etc...)
+ * @param {string} sForm form to update
  * @param {object} data FormData to send
  * @param {function} functSuccess function to load in case of success
  * @param {function} functError function to load in case of error
  */
-nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest = function (cmd, data, functSuccess, functError) {
+nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest = function (cmd, sForm, data, functSuccess, functError) {
     oVFB.log('nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest');
 
     var url = '';
@@ -810,15 +833,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest = function
         'success': functSuccess,
         'error': functError
     });
-
-//    this.$http_({
-//        url: url,
-//        method: 'PUT',
-//        data: data,
-//        headers: {
-//            "Content-Type": "undefined"
-//        }
-//    }).success(functSuccess).error(functError);
 };
 
 /**
@@ -829,14 +843,34 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.suggestGenerateForm =
     oVFB.log('nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.suggestGenerateForm');
 
     var this_ = this;
-    var oModal = bootbox.confirm('<h4>' + this.$scope_['text']['Loader']['Notify']['generate_form'] + '</h4>', function (result) {
-        if (result === true) {
-            this_.suggestColumnsToGenerateForm();
-        } else {
-            this_['aSuggestedTableFields'] = [];
-            this_.generateFormByBusinessObject();
+    var oModal = bootbox['dialog']({
+        'message': '<h4>' + this.$scope_['text']['Loader']['Notify']['generate_form'] + '</h4>',
+        'buttons': {
+            'cancel': {
+                'label': this.$scope_['text']['Loader']['Cancel'],
+                'className': 'btn-default',
+                'callback': function(){
+                    this_.useEmptyForm();
+                }
+            },
+            'create_empty': {
+                'label': this.$scope_['text']['Loader']['CreateEmptyForm'],
+                'className': 'btn-primary',
+                'callback': function(){
+                    this_['aSuggestedTableFields'] = [];
+                    this_.generateFormByBusinessObject();
+                }
+            },
+            'generate_from_columns': {
+                'label': this.$scope_['text']['Loader']['GenerateForm'],
+                'className': 'btn-primary',
+                'callback': function(){
+                    this_.suggestColumnsToGenerateForm();
+                }
+            }
         }
     });
+
     // Déplace la popup dans l'élément principal du studio (sinon elle est masquée en mode plein écran).
     oVFB.studioMainController.prototype.moveBootboxModalToStudioContainer(oModal);
 };
@@ -860,10 +894,16 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.useEmptyForm = functio
         'javascript': false,
         'name': 'custom-form',
         'nb_cols': 12,
-        'rows': [],
+        'rows': [{
+            'fields': []
+        }],
         'title': ''
     };
 
+    if (!goog.isArray(data)) {
+        data = [];
+    }
+
     data[0] = {
         'datasources': {}
     };
@@ -1017,7 +1057,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.generateFormByBusiness
         var error = function (data, status) {
             $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Reset_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
         };
-        this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", {"field": sFieldsToUse, "label": afieldsLabel}, success, error);
+        this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", this_.$scope_["FormSelected"], {"field": sFieldsToUse, "label": afieldsLabel}, success, error);
     } else {
 
         ajaxRequest({
@@ -1035,19 +1075,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.generateFormByBusiness
                 $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["CreateJson_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
             }
         });
-
-//        this.$http_({
-//            url: url,
-//            method: 'POST',
-//            data: {
-//                'fields': sFieldsToUse,
-//                'label': afieldsLabel
-//            }
-//        }).success(function () {
-//            this_.requestToJson();
-//        }).error(function () {
-//            $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["CreateJson_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
-//        });
     }
 };
 
diff --git a/src/vitis/client/javascript/externs/studio/lang/lang-en.json b/src/vitis/client/javascript/externs/studio/lang/lang-en.json
index f33be9b38476461cc2228befc9bf4eb5f7f860cb..b6d34b3729e50d6508ea9665f3c1446ae7cec112 100755
--- a/src/vitis/client/javascript/externs/studio/lang/lang-en.json
+++ b/src/vitis/client/javascript/externs/studio/lang/lang-en.json
@@ -10,6 +10,8 @@
         "WabState": "State",
         "Validate": "Validate",
         "Cancel": "Cancel",
+        "GenerateForm": "Generate form",
+        "CreateEmptyForm": "Create empty form",
         "AddTab": "Add tab",
         "EditTab": "Edit",
         "RemoveTab": "Remove",
@@ -34,6 +36,7 @@
                 "Button_gtf": "FME generated form"
             },
             "Published": {
+                "DeletePublishedForm": "Delete published form",
                 "Button": "Used form",
                 "Button_gtf": "Used form"
             },
@@ -42,7 +45,8 @@
                 "Reload": "Reload files from server",
                 "Publish": "Publish the custom form",
                 "Reset": "Replace the custom form by the default form",
-                "Button": "Modification used form"
+                "Button": "Modification used form",
+                "Delete_JS": "Remove JavaScript"
             }
         },
         "Form": {
@@ -87,6 +91,10 @@
             "ProblemId": "ID problem, try again or contact an admin",
             "Reset": "Was reset",
             "Reset_Error": "Error while resetting : ",
+            "Delete": "Le formulaire a été supprimé",
+            "Delete_Error": "Erreur lors de la suppression du formulaire : ",
+            "Delete_JS": "JavaScript file deleted",
+            "Delete_JS_Error": "Erorr while deleting JavaScript file : ",
             "Publish": " Has been published",
             "PublishAndSave": " Has been published and saved",
             "Publish_Error": "Error while publishing : ",
diff --git a/src/vitis/client/javascript/externs/studio/lang/lang-fr.json b/src/vitis/client/javascript/externs/studio/lang/lang-fr.json
index 43a99c1e47c1a55b798c6eaa2b4daedeaccfd126..ddaad2891c0fd4177698f0341e3e075d915290b3 100755
--- a/src/vitis/client/javascript/externs/studio/lang/lang-fr.json
+++ b/src/vitis/client/javascript/externs/studio/lang/lang-fr.json
@@ -10,6 +10,8 @@
         "WabState": "État wab",
         "Validate": "Valider",
         "Cancel": "Annuler",
+        "GenerateForm": "Générer un formulaire",
+        "CreateEmptyForm": "Créer un formulaire vide",
         "AddTab": "Ajouter un onglet",
         "EditTab": "Éditer",
         "RemoveTab": "Supprimer",
@@ -34,6 +36,7 @@
                 "Button_gtf": "Afficher le formulaire par défaut"
             },
             "Published": {
+                "DeletePublishedForm": "Supprimer le formulaire publié",
                 "Button": "Afficher le formulaire par publié",
                 "Button_gtf": "Afficher le formulaire par publié"
             },
@@ -44,7 +47,8 @@
                 "Reset": "Remplacer le formulaire personnalisé par le formulaire par défaut",
                 "ResetWab": "Regénérer le formulaire depuis la base",
                 "Button": "Afficher le formulaire par personnalisé",
-                "Button_gtf": "Afficher le formulaire par personnalisé"
+                "Button_gtf": "Afficher le formulaire par personnalisé",
+                "Delete_JS": "Supprimer la partie JavaScript du formulaire"
             }
         },
         "Form": {
@@ -89,6 +93,10 @@
             "ProblemId": "Problème d'ID, réessayer ou contacter un administrateur",
             "Reset": " a été réinitialisé",
             "Reset_Error": "Erreur lors de la réinitialisation : ",
+            "Delete": "Le formulaire a été supprimé",
+            "Delete_Error": "Erreur lors de la suppression du formulaire : ",
+            "Delete_JS": "Le fichier JavaScript a été supprimé",
+            "Delete_JS_Error": "Erreur lors de la suppression du fichier JavaScript : ",
             "Publish": " a été publié",
             "PublishAndSave": " a été publié et sauvegardé",
             "Publish_Error": "Erreur lors de la publication : ",
diff --git a/src/vitis/client/javascript/externs/studio/less/studio.less b/src/vitis/client/javascript/externs/studio/less/studio.less
index 39431d7eef77567589e097ec3edf7dc1e449092f..25844881140da28f02b1d7303efee582025d3138 100755
--- a/src/vitis/client/javascript/externs/studio/less/studio.less
+++ b/src/vitis/client/javascript/externs/studio/less/studio.less
@@ -3,7 +3,7 @@ To change this license header, choose License Headers in Project Properties.
 To change this template file, choose Tools | Templates
 and open the template in the editor.
 */
-/* 
+/*
     Created on : 5 janv. 2016, 12:08:09
     Author     : a_borghi
 */
@@ -23,7 +23,7 @@ and open the template in the editor.
 //@import (less) '../css/lib/bootstrap/css/bootstrap.css';
 
 
-//définit la taille de la fenêtre 
+//définit la taille de la fenêtre
 .app_window{
     /*Skin scrollBar*/
     ::-webkit-scrollbar {
@@ -39,11 +39,11 @@ and open the template in the editor.
     ::-webkit-scrollbar-thumb {
         -webkit-border-radius: 10px;
         border-radius: 10px;
-        background: @studio-color-purple; 
-        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); 
+        background: @studio-color-purple;
+        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
     }
     ::-webkit-scrollbar-thumb:window-inactive {
-        background: @studio-color-purple; 
+        background: @studio-color-purple;
     }
 
     input[type=number]::-webkit-outer-spin-button,
@@ -61,7 +61,7 @@ and open the template in the editor.
 
 /*Laisse une marge sous un composant*/
 .element-margin {
-    margin-bottom: 10px; 
+    margin-bottom: 10px;
 }
 
 //align un div sur la droite avec une petite marge
@@ -199,19 +199,14 @@ and open the template in the editor.
 }
 
 // rend un élément non selectable
-.unselectable { 
-    -moz-user-select: none; 
-    -khtml-user-select: none; 
-    -webkit-user-select: none; 
-    -o-user-select: none; 
-}
-
-// décalage pour les checkbox et radio 
-.checkbox_margin {
-    margin-left: 30px;
+.unselectable {
+    -moz-user-select: none;
+    -khtml-user-select: none;
+    -webkit-user-select: none;
+    -o-user-select: none;
 }
 
-// Permet à code Mirror de prendre toute la place dans la div 
+// Permet à code Mirror de prendre toute la place dans la div
 .CodeMirror {
     border: 1px solid #eee;
     height: auto;
@@ -241,7 +236,7 @@ and open the template in the editor.
 }
 
 .invalid_input{
-    background-color: rgba(255,0,0,0.5); 
+    background-color: rgba(255,0,0,0.5);
 }
 
 /*th, td{
@@ -343,15 +338,6 @@ and open the template in the editor.
     font-size:11px
 }
 
-.checkbox label::before, .checkbox label::after{
-    width:13px;
-    height: 13px;
-}
-
-.checkbox {
-    padding-left: 12px;
-}
-
 .collapser-form-wab-modal{
     font-size: 40px;
     padding-top: 10px;
@@ -359,8 +345,8 @@ and open the template in the editor.
 }
 
 .transition-form-wab-collapser{
-    transition: width 0.5s; 
-    //transition: display 1s; 
+    transition: width 0.5s;
+    //transition: display 1s;
 }
 .form-tools-tree-container{
     overflow-y: auto;
@@ -381,4 +367,4 @@ and open the template in the editor.
     background-color: initial;
     top: initial;
     //border: initial;
-}
\ No newline at end of file
+}
diff --git a/src/vitis/client/javascript/externs/studio/templates/JsonLoader.html b/src/vitis/client/javascript/externs/studio/templates/JsonLoader.html
index f5b18f1bbcdc94c3affda84e3f319650ca32def9..6e320cdab08eda903260ccea6a2e5c0effbf9041 100755
--- a/src/vitis/client/javascript/externs/studio/templates/JsonLoader.html
+++ b/src/vitis/client/javascript/externs/studio/templates/JsonLoader.html
@@ -1,8 +1,4 @@
 <div class="panel panel-veremes" id="FilesURL">
-    <!--    <div class="panel-heading unselectable" ng-click="ctrl.resize()">{{::ctrl.text.Title}}
-            <span ng-if="collapsed" id="colapse_uploader_icon" class="fa fa-angle-right fa-lg" style="float:right"></span>
-            <span ng-if="!collapsed" id="colapse_uploader_icon" class="fa fa-angle-down fa-lg" style="float:right"></span>
-        </div>-->
     <div class="panel-heading unselectable">
         <!--Fichier-->
         <div class="btn-group dropdown margin-right-10">
@@ -50,6 +46,24 @@
                         {{::ctrl.text.InfoBulle.Perso.Publish}}
                     </a>
                 </li>
+                <li ng-hide="ctrl.buttonHide"
+                    ng-show="(FormSelected === 'Perso' || FormSelected === 'Published') && ctrl.applicationName === 'vmap'">
+                    <a title="{{::ctrl.text.InfoBulle.Published.Delete}}"
+                       href="javascript:void(0);"
+                       ng-click="ctrl.deletePublishedForm()">
+                        <span class="fa icon-trash" aria-hidden="true"></span>
+                        {{::ctrl.text.InfoBulle.Published.DeletePublishedForm}}
+                    </a>
+                </li>
+                <li ng-hide="ctrl.buttonHide"
+                    ng-show="(FormSelected === 'Perso' || FormSelected === 'Published') && ctrl.applicationName === 'vmap'">
+                    <a title="{{::ctrl.text.InfoBulle.Perso.Delete_JS}}"
+                       href="javascript:void(0);"
+                       ng-click="ctrl.deleteJS()">
+                        <span class="fa icon-trash" aria-hidden="true"></span>
+                        {{::ctrl.text.InfoBulle.Perso.Delete_JS}}
+                    </a>
+                </li>
                 <li ng-hide="ctrl.buttonHide" ng-show="FormSelected === 'Perso'">
                     <a title="{{::ctrl.text.InfoBulle.Perso.Reset}}"
                        href="javascript:void(0);"
diff --git a/src/vitis/client/lang/lang-en.json b/src/vitis/client/lang/lang-en.json
index 349fcf07df20a59f918709e36e4db469d4cfcffb..0038b8111b023f79ac39954b3ddc1e892fbeeb59 100644
--- a/src/vitis/client/lang/lang-en.json
+++ b/src/vitis/client/lang/lang-en.json
@@ -7,6 +7,7 @@
     "FORM_LOGIN_CONNECTION_ERROR": "Connection failed. Incorrect user / password / domain or database not available",
     "FORM_LOGIN_CONNECTION_ERROR_FORBIDDEN_IP": "Connection failed. IP [IPAddress] forbiden",
     "FORM_LOGIN_CONNECTION_ERROR_MISSING_PRIVILEGES": "Connection failed. The user does not have the required privileges. Please contact your administrator.",
+    "FORM_LOGIN_CONNECTION_ERROR_UNREACHABLE_DATABASE": "The application is currently unavailable (database unreachable).",
     "FORM_LOGIN_REMEMBER_ME": "Remember connection?",
     "FORM_APP_STATUS_ERROR": "Unstable application",
     "FORM_VAS_STATUS_ERROR": "Unstable VAS",
diff --git a/src/vitis/client/lang/lang-fr.json b/src/vitis/client/lang/lang-fr.json
index 5c5eb178de24b151ef22b6b2e7c0701363bc0297..7dfe445bb0d0440f1fc6b9a0b41d979c21b9a308 100644
--- a/src/vitis/client/lang/lang-fr.json
+++ b/src/vitis/client/lang/lang-fr.json
@@ -7,6 +7,7 @@
     "FORM_LOGIN_CONNECTION_ERROR": "Connexion refusée. Utilisateur / Mot de passe / domaine incorrect ou base de données non disponible.",
     "FORM_LOGIN_CONNECTION_ERROR_FORBIDDEN_IP": "Connexion refusée. Adresse IP [IPAddress] non autorisée",
     "FORM_LOGIN_CONNECTION_ERROR_MISSING_PRIVILEGES": "Connexion refusée. L'utilisateur ne dispose pas des privilèges requis. Merci de contacter votre administrateur.",
+    "FORM_LOGIN_CONNECTION_ERROR_UNREACHABLE_DATABASE": "L'application est actuellement indisponible (base de données injoignable).",
     "FORM_LOGIN_REMEMBER_ME": "Se souvenir de moi ?",
     "FORM_APP_STATUS_ERROR": "Application instable",
     "FORM_VAS_STATUS_ERROR": "VAS instable",
diff --git a/src/vitis/client/less/htmlForm.less b/src/vitis/client/less/htmlForm.less
index 10480f56b30c5eefffc323ea0264d948b3675294..99e18c281d2a56bae257aa96f5758214cc3b46c9 100755
--- a/src/vitis/client/less/htmlForm.less
+++ b/src/vitis/client/less/htmlForm.less
@@ -595,3 +595,16 @@ form .checkbox {
 .timepicker-picker > table, .bootstrap-datetimepicker-widget .picker-switch .table-condensed {
     margin: auto
 }
+
+// Loader ajax pour un element de formulaire.
+.form-glyphicon-refresh-animate {
+    display: inline-block;
+    top: 3px !important;
+    left: 3px;
+    font-size: large;
+    font-weight: 800;
+    color: black;
+    -webkit-animation:spin 1.5s linear infinite;
+    -moz-animation:spin 1.5s linear infinite;
+    animation:spin 1.5s linear infinite;
+}
diff --git a/src/vitis/client/less/main.less b/src/vitis/client/less/main.less
old mode 100755
new mode 100644
index d567b91f34adfab804aee576cdf68409e253dda4..56042ea63502decf8696aff10e5c6dc4cc2020da
--- a/src/vitis/client/less/main.less
+++ b/src/vitis/client/less/main.less
@@ -1046,3 +1046,24 @@ div[data-app-html-form]>div[app-form-reader]>.modal>.modal-dialog{
 /*@supports (-ms-accelerator:true) and (not (color:unset)) {
   .selector { property:value; }
 }*/
+
+.checkbox {
+    padding-left: 12px;
+}
+
+.checkbox_margin {
+    margin-left: 30px;
+}
+
+.checkbox-inline label::before{
+    top: 3px;
+    left: 1px
+}
+.checkbox-inline label::after{
+    top: 2px;
+}
+
+.checkbox label::before, .checkbox label::after{
+    width:13px;
+    height: 13px;
+}
diff --git a/src/vitis/client/modules/vitis/forms/configuration/configuration_vitis_configuration.json b/src/vitis/client/modules/vitis/forms/configuration/configuration_vitis_configuration.json
old mode 100755
new mode 100644
diff --git a/src/vitis/client/modules/vitis/forms/exploitation/exploitation_exploitation.json b/src/vitis/client/modules/vitis/forms/exploitation/exploitation_exploitation.json
new file mode 100755
index 0000000000000000000000000000000000000000..a7b4cde99ba8412476eb7ffe7a66a37f9c7c9bed
--- /dev/null
+++ b/src/vitis/client/modules/vitis/forms/exploitation/exploitation_exploitation.json
@@ -0,0 +1,160 @@
+{
+    "search":{
+            
+    },
+    "update":{
+        "name":"gtf_exploitation_shared_directory_update_form",
+        "title":"FORM_TITLE_EXPLOITATION_EXPLOITATION",
+        "initEvent":"initExploitationSharedDirectoryForm()",
+        "event":"",
+        "input_size":"xs",
+        "nb_cols":12,
+        "class":"project-directory-upload-form",
+        "rows":[
+            {
+                "class":"shared-directory-treeview",
+                "fields":[
+                    {
+                        "type":"treeview",
+                        "name":"shared_directory",
+                        "label":"",
+                        "required":false,
+                        "pattern":"",
+                        "nb_cols":12,
+                        "id":"shared_directory",
+                        "options":{
+                            "showBorder":false,
+                            "levels":0,
+                            "showCheckbox":true,
+                            "expandIcon":"glyphicon glyphicon-folder-close",
+                            "collapseIcon":"glyphicon glyphicon-folder-open",
+                            "highlightSelected":true,
+                            "multiSelect":false,
+                            "dataLoadingEvent": "sharedDirectoryTreeviewDataLoaded"
+                        }
+                    }
+                ]
+            },            
+            {
+                "fields":[
+                    {
+                        "type":"button",
+                        "class":"btn-ungroup btn-group-xs",
+                        "nb_cols":12,
+                        "buttons":[
+                            {
+                                "type":"button",
+                                "name":"btn_download_file",
+                                "glyphicon":"download",
+                                "class":"btn-primary btn-xs",
+                                "event":"downloadFile()",
+                                "tooltip": {
+                                        "title":"FORM_DOWNLOAD_FILE_EXPLOITATION_EXPLOITATION",
+                                        "placement": "bottom",
+                                        "trigger": "hover",
+                                        "container": "body"
+                                },
+                                "visible":false
+                            },
+                            {
+                                "type":"button",
+                                "name":"btn_refresh_treeview",
+                                "glyphicon":"refresh",
+                                "class":"btn-primary btn-xs",
+                                "event":"refreshExploitationSharedDirectoryTreeview()",
+                                "tooltip": {
+                                        "title":"FORM_RELOAD_DIRECTORY_EXPLOITATION_EXPLOITATION",
+                                        "placement": "bottom",
+                                        "trigger": "hover",
+                                        "container": "body"
+                                }
+                            },
+                            {
+                                "type":"button",
+                                "name":"btn_delete_file",
+                                "glyphicon":"trash",
+                                "class":"btn-primary btn-xs",
+                                "event":"deleteSharedDirectoryFiles()",
+                                "tooltip": {
+                                        "title":"FORM_DELETE_FILES_EXPLOITATION_EXPLOITATION",
+                                        "placement": "bottom",
+                                        "trigger": "hover"
+                                }
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                "class":"form-field-inline",
+                "fields":[
+                    {
+                        "type":"upload",
+                        "name":"file",
+                        "label":"FORM_FILE_EXPLOITATION_EXPLOITATION",
+                        "nb_cols":4
+                    },
+                    {
+                        "type":"text",
+                        "name":"directory_name",
+                        "label":"FORM_DIRECTORY_EXPLOITATION_EXPLOITATION",
+                        "nb_cols":4
+                    }
+                ]
+            },
+            {
+                "class":"form-field-inline",
+                "fields":[
+                    {
+                        "type":"button",
+                        "class":"btn-ungroup btn-group-sm",
+                        "nb_cols":4,
+                        "buttons":[
+                            {
+                                "type":"button",
+                                "name":"btn_upload_file",
+                                "label":"FORM_UPLOAD_FMW_FILE_EXPLOITATION_EXPLOITATION",
+                                "event":"uploadSharedDirectoryFile()",
+                                "class":"btn-primary"
+                            }
+                        ]
+                    },
+                    {
+                        "type":"button",
+                        "class":"btn-ungroup btn-group-sm",
+                        "nb_cols":4,
+                        "buttons":[
+                            {
+                                "type":"button",
+                                "name":"btn_create_directory",
+                                "label":"FORM_BTN_CREATE_DIRECTORY_EXPLOITATION_EXPLOITATION",
+                                "event":"createSharedDirectoryFolder()",
+                                "class":"btn-primary"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "insert":{
+            
+    },
+    "display":{
+        "name":"gtf_exploitation_shared_directory_display_form",
+        "title":"FORM_TITLE_EXPLOITATION_EXPLOITATION",
+        "input_size":"xs",
+        "nb_cols":8,
+        "rows":[
+            {
+                "fields":[
+                    {
+                        "type":"hidden",
+                        "name":"fmw_file",
+                        "nb_cols":12
+                    }
+                ]
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/src/vitis/client/modules/vitis/forms/user/user_vitis_user.json b/src/vitis/client/modules/vitis/forms/user/user_vitis_user.json
old mode 100755
new mode 100644
diff --git a/src/vitis/client/modules/vitis/forms/users/users_vitis_users.json b/src/vitis/client/modules/vitis/forms/users/users_vitis_users.json
old mode 100755
new mode 100644
diff --git a/src/vitis/client/modules/vitis/javascript/script_module.js b/src/vitis/client/modules/vitis/javascript/script_module.js
old mode 100755
new mode 100644
index 1f0e99b41d538a838143044510f0016012a6f4ce..716b8de908bc4dfb057afe25e838d92aa2463531
--- a/src/vitis/client/modules/vitis/javascript/script_module.js
+++ b/src/vitis/client/modules/vitis/javascript/script_module.js
@@ -1211,7 +1211,9 @@ vitisApp.on('appMainDrtvLoaded', function () {
                     '</div>',
             link: function (scope, element, attrs) {
 
-                scope.textValue = (goog.isDefAndNotNull(attrs["hidevalue"])) ? "" : scope["row"]["entity"][scope["col"]["field"]] + "%";
+                scope.$watch("row.entity." + scope["col"]["field"], function(val){
+                    scope.textValue = (goog.isDefAndNotNull(attrs["hidevalue"])) ? "" : val + "%";
+                });
 
                 if (goog.isDefAndNotNull(attrs["mode"]))
                     element[0].firstChild.className = element[0].firstChild.className + " progress-bar-" + attrs["mode"];
@@ -1693,4 +1695,261 @@ vitisApp.on('appMainDrtvLoaded', function () {
         envSrvc["oFormValues"][envSrvc["sFormDefinitionName"]]["tr_status_method"] = sMethod;
         // l'event submit du formulaire sera appelé après cette fonction 
     };
+    
+    /**
+     * loadVitisExploitation function.
+     * Chargement des sections du mode "exploitation".
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["loadVitisExploitation"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var envSrvc = angular.element(vitisApp.appWorkspaceListDrtv).injector().get(["envSrvc"]);
+        //
+        $log.info("loadVitisExploitation");
+        // Passage en mode "Update" (pour afficher les sections).
+        envSrvc["sMode"] = "update";
+    };
+    
+    /**
+     * initExploitationSharedDirectoryForm function.
+     * Chargement de l'arborescence du répertoire partagé.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["initExploitationSharedDirectoryForm"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var $rootScope = angular.element(vitisApp.appMainDrtv).injector().get(["$rootScope"]);
+        var $timeout = angular.element(vitisApp.appMainDrtv).injector().get(["$timeout"]);
+        var formSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["formSrvc"]);
+        var envSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["envSrvc"]);
+        //
+        $log.info("initExploitationSharedDirectoryForm");
+        // Attends la fin de l'affichage du 1er formulaire.
+        var clearListener = $rootScope.$on('formExtracted', function (event) {
+            // Supprime le "listener".
+            clearListener();
+            //
+            $timeout(function () {
+                $rootScope["loadExploitationSharedDirectoryTreeviewData"]().then(function(aNodes){
+                    $rootScope.$emit("sharedDirectoryTreeviewDataLoaded", aNodes);
+                });
+            });
+            // Huteur du treeview.
+            var oFormElementDefinition = formSrvc["getFormElementDefinition"]("shared_directory", envSrvc["sFormDefinitionName"]);
+            document.getElementById(oFormElementDefinition["id"] + "_treeview").style.height = document.getElementById("container_mode_exploitation").clientHeight - 221 + "px";
+        });
+    };
+    
+    /**
+     * refreshExploitationSharedDirectoryTreeview function.
+     * Recharge les données du treeview du répertoire partagé.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["refreshExploitationSharedDirectoryTreeview"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var $rootScope = angular.element(vitisApp.appMainDrtv).injector().get(["$rootScope"]);
+        var envSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["envSrvc"]);
+        var formSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["formSrvc"]);
+        //
+        $log.info("refreshExploitationSharedDirectoryTreeview");
+        $rootScope["loadExploitationSharedDirectoryTreeviewData"]().then(function(aNodes){
+            var oFormElementDefinition = formSrvc["getFormElementDefinition"]("shared_directory", envSrvc["sFormDefinitionName"]);
+            var oTreeviewOptions = $("#" + oFormElementDefinition["id"] + "_treeview")["treeview"](true)["options"];
+            $("#" + oFormElementDefinition["id"] + "_treeview")["treeview"](true)["remove"]();
+            oTreeviewOptions["data"] = aNodes;
+            $("#" + oFormElementDefinition["id"] + "_treeview")["treeview"](oTreeviewOptions);
+            // Huteur du treeview.
+            document.getElementById(oFormElementDefinition["id"] + "_treeview").style.height = document.getElementById("container_mode_exploitation").parentElement.clientHeight - 221 + "px";
+        });
+    };
+    
+    /**
+     * loadExploitationSharedDirectoryTreeviewData function.
+     * Charge les données du treeview du répertoire partagé.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["loadExploitationSharedDirectoryTreeviewData"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var $q = angular.element(vitisApp.appStatisticsFormDrtv).injector().get(["$q"]);
+        var propertiesSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["propertiesSrvc"]);
+        //
+        $log.info("loadExploitationSharedDirectoryTreeviewData");
+        var deferred = $q.defer();
+        var promise = deferred.promise;
+        // Charge l'arborescence du répertoire partagé.
+        ajaxRequest({
+            "method": "GET",
+            "url": propertiesSrvc["web_server_name"] + "/" + propertiesSrvc["services_alias"] + "/vitis/exploitations/SharedDirectory",
+            "success": function(response) {
+                if (response["data"]["status"] === 1) {
+                    if (typeof (response["data"]) !== "undefined")
+                        deferred.resolve(response["data"]["tree"]["data"]);
+                }
+            }
+        });
+        return promise;
+    };
+    
+    /**
+     * deleteSharedDirectoryFiles function.
+     * Charge les données du treeview du répertoire partagé.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["deleteSharedDirectoryFiles"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var $rootScope = angular.element(vitisApp.appMainDrtv).injector().get(["$rootScope"]);
+        var $translate = angular.element(vitisApp.appMainDrtv).injector().get(["$translate"]);
+        var propertiesSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["propertiesSrvc"]);
+        var envSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["envSrvc"]);
+        var formSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["formSrvc"]);
+        //
+        $log.info("deleteSharedDirectoryFiles");
+        var oFormElementDefinition = formSrvc["getFormElementDefinition"]("shared_directory", envSrvc["sFormDefinitionName"]);
+        var aFileList = $("#" + oFormElementDefinition["id"] + "_treeview")["treeview"](true)["getChecked"]();
+        if (aFileList.length > 0) {
+            var oOptions = {
+                "className": "modal-warning",
+                "message": "CONFIRM_DELETE_FILES_EXPLOITATION_EXPLOITATION",
+                "callback": function(bResponse) {
+                    if (bResponse) {
+                        // Liste des fichiers et répertoires à supprimer.
+                        var aFilePathList = [];
+                        for (var i = 0; i < aFileList.length; i++) {
+                            if (typeof(aFileList[i]["path"]["nodes"] != "undefined"))
+                                aFilePathList.push(aFileList[i]["path"]);
+                            else
+                                aFilePathList.push(aFileList[i]["path"] + "/" + aFileList[i]["name"]);
+                        }
+                        // Suppression des fichiers et répertoires.
+                        ajaxRequest({
+                            "method": "DELETE",
+                            "url": propertiesSrvc["web_server_name"] + "/" + propertiesSrvc["services_alias"] + "/vitis/exploitations/SharedDirectory",
+                            "params": {
+                                "idList": aFilePathList.join("|")
+                            },
+                            "success": function(response) {
+                                if (response["data"]["status"] == 1) {
+                                    // Message et rechargement du treeview.
+                                    $translate("SUCCESSFUL_OPERATION").then(function (sTranslation) {
+                                        $.notify(sTranslation, "success");
+                                        $rootScope["refreshExploitationSharedDirectoryTreeview"]();
+                                    });
+                                }
+                                else {
+                                    // Affichage de la fenêtre modale d'erreur.
+                                    $rootScope["modalWindow"]("dialog", response["data"]["errorMessage"], {"className": "modal-danger"});
+                                }
+                            }
+                        });
+                    }
+                }
+            }
+            $rootScope["modalWindow"]("confirm", "", oOptions);
+        }
+    };
+    
+    /**
+     * createSharedDirectoryFolder function.
+     * Création d'un répertoire dans le répertoire partagé.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["createSharedDirectoryFolder"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var $translate = angular.element(vitisApp.appMainDrtv).injector().get(["$translate"]);
+        var $rootScope = angular.element(vitisApp.appMainDrtv).injector().get(["$rootScope"]);
+        var propertiesSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["propertiesSrvc"]);
+        var envSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["envSrvc"]);
+        var formSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["formSrvc"]);
+        //
+        $log.info("createSharedDirectoryFolder");
+        // Si un répertoire est sélectionné -> création à l'intérieur.
+        var sDirectoryPath = envSrvc["oFormValues"][envSrvc["sFormDefinitionName"]]["directory_name"];
+        if (typeof(sDirectoryPath) == "string" && sDirectoryPath != "") {
+            var oFormElementDefinition = formSrvc["getFormElementDefinition"]("shared_directory", envSrvc["sFormDefinitionName"]);
+            var aFileList = $("#" + oFormElementDefinition["id"] + "_treeview")["treeview"](true)["getSelected"]();
+            if (aFileList.length > 0)
+                sDirectoryPath = aFileList[0]["path"] + "/" + sDirectoryPath;
+            //
+            var formData = new FormData();
+            formData.append("directory_path", sDirectoryPath);
+            ajaxRequest({
+                "method": "POST",
+                "url": propertiesSrvc["web_server_name"] + "/" + propertiesSrvc["services_alias"] + "/vitis/exploitations/SharedDirectory/Directory",
+                "data": formData,
+                "success": function(response) {
+                    if (response["data"]["status"] == 1) {
+                        // Message et rechargement du treeview.
+                        $translate("SUCCESSFUL_OPERATION").then(function (sTranslation) {
+                            $.notify(sTranslation, "success");
+                            $rootScope["refreshExploitationSharedDirectoryTreeview"]();
+                            var sFormElementName = envSrvc['oFormDefinition'][envSrvc['sFormDefinitionName']]['name'];
+                            document.querySelector("form[name='" + sFormElementName + "']").reset();
+                        });
+                    }
+                    else {
+                        // Affichage de la fenêtre modale d'erreur.
+                        $rootScope["modalWindow"]("dialog", response["data"]["errorMessage"], {"className": "modal-danger"});
+                    }
+                }
+            });
+        }
+        else {
+            // Affichage de la fenêtre modale d'erreur.
+            $rootScope["modalWindow"]("dialog", "FORM_NO_DIRECTORY_EXPLOITATION_EXPLOITATION", {"className": "modal-danger"});
+        }
+    };
+    
+    /**
+     * uploadSharedDirectoryFile function.
+     * Upload d'un fichier dans le répertoire partagé.
+     **/
+    angular.element(vitisApp.appMainDrtv).scope()["uploadSharedDirectoryFile"] = function () {
+        // Injection des services.
+        var $log = angular.element(vitisApp.appMainDrtv).injector().get(["$log"]);
+        var $translate = angular.element(vitisApp.appMainDrtv).injector().get(["$translate"]);
+        var $rootScope = angular.element(vitisApp.appMainDrtv).injector().get(["$rootScope"]);
+        var propertiesSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["propertiesSrvc"]);
+        var envSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["envSrvc"]);
+        var formSrvc = angular.element(vitisApp.appMainDrtv).injector().get(["formSrvc"]);
+        //
+        $log.info("uploadSharedDirectoryFile");
+        // Si un fichier est sélectionné -> upload.
+        var oFile = envSrvc["oFormValues"][envSrvc["sFormDefinitionName"]]["file"];
+        if (typeof(oFile) != "undefined" && oFile["aFiles"].length > 0) {
+            // Upload dans un répertoire.
+            var sDirectoryPath = "";
+            var oFormElementDefinition = formSrvc["getFormElementDefinition"]("shared_directory", envSrvc["sFormDefinitionName"]);
+            var aFileList = $("#" + oFormElementDefinition["id"] + "_treeview")["treeview"](true)["getSelected"]();
+            if (aFileList.length > 0)
+                sDirectoryPath = aFileList[0]["path"];
+            // Création du formdata.
+            var formData = new FormData();
+            formData.append("file", oFile["aFiles"][0]);
+            formData.append("directory_path", sDirectoryPath);
+            //
+            ajaxRequest({
+                "method": "POST",
+                "url": propertiesSrvc["web_server_name"] + "/" + propertiesSrvc["services_alias"] + "/vitis/exploitations/SharedDirectory/File",
+                "data": formData,
+                "success": function(response) {
+                    if (response["data"]["status"] == 1) {
+                        // Message, rechargement du treeview, vidage du formulaire.
+                        $translate("SUCCESSFUL_OPERATION").then(function (sTranslation) {
+                            $.notify(sTranslation, "success");
+                            $rootScope["refreshExploitationSharedDirectoryTreeview"]();
+                            var sFormElementName = envSrvc['oFormDefinition'][envSrvc['sFormDefinitionName']]['name'];
+                            document.querySelector("form[name='" + sFormElementName + "']").reset();
+                        });
+                    }
+                    else {
+                        // Affichage de la fenêtre modale d'erreur.
+                        $rootScope["modalWindow"]("dialog", response["data"]["errorMessage"], {"className": "modal-danger"});
+                    }
+                }
+            });
+        }
+        else {
+            // Affichage de la fenêtre modale d'erreur.
+            $rootScope["modalWindow"]("dialog", "FORM_NO_FILE_EXPLOITATION_EXPLOITATION", {"className": "modal-danger"});
+        }
+    };
 });
\ No newline at end of file
diff --git a/src/vitis/client/modules/vitis/lang/lang-en.json b/src/vitis/client/modules/vitis/lang/lang-en.json
old mode 100755
new mode 100644
index c8132242ba9258b6005e2fd7d9f502e8311efd72..dc98a487ebd474dde8d906521ce10687fd6b5a2f
--- a/src/vitis/client/modules/vitis/lang/lang-en.json
+++ b/src/vitis/client/modules/vitis/lang/lang-en.json
@@ -326,5 +326,21 @@
     "FORM_BILLINGGROUP_USERS_BILLINGGROUP": "Name",
     "FORM_DESCRIPTION_USERS_BILLINGGROUP": "Description",
     "FORM_AVAILABLE_USER_USERS_BILLINGGROUP": "Available users",
-    "FORM_LINKED_USER_USERS_BILLINGGROUP": "Users linked to group"
+    "FORM_LINKED_USER_USERS_BILLINGGROUP": "Users linked to group",
+    "" : "",
+    "FORM_TITLE_EXPLOITATION_EXPLOITATION" : "Shared directory",
+    "FORM_DOWNLOAD_FILE_EXPLOITATION_EXPLOITATION" : "Download file",
+    "FORM_RELOAD_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Reload directory",
+    "FORM_DELETE_FILES_EXPLOITATION_EXPLOITATION" : "Delete files",
+    "FORM_UPLOAD_FMW_FILE_EXPLOITATION_EXPLOITATION" : "Upload",
+    "FORM_FILE_EXPLOITATION_EXPLOITATION" : "File to upload",
+    "CONFIRM_DELETE_FILES_EXPLOITATION_EXPLOITATION" : "Delete selected files and directories ?",
+    "FORM_CREATE_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Create a directory",
+    "FORM_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Name of the directory to create",
+    "FORM_BTN_UPLOAD_FILE_EXPLOITATION_EXPLOITATION" : "Upload",
+    "FORM_BTN_CREATE_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Create",
+    "FORM_NO_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Please specify a name for the directory to create",
+    "FORM_NO_FILE_EXPLOITATION_EXPLOITATION" : "Please select a file to upload",
+    "DIRECTORY_CREATION_ERROR_EXPLOITATION_EXPLOITATION" : "Directory creation error",
+    "FILE_UPLOAD_ERROR_EXPLOITATION_EXPLOITATION" : "File creation error"
 }
diff --git a/src/vitis/client/modules/vitis/lang/lang-fr.json b/src/vitis/client/modules/vitis/lang/lang-fr.json
old mode 100755
new mode 100644
index a25cbd86a472840b7cd34f0aeb4db57686e83610..c752c00a89122b4ccf90a5bb275a952f7ebfc775
--- a/src/vitis/client/modules/vitis/lang/lang-fr.json
+++ b/src/vitis/client/modules/vitis/lang/lang-fr.json
@@ -328,5 +328,21 @@
     "FORM_BILLINGGROUP_USERS_BILLINGGROUP": "Nom",
     "FORM_DESCRIPTION_USERS_BILLINGGROUP": "Description",
     "FORM_AVAILABLE_USER_USERS_BILLINGGROUP": "Utilisateurs disponibles",
-    "FORM_LINKED_USER_USERS_BILLINGGROUP": "Utilisateurs liés au groupe"
+    "FORM_LINKED_USER_USERS_BILLINGGROUP": "Utilisateurs liés au groupe",
+    "" : "",
+    "FORM_TITLE_EXPLOITATION_EXPLOITATION" : "Répertoire partagé",
+    "FORM_DOWNLOAD_FILE_EXPLOITATION_EXPLOITATION" : "Télécharger le fichier",
+    "FORM_RELOAD_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Recharger le répertoire",
+    "FORM_DELETE_FILES_EXPLOITATION_EXPLOITATION" : "Supprimer les fichiers",
+    "FORM_UPLOAD_FMW_FILE_EXPLOITATION_EXPLOITATION" : "Uploader",
+    "FORM_FILE_EXPLOITATION_EXPLOITATION" : "Fichier à uploader",
+    "CONFIRM_DELETE_FILES_EXPLOITATION_EXPLOITATION" : "Supprimer les fichiers et répertoires sélectionnés ?",
+    "FORM_CREATE_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Créer un dossier",
+    "FORM_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Nom du dossier à créer",
+    "FORM_BTN_UPLOAD_FILE_EXPLOITATION_EXPLOITATION" : "Uploader",
+    "FORM_BTN_CREATE_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Créer",
+    "FORM_NO_DIRECTORY_EXPLOITATION_EXPLOITATION" : "Veuiller spécifier un nom pour le dossier à créer",
+    "FORM_NO_FILE_EXPLOITATION_EXPLOITATION" : "Veuiller sélectionner un fichier à uploader",
+    "DIRECTORY_CREATION_ERROR_EXPLOITATION_EXPLOITATION" : "Erreur de création du dossier",
+    "FILE_UPLOAD_ERROR_EXPLOITATION_EXPLOITATION" : "Erreur pendant l'upload du fichier"
 }
diff --git a/src/vitis/client/modules/vitis/less/main.less b/src/vitis/client/modules/vitis/less/main.less
index 66adeeb6954871428c3685880d1a6a9bbb8ee302..bbfd6cb88daa780124cac53154b6278d493816d8 100755
--- a/src/vitis/client/modules/vitis/less/main.less
+++ b/src/vitis/client/modules/vitis/less/main.less
@@ -7,4 +7,5 @@
 @import 'updateConfiguration.less';
 @import 'users.less';
 @import 'activeDirectoryTree.less';
-@import 'webServiceHelp.less';
\ No newline at end of file
+@import 'webServiceHelp.less';
+@import 'sharedDirectory.less';
\ No newline at end of file
diff --git a/src/vitis/client/modules/vitis/less/sharedDirectory.less b/src/vitis/client/modules/vitis/less/sharedDirectory.less
new file mode 100755
index 0000000000000000000000000000000000000000..7672659599a8c4ad76d0f469e8114d4202d7a937
--- /dev/null
+++ b/src/vitis/client/modules/vitis/less/sharedDirectory.less
@@ -0,0 +1,3 @@
+.shared-directory-treeview .treeview {
+    overflow-y: auto;
+}
\ No newline at end of file
diff --git a/src/vitis/vas/rest/class/aws_lib/AmazonAWS.class.inc b/src/vitis/vas/rest/class/aws_lib/AmazonAWS.class.inc
old mode 100755
new mode 100644
index 67f30140fb630544249a97969ea0e7b51f7259c1..223a0534b6262627e65631e7905eb9256825f8b9
--- a/src/vitis/vas/rest/class/aws_lib/AmazonAWS.class.inc
+++ b/src/vitis/vas/rest/class/aws_lib/AmazonAWS.class.inc
@@ -13,6 +13,7 @@ Class AmazonAWS {
     public $sAwsRegion;
     public $aLastCurlRequestInfo;
     public $sHost;
+    public $sLogFilePath;   // Chemin optionnel vers le fichier de log pour Amazon S3.
     private $sAwsAccessKeyId;
     private $sAwsSecretAccessKey;
     private $sHashingAlgorithmString;
@@ -467,5 +468,18 @@ Class AmazonAWS {
     function generateAuthorizationHeader($sAlgorithm, $sCredentialScope, $sSignedHeaders, $sSignature) {
         return $sAlgorithm . ' Credential=' . $this->sAwsAccessKeyId . '/' . $sCredentialScope . ', SignedHeaders=' . $sSignedHeaders . ', Signature=' . $sSignature;
     }
+    
+    /**
+     * Write a message to the error log file.
+     * @param {string} $sMessage Message to write to the log file.
+     */
+    function writeToErrorLog($sMessage) {
+        $aDebugBacktrace = debug_backtrace();
+        $sLogMessage = '|ERROR|' . $aDebugBacktrace[1]['class'] . '::' . $aDebugBacktrace[1]['function'] . '| ' . $sMessage;
+        if (empty($this->sLogFilePath))
+            writeToErrorLog($sLogMessage);
+        else
+            writeToLog($sLogMessage, $this->sLogFilePath);
+    }
 }
 ?>
\ No newline at end of file
diff --git a/src/vitis/vas/rest/class/aws_lib/AmazonS3.class.inc b/src/vitis/vas/rest/class/aws_lib/AmazonS3.class.inc
old mode 100755
new mode 100644
index f9bfdb4dcc555ceb4122ffec2b794e4a3180b82f..32c7ed76f933ba2499f7cfa63c4a943cb4fa6bd9
--- a/src/vitis/vas/rest/class/aws_lib/AmazonS3.class.inc
+++ b/src/vitis/vas/rest/class/aws_lib/AmazonS3.class.inc
@@ -102,9 +102,6 @@ Class AmazonS3 extends AmazonAWS {
         }
 
         $sFullUrl = $sMethod . ' ' . $sUrl . ' HTTP/1.1';
-
-        error_log($sFullUrl);
-
         return $this->generateAwsSignedHeaders($sFullUrl, $sBucketHost, self::API_COMPONENT_SERVICE, $aHeaders, $sRequestPayload, true, 'Now', true);
     }
 
@@ -171,8 +168,10 @@ Class AmazonS3 extends AmazonAWS {
         // Transfert cURL.
         $sRequestResult = $this->curlRequest($sUrl, $sMethod, null, $aHeaders);
         //
-        if ($this->aLastCurlRequestInfo['http_code'] != 200)
-            writeToErrorLog($sRequestResult);
+        if ($this->aLastCurlRequestInfo['http_code'] != 200) {
+            $this->writeToErrorLog($this->formatS3ErrorMessage($sRequestResult));
+            return false;
+        }
         else {
             if (!empty($sFilePath))
                 file_put_contents($sFilePath, $sRequestResult);
@@ -191,24 +190,23 @@ Class AmazonS3 extends AmazonAWS {
     function uploadFile($sBucket, $sKey, $sFilePath) {
         if (file_exists($sFilePath)) {
             $sFileName = pathinfo($sFilePath, PATHINFO_BASENAME);
-
             // Url vers le fichier.
             $sUrl = 'https://' . $sBucket . '.' . $this->sHost;
-
             // Génération des entêtes pour la requete.
             $aPostData = $this->generatePostData($sBucket, $sKey);
             $aPostData['Content-Type'] = mime_content_type($sFilePath);
             $aPostData['file'] = new CurlFile(realpath($sFilePath), $aPostData['Content-Type'], $sFileName);
-
             $aHeaders = array(
                 'Content-Type: multipart/form-data',
             );
-
             $sRequestResult = $this->curlRequest($sUrl, 'post', $aPostData, $aHeaders, true);
-
-            if ($this->aLastCurlRequestInfo['http_code'] != 204)
-                writeToErrorLog($sRequestResult);
+            if ($this->aLastCurlRequestInfo['http_code'] != 204) {
+                $this->writeToErrorLog($this->formatS3ErrorMessage($sRequestResult));
+                return false;
+            }
         }
+        else
+            return false;
     }
 
     /**
@@ -229,10 +227,12 @@ Class AmazonS3 extends AmazonAWS {
         $aHeaders = $this->generateS3requestHeaders($sMethod, $sUrl, $sBucket, array('Content-Type: application/x-www-form-urlencoded'), '');
         // Transfert cURL.
         $sRequestResult = $this->curlRequest($sUrl, $sMethod, null, $aHeaders);
-        //error_log($sRequestResult);
-        if ($this->aLastCurlRequestInfo['http_code'] != 200){
-            writeToErrorLog("ERROR: ScanDir can't scan this prefix or this bucket");
-        } else {
+        if ($this->aLastCurlRequestInfo['http_code'] != 200) {
+            $this->writeToErrorLog("ERROR: ScanDir can't scan this prefix or this bucket");
+            $this->writeToErrorLog($this->formatS3ErrorMessage($sRequestResult));
+            return false;
+        }
+        else {
             $oXMLContent= json_decode(json_encode(simplexml_load_string($sRequestResult)), true);
             $oFiles = $this->awsObjectListXmlToTree($oXMLContent, $bWithFileInfos);
         }
@@ -332,14 +332,44 @@ Class AmazonS3 extends AmazonAWS {
         // Transfert cURL.
         $sRequestResult = $this->curlRequest($sUrl, $sMethod, null, $aHeaders);
         
-        if ($this->aLastCurlRequestInfo['http_code'] != 200){
-            writeToErrorLog("ERROR: it's impossible to delete this key in this bucket");
-        } else {
+        if ($this->aLastCurlRequestInfo['http_code'] != 200) {
+            $this->writeToErrorLog("ERROR: it's impossible to delete this key in this bucket");
+            $this->writeToErrorLog($this->formatS3ErrorMessage($sRequestResult));
+        } else
             $bReturn = true;
-            error_log($sRequestResult);
-        }
 
         return $bReturn;
     }
+    
+    /**
+     * Convert an error message returned by s3 (xml to object).
+     * @param {string} $sXmlErrorMessage Error message returned by s3 (xml format).
+     * @return object S3 Error 
+     */
+    function getS3ErrorObject($sXmlErrorMessage) {
+        $oSimpleXmlElement = simplexml_load_string($sXmlErrorMessage);
+        if (is_object($oSimpleXmlElement)) {
+            $oErrorMessage = new stdClass();
+            foreach ($oSimpleXmlElement as $sProperty => $oValue) {
+                $oErrorMessage->$sProperty = $oValue->__toString();
+            }
+            return $oErrorMessage;
+        }
+        else
+            return false;
+    }
+    
+    /**
+     * Format an error message returned by s3.
+     * @param {string} $sXmlErrorMessage Error message returned by s3 (xml format).
+     * @return string Error message
+     */
+    function formatS3ErrorMessage($sXmlErrorMessage) {
+        $oErrorMessage = $this->getS3ErrorObject($sXmlErrorMessage);
+        if ($oErrorMessage !== false)
+            return ($oErrorMessage->Code . ' : ' . $oErrorMessage->Message);
+        else
+            return $sXmlErrorMessage;
+    }
 }
 ?>
\ No newline at end of file
diff --git a/src/vitis/vas/rest/class/vitis_lib/VitisError.class.inc b/src/vitis/vas/rest/class/vitis_lib/VitisError.class.inc
index 0d61f69fcd02cf3cf89e8758a57bb2723d85eef4..1c52cfaa95a3a0479a910281e35cde8f25376703 100644
--- a/src/vitis/vas/rest/class/vitis_lib/VitisError.class.inc
+++ b/src/vitis/vas/rest/class/vitis_lib/VitisError.class.inc
@@ -4,7 +4,7 @@ require_once(__DIR__."/DbClass.class.inc");
 
 class VitisError extends DbClass  {
 		
-    function __construct($iErrorId, $sMessage=""){
+    function __construct($iErrorId, $sErrorMessage="", $sMessage = ''){
 		$this->aFields['errorCode']=$iErrorId;	
 		switch ($iErrorId){
 			case 1 :
@@ -57,9 +57,17 @@ class VitisError extends DbClass  {
 			break;
 			case 18 :
 				$this->aFields['errorType']="Missing privileges";
+			case 17 :
+				$this->aFields['errorType']="The request returned an error";
+			break;
+			case 19 :
+				$this->aFields['errorType']="The database is unreachable";
 			break;
 		}
-		$this->aFields['errorMessage']=$sMessage; //Message renvoyé par la base de donnée
+		$this->aFields['errorMessage']=$sErrorMessage; //Message renvoyé par la base de donnée
+		// Message d'erreur additionnel.
+		if (!empty($sMessage))
+		    $this->aFields['message'] = $sMessage;
     }
 }
 ?>
\ No newline at end of file
diff --git a/src/vitis/vas/rest/class/vmlib/BD.class.inc b/src/vitis/vas/rest/class/vmlib/BD.class.inc
old mode 100755
new mode 100644
diff --git a/src/vitis/vas/rest/class/vmlib/error.inc b/src/vitis/vas/rest/class/vmlib/error.inc
old mode 100755
new mode 100644
index b36e043d301409462ee479bed0ea211463bb8a54..13db7b08ff362840fee0ef2bd2d8b84d0c63b52b
--- a/src/vitis/vas/rest/class/vmlib/error.inc
+++ b/src/vitis/vas/rest/class/vmlib/error.inc
@@ -19,6 +19,10 @@ define('ERROR_0008', "ERROR - Aucune méthode n'a permis d'affecté un moteur au
 // define('ERROR_0009', "ERROR - L'algorithme ne permet pas de retourner un numéro de moteur exploitable. Le numéro de moteur retourné n'est pas de type entier. Type de la valeur retournée par la méthode : ");
 // define('ERROR_0010', "ERROR - Le numéro du moteur retourné par l'algorithme n'existe pas dans la liste des moteurs disponible dans GTF.");
 define('ERROR_0011', "Erreur Le fichier [_FILES[sNomObjet][name]] n'est pas téléchargé sur le serveur");
+define('ERROR_0035', "Erreur de la suppression d'un processus d'une demande stoppée");
+define('ERROR_0036', "Erreur de la commande d'information d'un processus d'une demande stoppée");
+define('ERROR_0037', "Erreur pendant l'arrêt de la demande sur Fme Desktop.");
+define('ERROR_0038', "Erreur pendant l'arrêt de la demande sur Fme Server.");
 
 // veremap/DownloadMaj.class.inc
 define('ERROR_0012', "Unable to write file");
diff --git a/src/vitis/vas/rest/class/vmlib/logUtil.inc b/src/vitis/vas/rest/class/vmlib/logUtil.inc
old mode 100755
new mode 100644
index f1334250b8024768910a30fecc9ac5a58b72f681..d7474ff379d5a0cf1850ac78f8ab2f5712560450
--- a/src/vitis/vas/rest/class/vmlib/logUtil.inc
+++ b/src/vitis/vas/rest/class/vmlib/logUtil.inc
@@ -7,7 +7,7 @@
  * Fonctions de mise en place de logs
  *
  * \author Olivier Gayte <olivier.gayte@veremes.com>
- * \author Fr�d�ric Mauro
+ * \author Frédéric Mauro
  */
 /*
  * Variable globale stockant une erreur.
@@ -20,8 +20,8 @@ $sMessageLogError = "";
 $sFolderLib = "vmlib";
 /**
  * Converti une chaine ISO-8859-1 en UTF-8
- * \param $sString Cha�ne de caract�res � convertir.
- * \return une chaine encod�e en UTF-8
+ * \param $sString Chaîne de caractères à convertir.
+ * \return une chaine encodée en UTF-8
  */
 /* function Latin1ToUtf8($sString){ 
   if( mb_detect_encoding($sString,"UTF-8, ISO-8859-1")!="UTF-8" ){
@@ -52,22 +52,45 @@ function writeToLog($sString, $sFileName) {
         return false;
     global $properties, $sMessageLogError, $sFolderLib;
 
-    // Fred 05/06/2013 : Si le r�pertoire de log n'existe pas : cr�ation	
+    // Si le répertoire de log n'existe pas : création	
     if (!is_dir(dirname($sFileName)))
         mkdir(dirname($sFileName), 0777, true);
     if (empty(pathinfo($sFileName, PATHINFO_EXTENSION)))
         return false;
- 
+
+    // Add Date and User informations before writing message in log file
     loadLang($sFolderLib, $properties["language"], $sFolderLib . "/");
     $sString = str_replace(chr(13), '[\n]', $sString);
     $sString = str_replace(chr(10), '[\n]', $sString);
-    $handle = fopen($sFileName, 'a');
     if(isset($_SESSION['ses_Login']) && isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['REMOTE_PORT'])){
         $sPrelog = date("d/n/Y H:i:s").' '.$_SESSION['ses_Login'].' '.$_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'];
     } else {
         $sPrelog = date("d/n/Y H:i:s");
     }
-    if (fwrite($handle, $sPrelog . $properties["log_delim"] . $sString . CR . LF) === false) {
+
+    $sMessageLogtoWrite = $sPrelog . $properties["log_delim"] . $sString . CR . LF;
+
+    // Rename old file if greater than porperties log_size (maximum log size to open it through app in Kb)
+    // Get size of Log file in bytes
+    $iLogFileSize = filesize($sFileName);
+
+    if($iLogFileSize !== false){
+        // get size of log message
+        $iMessageLength = strlen($sMessageLogtoWrite);
+        $iTotalSizeKb = ($iLogFileSize + $iMessageLength) / 1024;
+        // compare with porperties log_size (maximum log size to open it through app in Kb)
+        if($iTotalSizeKb >= $properties['log_size'] - 1){
+            // Rename of the original file to split log and keep the possibility to read it through application
+            $sFileSplitName = str_replace(".log", "." . date("Y_m_d_U") . ".log", $sFileName);
+            if(!rename($sFileName, $sFileSplitName)){
+                $sMessageLogError = ERROR_IMPOSSIBLE_WRITE . $sFileName . ERROR_RIGHTS_ON_FILE . " (" . $sString . ").";
+            }
+        }
+    }
+
+    // create if needed and open log file to write log message inside. 
+    $handle = fopen($sFileName, 'a');
+    if (fwrite($handle, $sMessageLogtoWrite) === false) {
         fclose($handle);
         if (is_writable($sFileName)) {
             $sMessageLogError = ERROR_IMPOSSIBLE_WRITE . $sFileName . ERROR_RIGHTS_ON_FILE . " (" . $sString . ").";
diff --git a/src/vitis/vas/rest/class/vmlib/phpUtil.inc b/src/vitis/vas/rest/class/vmlib/phpUtil.inc
index 08c287ba00d806bb737927d08cdc2a9f5ca93229..dee4b832527ccda3d2af6ca01b50acc49085d063 100755
--- a/src/vitis/vas/rest/class/vmlib/phpUtil.inc
+++ b/src/vitis/vas/rest/class/vmlib/phpUtil.inc
@@ -203,9 +203,10 @@ function getFileName($sFullFileName) {
  *@file vmlib/phpUtil.inc
  *@param string $sFolder
  *@param string $sDestination
+ *@param string $sPassword
  *@return boolean
  */
-function createZip($sFolder, $sDestination, $sExtensionToExclude = '') {
+function createZip($sFolder, $sDestination, $sExtensionToExclude = '', $sPassword = '', $bDeleteFiles = false) {
     if (!empty($sExtensionToExclude)) {
         $aExtensionToExclude = explode('|', $sExtensionToExclude);
     } else {
@@ -222,6 +223,7 @@ function createZip($sFolder, $sDestination, $sExtensionToExclude = '') {
     $files = new RecursiveIteratorIterator(
             new RecursiveDirectoryIterator($sFolder), RecursiveIteratorIterator::LEAVES_ONLY
     );
+    $aCompressedFiles = array();
     foreach ($files as $name => $file) {
         if (!$file->isDir()) {
             $filePath = $file->getRealPath();
@@ -234,12 +236,23 @@ function createZip($sFolder, $sDestination, $sExtensionToExclude = '') {
             if (in_array($sExtension, $aExtensionToExclude)) {
                 continue;
             }
-            $zip->addFile($filePath, $relativePath);
+            if ($zip->addFile($filePath, $relativePath))
+                $aCompressedFiles[] = $filePath;
+            // Mot de passe.
+            if (!empty($sPassword))
+                $zip->setEncryptionName($oFileInfo->getFilename(), ZipArchive::EM_AES_256, $sPassword);
         }
     }
 
-    $zip->close();
-
+    if ($zip->close()) {
+        // Suppression des fichiers compressés.
+        if ($bDeleteFiles) {
+            foreach ($aCompressedFiles as $sFilePath) {
+                if (file_exists($sFilePath))
+                    unlink($sFilePath);
+            }
+        }
+    }
     return file_exists($sDestination);
 }
 
diff --git a/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.inc b/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.inc
index 34c24838743268ee7a5b0f40694ddb4094775403..36ae854ee3dd0789c11f938c6eba90dda09a36bf 100755
--- a/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.inc
+++ b/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.inc
@@ -21,7 +21,6 @@ class WabBusinessObject {
     protected $aSql = array();
     protected $bNoError = true;
     protected $sErrorMessage;
-    protected $aLastCurlRequestInfo = "";
 
     /*     * ****************************************************
       Class constructor
@@ -32,7 +31,7 @@ class WabBusinessObject {
 
     public function __construct($oBd, $aTableInfo, $aValues, $aProperties, $className, $iId = null) {
         require 'BusinessObject.class.sql.inc';
-        $this->aTableInfo = $aTableInfo;
+        //$this->aTableInfo = $aTableInfo;
         $this->oBd = $oBd;
         $this->aValues = $aValues;
         $this->aProperties = $aProperties;
@@ -41,12 +40,30 @@ class WabBusinessObject {
         $this->history = "";
     }
 
+    /*     * ****************************************************
+      Sauve l'action réalisé par l'utilisateur
+      \sEvent : action réalisé (changement de statut...)
+     * **************************************************** */
+
+    private function addHistoryEvent($sEvent) {
+        $this->history .= date('d/m/Y H:i') . ' | ' . $_SESSION['ses_Login'] . ' | ' . $sEvent . PHP_EOL;
+    }
 
-     /* *****************************************************
+    /*     * ****************************************************
       Change le statut
       \sStatus : statut
      * **************************************************** */
-
+/*
+    protected function setStatus($sStatus) {
+        // Mode insertion ?	
+        if (!empty($this->iId))
+            $this->bo_id = $this->iId;
+        //	
+        $this->status = $sStatus;
+        $this->addHistoryEvent($this->status);
+        $this->save();
+    }
+*/
     public function wabSetStatus($sSchema, $sTable, $sBoNameField, $mBoIdValue, $sStatusName, $sView = '') {
         require 'BusinessObject.class.sql.inc';
 
@@ -62,24 +79,20 @@ class WabBusinessObject {
           );
         $oResultat = $this->oBd->executeWithParams($aSQL["getStatusId"], $aParams);
 
-        //$this->status = $this->oBd->objetSuivant($oResultat)->status_id;
-		$oStatus = $this->oBd->objetSuivant($oResultat);
+        $this->status = $this->oBd->objetSuivant($oResultat)->status_id;
         // ajout historique
-        //$this->addHistoryEvent($this->status);
-        //$this->addHistoryEvent($oStatus->name);
-		// UPDATE dans la table avec le boName
+        $this->addHistoryEvent($this->status);
+        // UPDATE dans la table avec le boName
         $sSql = $aSQL["updateStatus"];
         $aParams = array(
           "SCHEMA" => array("value"=> $sSchema, "type"=> 'column_name'),
           "TABLE" => array("value"=> $sView, "type"=> 'column_name'),
-          "STATUS_ID" => array("value"=> $oStatus->status_id, "type"=> 'number'),
+          "STATUS_ID" => array("value"=> $this->status, "type"=> 'number'),
           "BOIDFIELD" => array("value"=> $sBoNameField, "type"=> 'column_name'),
           "BOID" => array("value"=> $mBoIdValue, "type"=> 'number')
           );
 
         $this->oBd->executeWithParams($sSql, $aParams);
-		
-		$this->aValues["status_id"] = $oStatus->status_id;
     }
 
     public function wabGetStatus($sSchema, $sTable, $sBoNameField, $mBoIdValue) {
@@ -96,28 +109,13 @@ class WabBusinessObject {
         $oResultat = $this->oBd->executeWithParams($sSql, $aParams);
         return $this->oBd->objetSuivant($oResultat)->name;
     }
-	
-	public function wabGetObject($sSchema, $sTable, $sBoNameField, $mBoIdValue){
-		require 'BusinessObject.class.sql.inc';
-		$aParams = array(
-          "SCHEMA" => array("value"=> $sSchema, "type"=> 'column_name'),
-          "TABLE" => array("value"=> $sTable, "type"=> 'column_name'),
-          "BOIDFIELD" => array("value"=> $sBoNameField, "type"=> 'column_name'),
-          "BOID" => array("value"=> $mBoIdValue, "type"=> 'number')
-          );
-
-        $oResultat = $this->oBd->executeWithParams($aSQL["getBoValues"], $aParams);
-		$oFields = (array) $this->oBd->objetSuivant($oResultat);
-		
-		return $oFields;
-	}
     /*     * ********************************************************************
       Ajoute une note
       \sLineAttribute : Champ de form. contenant la note à ajouter
       \sNoteAttribute : Champ de form. contenant l'historique des notes
      * ******************************************************************** */
 
-    public function addNote($sLineAttribute, $sNoteAttribute) {
+    protected function addNote($sLineAttribute, $sNoteAttribute) {
         if (!empty($this->aValues[$sLineAttribute])) {
             // Mode insertion ?
             if (!empty($this->iId))
@@ -223,10 +221,8 @@ class WabBusinessObject {
      * ******************************************************************** */
 
     function save() {
-        //$aValues = $this->getClassParameters();
-        //$this->oBd->update($this->aTableInfo['schema_name'], str_replace($this->aTableInfo["module"] . "_", "", $this->aTableInfo['name']), $aValues, $this->aTableInfo['id_field'], $this->bo_id, $this->aTableInfo['id_field_type']);
-		$aValues = $this->getClassParameters();
-        $this->oBd->update($this->aTableInfo['schema_name'], $this->aTableInfo['name'], $aValues, $this->aTableInfo['id_field'], $this->bo_id, $this->aTableInfo['id_field_type']);
+        $aValues = $this->getClassParameters();
+        $this->oBd->update($this->aTableInfo['schema_name'], str_replace($this->aTableInfo["module"] . "_", "", $this->aTableInfo['name']), $aValues, $this->aTableInfo['id_field'], $this->bo_id, $this->aTableInfo['id_field_type']);
     }
 
     /*     * ********************************************************************
@@ -257,38 +253,44 @@ class WabBusinessObject {
         
       $bNoError = true;
 
-      //get workspace id
-      $sSQL = "SELECT workspace_id FROM [SCHEMA_GTF].workspace WHERE key = [WK_KEY];";
-      $aParams = array(
-        "SCHEMA_GTF" => array('value'=> $this->aProperties["schema_gtf"], 'type' => 'column_name'),
-        "WK_KEY" => array('value'=> $sWorkspaceKey, 'type' => 'string'),
-      );
-      $oWK = $this->oBd->executeWithParams($sSQL, $aParams);
-      // oBd en erreur
-      $iWKid = $this->oBd->objetSuivant ($oWK)->workspace_id;
-      // Insertion de la demande
-      $sUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'] . '/gtf/userorders';
-      $postfields = array(
-      //'token'=>$sToken, 
-        'order_date' => date('Y-m-d'),
-        'workspace_id'=>$iWKid, 
-        'priority_id'=>$iPriorityId,
-        'email_option_id'=>$iEmailOptionId,
-        'wk_params'=>$sWkParams,
-        'xslstylesheet'=>$sXslStyleSheet
-      );
-        
-      if ( $sEmailNotifications != null){
-        $postfields['email_notifications'] = $sEmailNotifications;
+      if($properties['web_server_name'] === "[HTTP_HOST]"){
+        $properties['web_server_name'] = "https://localhost";
       }
-      
-      $oReturn = $this->contactCurrentApi("POST", 'gtf/userorders', $postfields , $sMode="json");
-	  
-	  error_log(print_r($oReturn, true));
 
-      if($oReturn === false){
+      // Get token  
+      $sToken = $this->getToken();
+
+      if ($sToken !== false) {
+
+        //get workspace id
+        $sSQL = "SELECT workspace_id FROM [SCHEMA_GTF].workspace WHERE key = [WK_KEY];";
+        $aParams = array(
+          "SCHEMA_GTF" => array('value'=> $this->aProperties["schema_gtf"], 'type' => 'column_name'),
+          "WK_KEY" => array('value'=> $sWorkspaceKey, 'type' => 'string'),
+        );
+        $oWK = $this->oBd->executeWithParams($sSQL, $aParams);
+        // oBd en erreur
+        $iWKid = $this->oBd->objetSuivant ($oWK)->workspace_id;
+        // Insertion de la demande
+        $sUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'] . '/gtf/userorders';
+        $postfields = array(
+          'token'=>$sToken, 
+          'order_date' => date('Y-m-d'),
+          'workspace_id'=>$iWKid, 
+          'priority_id'=>$iPriorityId,
+          'email_option_id'=>$iEmailOptionId,
+          'wk_params'=>$sWkParams,
+          'xslstylesheet'=>$sXslStyleSheet
+        );
+        
+        if ( $sEmailNotifications != null){
+          $postfields['email_notifications'] = $sEmailNotifications;
+        }
+
+        $oReturn = $this->postCurlRequest ($sUrl, $postfields);
+                 
+      } else
         $sErrorMsg = 'Error while performing a cURL session (' . __METHOD__ . ' (get token))';
-      }
 
       if ($sErrorMsg != '') {
         writeToErrorLog($sErrorMsg);
@@ -347,41 +349,32 @@ class WabBusinessObject {
       /Retour : string token
      * ******************************************************************** */
 
-    function getToken ($sServerRestUrl = '', $aAuthParams = null) {
-
-        if($this->aProperties['web_server_name'] === "[HTTP_HOST]"){
-          $this->aProperties['web_server_name'] = "https://localhost";
-        }
+    function getToken () {
 
-        if(empty($sServerRestUrl)){
-          $sServerRestUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'];
-        }
+      if($this->aProperties['web_server_name'] === "[HTTP_HOST]"){
+        $this->aProperties['web_server_name'] = "https://localhost";
+      }
+        $sUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'] . '/vitis/privatetoken';
 
-        $sUrl = $sServerRestUrl . '/vitis/privatetoken';
-		
-        if(!empty($aAuthParams)){
-          $postfields = $aAuthParams;
-        } else if(!empty($_SESSION["ses_Login"])){
+        if(!empty($_SESSION["ses_Login"])){
           $sUserPassword = trim(des(rtrim(utf8_decode($_SESSION['ses_Login'])), hexToString(rtrim($_SESSION['ses_Password'])), 0, 0, null));
           $postfields = array('user'=>$_SESSION["ses_Login"], 'password'=>$sUserPassword);
         } else {
           $postfields = array('user'=>$this->aProperties["login_bot"], 'password'=>$this->aProperties["pass_bot"]);
         }
 
-        //$oToken = json_decode($this->postCurlRequest ($sUrl, $postfields));
-        $oToken = json_decode($this->sendCurlRequest ("POST", $sUrl, json_encode($postfields), array("Accept: applicaton/json", "Content-Type: application/json")));
-		
+        $oToken = json_decode($this->postCurlRequest ($sUrl, $postfields));
         return $oToken->token;
     }
 
     /*     * ********************************************************************
-      envoi une requete curl en POST (DEPRECATED)
+      envoi une requete curl en POST
       \$sUrl : Url pour envoyer la requete
       \$postfields : array contenant les paramètres à envoyer
       /Retour : string token
      * ******************************************************************** */
     function postCurlRequest ($sUrl, $postfields) {
-		/*$ch = curl_init($sUrl);
+      $ch = curl_init($sUrl);
         curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
         curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json"));
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@@ -389,153 +382,9 @@ class WabBusinessObject {
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
-        return curl_exec($ch);*/
-		$this->sendCurlRequest("POST", $sUrl, $postfield, array("Accept: application/json"));
-    }
-
-    function sendCurlRequest($sMethod, $sUrl, $aParams=array(), $aHeaders=array()){
-
-        $this->aLastCurlRequestInfo = '';
-        //
-        $ch = curl_init();
-        $sType = strtoupper($sMethod);
-        // Force la méthode de requête utilisée (GET, POST...).
-        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $sType);
-        // Url à utiliser.
-        if (($sType == 'GET' || $sType == 'DELETE') && !empty($aParams))
-            $sUrl .= '?' . http_build_query($aParams);
-        curl_setopt($ch, CURLOPT_URL, $sUrl);
-        // ajout des en-tête
-        curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeaders);
-        // Retour sous forme de texte. 
-        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-        // Requête POST PUT parameters.
-
-        if ($sType == 'POST' || $sType == 'PUT') {
-			if($sType == 'POST'){
-				curl_setopt($ch, CURLOPT_POST, true);
-			}
-            // Chaîne de requête en encodage URL.
-            //if (is_array($aParamsaParams) && !$bMultipartFormData)
-            //    $aParams = http_build_query($aParams);
-            // Données de la requête.
-            curl_setopt($ch, CURLOPT_POSTFIELDS, $aParams);
-            //
-            //curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
-            // Entête pour la requête en POST.
-            //$aHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
-        }
-
-        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
-        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
-        // Curl error: SSL certificate problem: unable to get local issuer certificate
-        // Curl error n°60
-        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
-		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
-        //
-        $output = curl_exec($ch);
-        // Erreur de la requête CURL.
-        if(curl_errno($ch)) {
-            writeToErrorLog('Curl error: ' . curl_error($ch));
-            writeToErrorLog('Curl error n°' . curl_errno($ch));
-        }
-        // Informations de la requête.
-        $aCurlInfo = curl_getinfo($ch);
-        $this->aLastCurlRequestInfo = $aCurlInfo;
-        
-        // Ferme la session CURL.
-        curl_close($ch);
-        return $output;
-    }
-
-    function contactCurrentApi($sMethod, $sUrlPath, $aParams=array(), $sMode="json", $aAuthParams = null){
-
-      if($this->aProperties['web_server_name'] === "[HTTP_HOST]"){
-          $this->aProperties['web_server_name'] = "https://localhost";
-        }
-
-      $sRestUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'];
-
-      $this->contactAnotherApi($sMethod, $sRestUrl, $sUrlPath, $aParams, $sMode, $aAuthParams);
+        return curl_exec($ch);
     }
 
-    function contactAnotherApi($sMethod, $sRestUrl, $sUrlPath, $aParams=array(), $sMode="json", $aAuthParams = null){
-        $mToken = $this->getToken($sRestUrl, $aAuthParams);
-		
-        $sUrl = $sRestUrl . "/" . $sUrlPath;
-
-        if($mToken !== false){
-
-            // modification des paramètres si besoin
-            $aSendParams = array();
-            $aHeaders = array("token: " . $mToken);
-
-            switch ($sMode) {
-                case 'json':
-                    $aSendParams = json_encode($aParams);
-                    $aHeaders[] = "Content-Type: application/json";
-                    $aHeaders[] = "Accept: application/json";
-                    break;
-                case 'query':
-                    $sUrl .= '?' . http_build_query($aParams);
-                    $aHeaders[] = "Accept: application/x-vm-json";
-                    break;
-                case 'urlencode':
-                    $aSendParams = http_build_query($aParams);
-                    $aHeaders[] = "Accept: application/x-www-form-urlencoded";
-                    break;
-                case 'formdata' :
-                    $aSendParams = $aParams;
-                    break;
-            }
-
-            $sOutput = $this->sendCurlRequest($sMethod, $sUrl, $aSendParams, $aHeaders);
-			error_log(print_r($this->aLastCurlRequestInfo, true));
-            return $sOutput;
-        } else {
-            writeToErrorLog("This user can't have a token on Calimap at URL : " . $sRestUrl);
-            return false;
-        }
-    }
-	
-	/**********************************************************************
-      Sauve l'historique deprecated
-    **********************************************************************/
-    function saveHistory() {
-        $aHistoryValues = array('bo_id' => $this->aValues["my_vitis_id"], 'login' => $_SESSION['ses_Login'], 'comment' => $this->status, 'date' => date('Y-m-d H:i:s'));
-        $this->oBd->insert($this->aTableInfo['schema_name'], 'history', $aHistoryValues, $this->aTableInfo['schema_name'] . '.history_history_id_seq', 'history_id');
-    }
-	/**********************************************************************
-      Sauve une note ou commentaire (history sert d'historique)
-    **********************************************************************/
-	function addHistoryLine($sComment, $sHistoryTable, $iBoId){
-		$sUser = 'u_scheduler';
-		if(isset($_SESSION['ses_Login']) && !empty($_SESSION['ses_Login'])){
-			$sUser = $_SESSION['ses_Login'];
-		}
-		
-		$aHistoryValues = array('bo_id' => $iBoId, 'login' => $sUser, 'comment' => $sComment, 'date' => date('Y-m-d H:i:s'));
-        $this->oBd->insert($this->aTableInfo['schema_name'], $sHistoryTable, $aHistoryValues, $this->aTableInfo['schema_name'] . '.seq_' . $sHistoryTable . "_id" , 'history_id');
-	}
-	
-	function commitNoteLine($sNoteLineField, $sNoteTable, $sBoTable, $sFieldId, $iBoId){
-		// get note line
-		$aFields = $this->wabGetObject($this->aTableInfo['schema_name'], $sBoTable, $sFieldId, $iBoId);
-		
-		if(!empty($aFields[$sNoteLineField])){
-			$sUser = 'u_scheduler';
-			if(isset($_SESSION['ses_Login']) && !empty($_SESSION['ses_Login'])){
-				$sUser = $_SESSION['ses_Login'];
-			}
-			$aNoteValues = array('bo_id' => $iBoId, 'login' => $sUser, 'comment' => $aFields[$sNoteLineField], 'date' => date('Y-m-d H:i:s'));
-			$this->oBd->insert($this->aTableInfo['schema_name'], $sNoteTable, $aNoteValues, $this->aTableInfo['schema_name'] . '.seq_' . $sNoteTable . "_id", 'history_id');
-		}
-		
-		// reset note line
-		$this->aValues[$sNoteLineField] = "";
-		$this->save();
-	}
-	
 }
 
 ?>
diff --git a/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.sql.inc b/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.sql.inc
index a18ed1f2df0594917c4cdf5ec15499b422dd2273..bf02e36db648547116d594e3689cc070a8d36fc8 100755
--- a/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.sql.inc
+++ b/src/vitis/vas/rest/class/wab_lib/BusinessObject.class.sql.inc
@@ -1,6 +1,5 @@
 <?php
     $aSQL["getStatusId"] = 'SELECT * FROM [SCHEMA].rt_[TABLE]_status WHERE name = [STATUS_NAME]';
-	$aSQL["getBoValues"] = 'SELECT * FROM [SCHEMA].[TABLE] WHERE [TABLE].[BOIDFIELD]=[BOID]';
-    $aSQL["updateStatus"] = 'UPDATE [SCHEMA].[TABLE] SET status_id=[STATUS_ID] WHERE [TABLE].[BOIDFIELD]=[BOID]';
+    $aSQL["updateStatus"] = 'UPDATE [SCHEMA].v_[TABLE] SET status_id=[STATUS_ID] WHERE v_[TABLE].[BOIDFIELD]=[BOID]';
     $aSQL["getStatusName"] = 'SELECT name FROM [SCHEMA].rt_[TABLE]_status WHERE status_id = (SELECT status_id FROM [SCHEMA].[TABLE] WHERE [TABLE].[BOIDFIELD]=[BOID])';
 ?>
\ No newline at end of file
diff --git a/src/vitis/vas/rest/conf/properties.inc b/src/vitis/vas/rest/conf/properties.inc
old mode 100755
new mode 100644
diff --git a/src/vitis/vas/rest/conf/selected_properties.inc b/src/vitis/vas/rest/conf/selected_properties.inc
old mode 100755
new mode 100644
diff --git a/src/vitis/vas/rest/ws/vitis/Exploitations.class.inc b/src/vitis/vas/rest/ws/vitis/Exploitations.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..1703c2ce5b6eed19237293c8444271e3d0e4a709
--- /dev/null
+++ b/src/vitis/vas/rest/ws/vitis/Exploitations.class.inc
@@ -0,0 +1,362 @@
+<?php
+
+/**
+ * \file Exploitations.class.inc
+ * \class Exploitations
+ *
+ * \author Yoann Perollet <yoann.perollet@veremes.com>.
+ *
+ * 	\brief This file contains the Exploitations php class
+ *
+ * This class defines Rest Api to Vitis exploitations
+ * 
+ */
+require_once 'Vitis.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once(__DIR__ . '/../../class/vmlib/BdDataAccess.inc');
+
+class Exploitations extends Vitis {
+    /**
+     * @SWG\Definition(
+     *   definition="/exploitations",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/exploitations")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Exploitations",
+     *   description="Operations about Exploitations"
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array();
+    }
+
+    /**
+     * @SWG\Get(path="/exploitations/SharedDirectory",
+     *   tags={"Exploitations"},
+     *   summary="Get shared directory tree",
+     *   description="Request to get the shared directory tree",
+     *   operationId="GET",
+     *   produces={"application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/exploitations")
+     *     )
+     *  )
+     */
+
+    /**
+     * get Exploitations
+     * @return  Exploitations
+     */
+    function GET() {
+        // Arborescence du répertoire partagé.
+        if (strtolower($this->aPath[2]) == 'shareddirectory') {
+            $aTreeview = $this->getDirectoryTree($this->aProperties['shared_dir']);
+            if (!empty($aTreeview["data"][0]["nodes"]))
+                $this->aFields['tree']['data'] = $aTreeview["data"][0]["nodes"];
+            else
+                $this->aFields['tree']['data'] = [];
+        }
+        //
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        return $sMessage;
+    }
+
+    /**
+     * Get directory tree.
+     */
+    function getDirectoryTree($sDirectoryPath) {
+        $aReturn = array('status' => 1, 'message' => '');
+        // Création de l'arborescence des fichiers du répertoire.
+        if (!empty($sDirectoryPath)) {
+            $sDirectoryName = 'Downloads';
+            if (is_string($sDirectoryPath)) {
+                if (is_dir($sDirectoryPath)) {
+                    $aDirStructure = $this->getDirStructure($sDirectoryPath, $sDirectoryName, $sDirectoryName, "");
+                    $aTreeview["data"][] = $aDirStructure["data"];
+                    if (!empty($aDirStructure["files"])) {
+                        foreach ($aDirStructure["files"] as $aFiles) {
+                            $aTreeview["files"][] = $aFiles;
+                        }
+                    }
+                } else
+                    writeToErrorLog('scandir(' . $sDirectoryPath . '): failed to open dir');
+            }
+        }
+        return $aTreeview;
+    }
+
+    /*
+     * Retourne l'arborescence d'un répertoire formaté pour "bootstrap-treeview".
+     */
+
+    function getDirStructure($sDirectoryPath, $sSubDirectoryName, $sDirectoryName, $sFolder) {
+        $aFilteredDir['data'] = array('text' => $sSubDirectoryName, 'selectable' => true, 'path' => $sFolder . '/' . $sSubDirectoryName);
+        $aDir = scandir($sDirectoryPath);
+        // Les répertoires sont affichés avant les fichiers (idem windows).
+        $aSortedDir = array();
+        $aSortedFiles = array();
+        foreach ($aDir as $sName) {
+            $sPath = $sDirectoryPath . '/' . $sName;
+            $sFileType = filetype($sPath);
+            if ($sFileType == 'dir')
+                $aSortedDir[] = $sName;
+            else
+                $aSortedFiles[] = $sName;
+        }
+        sort($aSortedDir, SORT_STRING|SORT_FLAG_CASE);
+        sort($aSortedFiles, SORT_STRING|SORT_FLAG_CASE);
+        $aDir = array_merge($aSortedDir, $aSortedFiles);
+        //
+        if ($sSubDirectoryName !== $sDirectoryName)
+            $sFolder .= '/' . $sSubDirectoryName;
+
+        foreach ($aDir as $sName) {
+            $sPath = $sDirectoryPath . '/' . $sName;
+            $sFileType = filetype($sPath);
+            // Répertoire ?
+            if ($sFileType == 'dir') {
+                if ($sName != '.' && $sName != '..') {
+                    if (is_dir($sPath)) {
+                        $aDirStructure = $this->getDirStructure($sPath . '/', $sName, $sDirectoryName, $sFolder);
+                        //if (!empty($aDirStructure['data']['nodes'])) {
+                            // Structure du répertoire.
+                            $aFilteredDir['data']['nodes'][] = $aDirStructure['data'];
+                            // Liste des fichiers du répertoire.
+                            if (!empty($aDirStructure["files"])) {
+                                foreach ($aDirStructure["files"] as $aFiles) {
+                                    $aFilteredDir["files"][] = $aFiles;
+                                }
+                            }
+                        //}
+                    } else
+                        writeToErrorLog('scandir(' . $sPath . '): failed to open dir');
+                }
+            }
+            // fichier ?
+            if ($sFileType == 'file') {
+                // Taille + unité du fichier.
+                //$iFileSize = filesize($sPath);
+                $aFileInfos = stat($sPath);
+                $iFileSizeLabel = $aFileInfos['size'];
+                $aFileSizeUnity = array('o', 'Ko', 'Mo', 'Go', 'To');
+                $i = 0;
+                while ($iFileSizeLabel > 1024) {
+                    $iFileSizeLabel /= 1024;
+                    $i++;
+                }
+                // Sauve la structure du fichier pour le treeview.
+                $sFileLabel = $sName . ' (' . round($iFileSizeLabel) . ' ' . $aFileSizeUnity[$i] . ')';
+                $aFilteredDir['data']['nodes'][] = array(
+                    'folder' => $sFolder,
+                    'directory' => $sDirectoryName,
+                    'name' => $sName,
+                    'text' => $sFileLabel,
+                    'icon' => 'glyphicon glyphicon-file',
+                    'path' => str_replace('//', '/', $sFolder . '/' . '/' . $sName),
+                    //'tags' => array('<span class="glyphicon glyphicon-trash"></span>'),
+                    'size' => $aFileInfos['size'],
+                    'selectable' => false
+                );
+                // Sauve le nom et la date du fichier.
+                $aFilteredDir['files'][] = array(
+                    'path' => str_replace('//', '/', $sFolder . '/' . '/' . $sName),
+                    //'last_modif' => floor((time() - $aFileInfos['mtime']) / (24 * 3600))    // dernière modif. (Nb jours). 
+                );
+            }
+        }
+        return $aFilteredDir;
+    }
+    
+    /**
+     * @SWG\Post(path="/exploitations/SharedDirectory/Directory",
+     *   tags={"Exploitations"},
+     *   summary="Create directory",
+     *   description="Request to create a directory",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="directory_path",
+     *     in="formData",
+     *     description="path of the directory",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/exploitations/SharedDirectory")
+     *    )
+     *  )
+     */
+
+    /**
+     * @SWG\Post(path="/exploitations/SharedDirectory/File",
+     *   tags={"Exploitations"},
+     *   summary="Ulpload file",
+     *   description="Request to upload a file",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="directory_path",
+     *     in="formData",
+     *     description="path of the directory",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/exploitations/SharedDirectory")
+     *    )
+     *  )
+     */
+    
+    /**
+     * insert user
+     * @return id of the user created
+     */
+    function POST() {
+        // Répertoire partagé.
+        if (strtolower($this->aPath[2]) == 'shareddirectory') {
+            // Création d'un répertoire.
+            if (strtolower($this->aPath[3]) == 'directory') {
+                if (!empty($this->aValues['directory_path'])) {
+                    if (mkdir($this->aProperties['shared_dir'] . '/' . $this->aValues['directory_path'])) {
+                        $aXmlRacineAttribute['status'] = 1;
+                        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                    else {
+                        $oError = new VitisError(1, 'DIRECTORY_CREATION_ERROR_EXPLOITATION_EXPLOITATION');
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+            // Upload d'un fichier.
+            else if (strtolower($this->aPath[3]) == 'file') {
+                if (!empty($_FILES["file"])) {
+                    if (!empty($this->aValues['directory_path']))
+                        $sFilePath = $this->aProperties['shared_dir'] . '/' . $this->aValues['directory_path'] . '/' . $_FILES["file"]["name"];
+                    else
+                        $sFilePath = $this->aProperties['shared_dir'] . '/' . $_FILES["file"]["name"];
+                    if (!move_uploaded_file($_FILES['file']['tmp_name'], $sFilePath)) {
+                        $oError = new VitisError(1, 'FILE_CREATION_ERROR_EXPLOITATION_EXPLOITATION');
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                    else {
+                        $aXmlRacineAttribute['status'] = 1;
+                        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+        }
+        return $sMessage;
+    }
+    
+    /**
+     * @SWG\Delete(path="/exploitations/SharedDirectory",
+     *   tags={"Exploitations"},
+     *   summary="delete shared directory files",
+     *   description="Request to delete shared directory files",
+     *   operationId="DELETE",
+     *   produces={"application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="path of the files",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/exploitations/SharedDirectory")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete exploitation files
+     */
+    function DELETE() {
+        // Verify connection.
+        if (!empty($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        // Privilège "vitis_admin" requis.
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(1, "Rights problem : you don't have right to delete shared directory files");
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        // Suppression des fichiers.
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        if (!empty($this->aValues['idList'])) {
+            $aPathsToDelete = explode('|', $this->aValues['idList']);
+            $aDirToDelete = array();
+            foreach ($aPathsToDelete as $sPath) {
+                $sPath = str_replace('//', '/', $this->aProperties['shared_dir'] . $sPath);
+                if (file_exists($sPath)) {
+                    if (is_dir($sPath))
+                        array_unshift($aDirToDelete, $sPath);
+                    else
+                        unlink($sPath);
+                }
+            }
+        }
+        // Suppression des répertoires.
+        foreach ($aDirToDelete as $sPath) {
+            rmdir($sPath);
+        }
+        //
+        return $sMessage;
+    }
+}
+?>
\ No newline at end of file
diff --git a/src/vitis/vas/rest/ws/vitis/GenericQuerys.class.inc b/src/vitis/vas/rest/ws/vitis/GenericQuerys.class.inc
old mode 100755
new mode 100644
diff --git a/src/vitis/vas/rest/ws/vitis/Modes.class.inc b/src/vitis/vas/rest/ws/vitis/Modes.class.inc
old mode 100755
new mode 100644
index f9754ec0d4f3c9291507b34474333f70bcac1b52..c838ebe1c37627b79b3783a89d8f601904e94653
--- a/src/vitis/vas/rest/ws/vitis/Modes.class.inc
+++ b/src/vitis/vas/rest/ws/vitis/Modes.class.inc
@@ -34,8 +34,8 @@ class Modes extends Vitis {
      * construct
      * @param type $aPath url of the request
      * @param type $aValues parameters of the request
-     * @param type $properties properties
-     * @param type $bShortcut false to reinit variables
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
      * @param type $oConnection connection object
      */
     function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
@@ -131,6 +131,11 @@ class Modes extends Vitis {
      */
     function GET() {
         if ($this->oConnection->oError == null) {
+            if (!empty($this->aProperties["public_token"]) && $this->aProperties["allow_public_connection"] === true){
+                if($this->aProperties["public_token"] === $this->aValues['token']){
+                    $this->aValues["filter"] = '{"relation": "AND","operators":[{"column": "mode_id","compare_operator": "<>","value": "user"}]}';
+                }
+            }
             if (isset($this->aValues['action']) && !empty($this->aValues['action'])) {
                 if ($this->aValues['action'] == 'getAll') {
                     $aReturn = $this->genericGet($this->aProperties['schema_framework'], "vm_mode_rolname", "mode_id", true);
diff --git a/src/vitis/vas/rest/ws/vitis/PrivateToken.class.inc b/src/vitis/vas/rest/ws/vitis/PrivateToken.class.inc
index 649dc10c0bc7100d38721af81cab49b19706eab2..8295dcb302800b3391b9833d953d442b1070f955 100644
--- a/src/vitis/vas/rest/ws/vitis/PrivateToken.class.inc
+++ b/src/vitis/vas/rest/ws/vitis/PrivateToken.class.inc
@@ -134,76 +134,85 @@ class PrivateToken extends Vitis {
         }
 
         if (!$bXMLError) {
-            //connect to database
-            $oBd = new BD($this->aValues["user"], $this->aValues["password"], $this->aProperties["database"], $this->aProperties["server"], $this->aProperties["port"], $this->aProperties["sgbd"], $this->aProperties["page_encoding"]);
-            $_SESSION["ses_Login"] = $this->aValues["user"];
-            $ciphertext = stringToHex(des($this->aValues["user"], $this->aValues["password"], 1, 0));
-            $_SESSION["ses_Password"] = $ciphertext;
-            $_SESSION["ses_Remember"] = false;
-            $_SESSION["ses_Date"] = date('Y-m-d H:i:s', time() + ($this->aValues['duration'] * 60));
-            if ($oBd->erreurRencontree) {
-                $oError = new VitisError(1, $oBd->sMessage);
+            // Teste si la base de données est joignable.
+            if (fsockopen($this->aProperties["server"], $this->aProperties["port"], $errno, $errstr) === false) {
+                $oError = new VitisError(19, "The database is unreachable");
                 $aXmlRacineAttribute['status'] = 0;
                 $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
-                $bXMLError = true;
-            } else {
-                // Privilège 'vitis_user' obligatoire.
-                $aParams['sLogin'] = array('value' => $this->aValues["user"], 'type' => 'string');
-                $oPDOresult = $oBd->executeWithParams($aSql['getUserConnectionPrivileges'], $aParams);
-                if ($oBd->nombreLigne($oPDOresult) == 0) {
-                    $oError = new VitisError(18, "No 'vitis_user' privilege.");
+                writeToErrorLog("ERROR : " . $errstr . ' ' . $this->aValues["user"] . "'.");
+            }
+            else {
+                //connect to database
+                $oBd = new BD($this->aValues["user"], $this->aValues["password"], $this->aProperties["database"], $this->aProperties["server"], $this->aProperties["port"], $this->aProperties["sgbd"], $this->aProperties["page_encoding"]);
+                $_SESSION["ses_Login"] = $this->aValues["user"];
+                $ciphertext = stringToHex(des($this->aValues["user"], $this->aValues["password"], 1, 0));
+                $_SESSION["ses_Password"] = $ciphertext;
+                $_SESSION["ses_Remember"] = false;
+                $_SESSION["ses_Date"] = date('Y-m-d H:i:s', time() + ($this->aValues['duration'] * 60));
+                if ($oBd->erreurRencontree) {
+                    $oError = new VitisError(1, $oBd->sMessage);
                     $aXmlRacineAttribute['status'] = 0;
                     $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
-                    writeToErrorLog("ERROR : No 'vitis_user' privilege for user '" . $this->aValues["user"] . "'.");
+                    $bXMLError = true;
                 } else {
-                    // L'utilisateur doit exister dans la table s_vitis.user
-                    $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
-                    $aParams['sLogin'] = array('value' => $_SESSION["ses_Login"], 'type' => 'string');
-                    $oPDOresult = $oBd->executeWithParams($aSql['checkUser'], $aParams);
+                    // Privilège 'vitis_user' obligatoire.
+                    $aParams['sLogin'] = array('value' => $this->aValues["user"], 'type' => 'string');
+                    $oPDOresult = $oBd->executeWithParams($aSql['getUserConnectionPrivileges'], $aParams);
                     if ($oBd->nombreLigne($oPDOresult) == 0) {
-                        $oError = new VitisError(1, 'The user ' . $_SESSION["ses_Login"] . ' does not exist');
+                    $oError = new VitisError(18, "No 'vitis_user' privilege.");
                         $aXmlRacineAttribute['status'] = 0;
                         $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
-                        writeToErrorLog('ERROR : The user ' . $_SESSION["ses_Login"] . ' does not exist.');
+                        writeToErrorLog("ERROR : No 'vitis_user' privilege for user '" . $this->aValues["user"] . "'.");
                     } else {
-                        //verify the ip from wich the user is connected
-                        $aParams = array();
+                        // L'utilisateur doit exister dans la table s_vitis.user
                         $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
                         $aParams['sLogin'] = array('value' => $_SESSION["ses_Login"], 'type' => 'string');
-                        $oPDOresult = $oBd->executeWithParams($aSql['checkIP'], $aParams);
-                        $aFields = $oBd->ligneSuivante($oPDOresult);
-                        $oMetadataAccess = new MetadataAccess($oBd, $_SESSION["ses_Login"], $_SESSION["ses_Password"], session_id(), $this->aProperties);
-                        $bAuthorizedIp = $oMetadataAccess->checkUserIp($_SERVER['REMOTE_ADDR']);
-                        if (!$bAuthorizedIp) {
-                            $oError = new VitisError(11, 'Connection to the database forbidden with the ip \'' . $_SERVER['REMOTE_ADDR'] . '\'.');
+                        $oPDOresult = $oBd->executeWithParams($aSql['checkUser'], $aParams);
+                        if ($oBd->nombreLigne($oPDOresult) == 0) {
+                            $oError = new VitisError(1, 'The user ' . $_SESSION["ses_Login"] . ' does not exist');
                             $aXmlRacineAttribute['status'] = 0;
                             $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
-                            $bXMLError = true;
-                            writeToErrorLog('ERROR : Connection to the database forbidden with the ip \'' . $_SERVER['REMOTE_ADDR'] . '\'.');
+                            writeToErrorLog('ERROR : The user ' . $_SESSION["ses_Login"] . ' does not exist.');
                         } else {
+                            //verify the ip from wich the user is connected
+                            $aParams = array();
+                            $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
+                            $aParams['sLogin'] = array('value' => $_SESSION["ses_Login"], 'type' => 'string');
+                            $oPDOresult = $oBd->executeWithParams($aSql['checkIP'], $aParams);
+                            $aFields = $oBd->ligneSuivante($oPDOresult);
+                            $oMetadataAccess = new MetadataAccess($oBd, $_SESSION["ses_Login"], $_SESSION["ses_Password"], session_id(), $this->aProperties);
+                            $bAuthorizedIp = $oMetadataAccess->checkUserIp($_SERVER['REMOTE_ADDR']);
+                            if (!$bAuthorizedIp) {
+                                $oError = new VitisError(11, 'Connection to the database forbidden with the ip \'' . $_SERVER['REMOTE_ADDR'] . '\'.');
+                                $aXmlRacineAttribute['status'] = 0;
+                                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                                $bXMLError = true;
+                                writeToErrorLog('ERROR : Connection to the database forbidden with the ip \'' . $_SERVER['REMOTE_ADDR'] . '\'.');
+                            } else {
 
-                            error_log('session_id():' . session_id());
+                                error_log('session_id():' . session_id());
 
-                            $oConnection = new Connection(Array('token' => session_id()), $this->aProperties);
-                            $this->aFields['token'] = session_id();
-                            $this->aFields['user'] = $_SESSION["ses_Login"];
-                            $this->aFields['validity_date'] = date('Y-m-d H:i:s', time() + ($this->aValues['duration'] * 60));
-                            $this->aFields['user_id'] = $aFields['user_id'];
-                            $this->aFields['privileges'] = $oConnection->aPrivileges;
-                            if ($this->aValues['output'] === 'application/xml') {
-                                $this->aFields['privileges'] = implode(',', $this->aFields['privileges']);
+                                $oConnection = new Connection(Array('token' => session_id()), $this->aProperties);
+                                $this->aFields['token'] = session_id();
+                                $this->aFields['user'] = $_SESSION["ses_Login"];
+                                $this->aFields['validity_date'] = date('Y-m-d H:i:s', time() + ($this->aValues['duration'] * 60));
+                                $this->aFields['user_id'] = $aFields['user_id'];
+                                $this->aFields['privileges'] = $oConnection->aPrivileges;
+                                if ($this->aValues['output'] === 'application/xml') {
+                                    $this->aFields['privileges'] = implode(',', $this->aFields['privileges']);
+                                }
+                                $_SESSION["ses_user_id"] = $aFields['user_id'];
+                                $_SESSION["ses_restriction"] = $aFields['restriction'];
+                                $aXmlRacineAttribute['status'] = 1;
+                                $aParams = array();
+                                $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
+                                $aParams['user_id'] = array('value' => $aFields['user_id'], 'type' => 'number');
+                                $aParams['date'] = array('value' => gmdate('Y-m-d H:i:s'), 'type' => 'string');
+                                $oPDOresult = $oBd->executeWithParams($aSql['updateLastConnection'], $aParams);
+                                $sLogString = "connection" . $this->aProperties["log_delim"] . $_SESSION["ses_Login"] . $this->aProperties["log_delim"] . session_id();
+                                writeToLog($sLogString, $this->aProperties["connexion_log_file"]);
+                                $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
                             }
-                            $_SESSION["ses_user_id"] = $aFields['user_id'];
-                            $_SESSION["ses_restriction"] = $aFields['restriction'];
-                            $aXmlRacineAttribute['status'] = 1;
-                            $aParams = array();
-                            $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
-                            $aParams['user_id'] = array('value' => $aFields['user_id'], 'type' => 'number');
-                            $aParams['date'] = array('value' => gmdate('Y-m-d H:i:s'), 'type' => 'string');
-                            $oPDOresult = $oBd->executeWithParams($aSql['updateLastConnection'], $aParams);
-                            $sLogString = "connection" . $this->aProperties["log_delim"] . $_SESSION["ses_Login"] . $this->aProperties["log_delim"] . session_id();
-                            writeToLog($sLogString, $this->aProperties["connexion_log_file"]);
-                            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
                         }
                     }
                 }
diff --git a/src/vitis/vas/rest/ws/vitis/Vitis.class.inc b/src/vitis/vas/rest/ws/vitis/Vitis.class.inc
old mode 100755
new mode 100644
diff --git a/src/vitis/vas/rest/ws/vitis/VitisSection.class.inc b/src/vitis/vas/rest/ws/vitis/VitisSection.class.inc
index cd1e1840875aac99b320e6738dbeeb319528b0d4..1328958b8b1cf354a4bfa83ad2e96c06d3d89afb 100755
--- a/src/vitis/vas/rest/ws/vitis/VitisSection.class.inc
+++ b/src/vitis/vas/rest/ws/vitis/VitisSection.class.inc
@@ -30,7 +30,7 @@ class VitisSection extends Vitis {
      */
     function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
         parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
-        $this->aSelectedFields = Array("section_id", "tab_id", "event", "index", "label", "name", "link_table_name", "template", "ressource_id");
+        $this->aSelectedFields = Array("section_id", "tab_id", "event", "index", "label", "name", "link_table_name", "template", "ressource_id", "module_name");
     }
 
     /**
diff --git a/src/vitis/vas/rest/ws/vitis/VitisSections.class.inc b/src/vitis/vas/rest/ws/vitis/VitisSections.class.inc
index fb91cfe1ed733f0a04683f7921e7db9b9cf13dd0..3e7710cee087f81790610a140527bf029d79887e 100755
--- a/src/vitis/vas/rest/ws/vitis/VitisSections.class.inc
+++ b/src/vitis/vas/rest/ws/vitis/VitisSections.class.inc
@@ -45,7 +45,7 @@ class VitisSections extends Vitis {
      */
     function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
         parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
-        $this->aSelectedFields = Array("section_id", "tab_id", "event", "index", "label", "name", "link_table_name", "template", "ressource_id", "tab_name", "mode_id");
+        $this->aSelectedFields = Array("section_id", "tab_id", "event", "index", "label", "name", "link_table_name", "template", "ressource_id", "tab_name", "mode_id", "module_name");
     }
 
     /**
diff --git a/src/vitis/vas/sql/sqlQueries.xml b/src/vitis/vas/sql/sqlQueries.xml
old mode 100755
new mode 100644