docs: function (trace) {
  		var cmds = [],
  			modelElement = this.targetModel.findByPath(trace.previousPath || trace.srcPath),
  			currentModel,
  			instance,
  			du,
  			meta,
  			currentModelElement,
  			targetModelElement;
  
  		if (modelElement) {
  			if (!this.isVirtual(modelElement)) {
  				switch (trace.refName) {
  					case 'groups':
  					case 'hosts':
  					case 'components':
  						switch (trace.traceType.name()) {
  							case 'ADD':
  								if (this.isRelatedToPlatform(modelElement)) {
  									meta = modelElement.typeDefinition.select('deployUnits[]/filters[name=platform,value=js]');
  									if (meta.size() > 0) {
  										du = meta.get(0).eContainer();
  										if (!this.modelObjMapper.getObject(du.path())) {
  											cmds.push(this.createCommand(AddDeployUnit, du));
  										}
  									} else {
  										var err = new Error('no DeployUnit found for \'' + modelElement.name + ': ' + modelElement.typeDefinition.name + '/' + modelElement.typeDefinition.version + '\' that matches the \'js\' platform');
  										err.className = this.toString();
  										throw err;
  									}
  
  									if (!this.modelObjMapper.getObject(modelElement.path())) {
  										cmds.push(this.createCommand(AddInstance, modelElement));
  									}
  								}
  								break;
  
  							case 'REMOVE':
  								currentModel = this.node.getKevoreeCore().getCurrentModel(); // old model
  								var instFromCurrModel = currentModel.findByPath(trace.objPath); // instance from current model
  								var instFromTargModel = this.targetModel.findByPath(trace.objPath); // instance in target model
  								if ((instFromTargModel && !this.isRelatedToPlatform(instFromTargModel)) || !instFromTargModel) {
  									// instance is no longer related to platform or present in new model: stop & remove
  									if (this.modelObjMapper.getObject(instFromCurrModel.path())) {
  										if (instFromCurrModel.started) {
  											cmds.push(this.createCommand(StopInstance, instFromCurrModel));
  										}
  										if (this.modelObjMapper.getObject(trace.objPath)) {
  											cmds.push(this.createCommand(RemoveInstance, instFromCurrModel));
  										}
  									}
  								}
  
  								break;
  						}
  						break;
  
  					case 'deployUnits':
  						// switch (trace.traceType.name()) {
  						//   case 'ADD':
  						//     if (this.targetModel.findByPath(trace.srcPath).eContainer().metaClassName() === 'org.kevoree.Package') {
  						//       console.log('add hash=' + modelElement.hashcode, 'name=' + modelElement.name, 'version=' + modelElement.version);
  						//     }
  						//     // if (this.isRelatedToPlatform(modelElement)) {
  						//     //   cmds.push(this.createCommand(AddDeployUnit, modelElement));
  						//     // }
  						//     break;
  						//
  						//   case 'REMOVE':
  						//     currentModel = this.node.getKevoreeCore().getCurrentModel();
  						//     du = currentModel.findByPath(trace.objPath);
  						//     if (du.eContainer().metaClassName() === 'org.kevore.Package') {
  						//       console.log('remove hash=' + modelElement.hashcode, 'name=' + modelElement.name, 'version=' + modelElement.version);
  						//     }
  						//     // if (du) {
  						//     //   cmds.push(this.createCommand(RemoveDeployUnit, du));
  						//     // }
  						//     break;
  						// }
  						break;
  
  					case 'bindings':
  						switch (trace.traceType.name()) {
  							case 'ADD':
  								if (this.isRelatedToPlatform(modelElement)) {
  									if (!this.isVirtual(modelElement)) {
  										cmds.push(this.createCommand(AddBinding, modelElement));
  										cmds.push(this.createCommand(UpdateInstance, modelElement.hub));
  
  										if (modelElement.hub && this.isRelatedToPlatform(modelElement.hub)) {
  											if (!this.modelObjMapper.getObject(modelElement.hub.path())) {
  												meta = modelElement.hub.typeDefinition.select('deployUnits[]/filters[name=platform,value=js]');
  												if (meta.size() > 0) {
  													du = meta.get(0).eContainer();
  													if (!this.modelObjMapper.getObject(du.path())) {
  														cmds.push(this.createCommand(AddDeployUnit, du));
  													}
  												} else {
  													var e = new Error('no DeployUnit found for \'' + modelElement.hub.name + ': ' + modelElement.hub.typeDefinition.name + '/' + modelElement.hub.typeDefinition.version + '\' that matches the \'js\' platform');
  													e.className = this.toString();
  													throw e;
  												}
  
  												if (modelElement.hub.dictionary) {
  													cmds = cmds.concat(this.createUpdateDictionaryCommands(modelElement.hub.dictionary));
  												}
  
  												var fragDics = modelElement.hub.fragmentDictionary.iterator();
  												while (fragDics.hasNext()) {
  													var fragDic = fragDics.next();
  													if (fragDic.name === this.node.getName()) {
  														cmds = cmds.concat(this.createUpdateDictionaryCommands(fragDic));
  													}
  												}
  
  												cmds.push(this.createCommand(AddInstance, modelElement.hub));
  												if (modelElement.hub.started) {
  													cmds.push(this.createCommand(StartInstance, modelElement.hub));
  												}
  
  												var self = this;
  												modelElement.hub.bindings.array.forEach(function (binding) {
  													cmds.push(self.createCommand(AddBinding, binding));
  												});
  											}
  										}
  									}
  								}
  								break;
  
  							case 'REMOVE':
  								currentModel = this.node.getKevoreeCore().getCurrentModel(); // old model
  								var binding = currentModel.findByPath(trace.objPath); // binding before removal trace
  								if (binding) {
  									var newChan = this.targetModel.findByPath(binding.hub.path());
  									var chanStillUsed = false;
  									if (newChan) {
  										var bindings = newChan.bindings.iterator();
  										while (bindings.hasNext()) {
  											if (this.isRelatedToPlatform(bindings.next())) {
  												// there is still a binding between this chan and this platform => cant remove
  												chanStillUsed = true;
  												break;
  											}
  										}
  									}
  
  									if (!chanStillUsed && this.modelObjMapper.getObject(binding.hub.path())) {
  										if (this.modelObjMapper.getObject(binding.hub.path())) {
  											cmds.push(this.createCommand(RemoveInstance, binding.hub));
  										}
  
  										if (binding.hub.started) {
  											cmds.push(this.createCommand(StopInstance, binding.hub));
  										}
  									}
  								}
  
  								if (this.isRelatedToPlatform(binding)) {
  									cmds.push(this.createCommand(RemoveBinding, binding));
  									cmds.push(this.createCommand(UpdateInstance, binding.hub));
  								}
  								break;
  						}
  						break;
  
  					case 'started':
  						if (trace.traceType.name() === 'SET' && isInstance(modelElement)) {
  							if (this.isRelatedToPlatform(modelElement)) {
  								if (modelElement.metaClassName() === 'org.kevoree.ContainerNode' && modelElement.name === this.node.getName()) {
  									if (trace.content === 'true') {
  										// start this node platform
  										cmds.push(this.createCommand(StartInstance, modelElement));
  									} else {
  										// stop this node platform
  										cmds.push(this.createCommand(HaraKiri, modelElement));
  									}
  								} else {
  									if (trace.content === 'true') {
  										cmds.push(this.createCommand(StartInstance, modelElement));
  										if (!modelElement.host) {
  											if (modelElement.dictionary) {
  												var updateDicCmds = this.createUpdateDictionaryCommands(modelElement.dictionary);
  												if (updateDicCmds.length > 0) {
  													cmds = cmds.concat(updateDicCmds);
  													cmds.push(this.createCommand(UpdateInstance, modelElement));
  												}
  											}
  
  											var elemFragDics = modelElement.fragmentDictionary.iterator();
  											while (elemFragDics.hasNext()) {
  												var fDic = elemFragDics.next();
  												if (fDic.name === this.node.getName()) {
  													var updateFDicCmds = this.createUpdateDictionaryCommands(fDic);
  													if (updateFDicCmds.length > 0) {
  														cmds = cmds.concat(updateFDicCmds);
  														cmds.push(this.createCommand(UpdateInstance, modelElement));
  													}
  												}
  											}
  										}
  									} else {
  										if (modelElement.host && modelElement.host.name === this.node.getName()) {
  											// modelElement is an hosted node (so it does not have an instance in this platform)
  											cmds.push(this.createCommand(StopInstance, modelElement));
  
  										} else {
  											instance = this.modelObjMapper.getObject(modelElement.path());
  											if (instance && instance.isStarted()) {
  												cmds.push(this.createCommand(StopInstance, modelElement));
  											}
  										}
  									}
  								}
  							}
  						}
  						break;
  
  					case 'value':
  						if (trace.traceType.name() === 'SET' &&
  							modelElement.metaClassName() === 'org.kevoree.Value' &&
  							modelElement.eContainer().metaClassName() === 'org.kevoree.Dictionary') {
  							if (this.isRelatedToPlatform(modelElement)) {
  								instance = modelElement.eContainer().eContainer();
  								if (instance.started && !instance.host) {
  									var updateDicAttrs = this.createUpdateDictionaryCommands(modelElement.eContainer());
  									if (updateDicAttrs.length > 0) {
  										cmds = cmds.concat(updateDicAttrs);
  										cmds.push(this.createCommand(UpdateInstance, modelElement.eContainer().eContainer()));
  									}
  								}
  							}
  						}
  						break;
  
  					case 'typeDefinition':
  						switch (trace.traceType.name()) {
  							case 'ADD':
  								currentModel = this.node.getKevoreeCore().getCurrentModel();
  								currentModelElement = currentModel.findByPath(trace.srcPath);
  								if (currentModelElement) {
  									targetModelElement = this.targetModel.findByPath(trace.srcPath);
  									if (this.isRelatedToPlatform(currentModelElement)) {
  										if (currentModelElement.path() === this.node.getPath()) {
  											// this adaptation means: to change this node platform TypeDefinition
  											// TODO this should be checked and handled in the core.. not here
  										} else {
  											meta = modelElement.select('deployUnits[]/filters[name=platform,value=js]');
  											if (meta.size() > 0) {
  												du = meta.get(0).eContainer();
  												if (!this.modelObjMapper.getObject(du.path())) {
  													cmds.push(this.createCommand(AddDeployUnit, du));
  												}
  
  												instance = this.modelObjMapper.getObject(currentModelElement.path());
  												if (instance) {
  													// instance found in the node map
  													if (instance.started) {
  														// stop instance
  														cmds.push(this.createCommand(StopInstance, currentModelElement));
  													}
  
  													if (currentModelElement.metaClassName() === 'org.kevoree.Channel') {
  														// remove old bindings
  														currentModelElement.bindings.array.forEach(function (b) {
  															cmds.push(this.createCommand(RemoveBinding, b));
  														}.bind(this));
  														// add new bindings
  														targetModelElement.bindings.array.forEach(function (b) {
  															cmds.push(this.createCommand(AddBinding, b));
  														}.bind(this));
  
  													} else if (currentModelElement.metaClassName() === 'org.kevoree.ComponentInstance') {
  														// remove old input port bindings
  														currentModelElement.provided.array.forEach(function (input) {
  															input.bindings.array.forEach(function (b) {
  																cmds.push(this.createCommand(RemoveBinding, b));
  															}.bind(this));
  														}.bind(this));
  														// remove old outout port bindings
  														currentModelElement.required.array.forEach(function (output) {
  															output.bindings.array.forEach(function (b) {
  																cmds.push(this.createCommand(RemoveBinding, b));
  															}.bind(this));
  														}.bind(this));
  
  														// add new input port bindings
  														targetModelElement.provided.array.forEach(function (input) {
  															input.bindings.array.forEach(function (b) {
  																cmds.push(this.createCommand(AddBinding, b));
  															}.bind(this));
  														}.bind(this));
  														// add new outout port bindings
  														targetModelElement.required.array.forEach(function (output) {
  															output.bindings.array.forEach(function (b) {
  																cmds.push(this.createCommand(AddBinding, b));
  															}.bind(this));
  														}.bind(this));
  													}
  
  													// TODO upgradeInstance ?
  
  													//reinject dictionary
  													this.createUpdateDictionaryCommands(targetModelElement.dictionary);
  
  													//restart
  													cmds.push(this.createCommand(StartInstance, targetModelElement));
  												} else {
  													// TODO hmm => what to do then ?
  												}
  											} else {
  												var error = new Error('no DeployUnit found for \'' + modelElement.name + ': ' + modelElement.typeDefinition.name + '/' + modelElement.typeDefinition.version + '\' that matches the \'js\' platform');
  												error.className = this.toString();
  												throw error;
  											}
  										}
  									}
  								}
  								break;
  
  							case 'REMOVE':
  								//console.log('>>>>> REMOVE TypeDef', modelElement.path());
  								break;
  						}
  
  						break;
  				}
  			}
  		}
  
  		return cmds;
  	}