public bool postRollback(UpdateContext updateContext)
        {
            scheduler.Add(() => { foreach (var l in registeredListeners) { l.postRollback(updateContext); } });

            // TODO : is this really necessary ?
            return true;
        }
        public bool afterUpdate(UpdateContext updateContext)
        {
            scheduler.Add(() => { foreach (var l in registeredListeners) { l.afterLocalUpdate(updateContext); } });

            // TODO : is this really necessary ?
            return true;
        }
        private bool internalUpdateModel(IContainerRootMarshalled proposedNewModel, string callerPath)
        {
            if (proposedNewModel.findNodesByID(this.nodeName) == null)
            {
                return false;
            }
            try
            {
                var readOnlyNewModel = CloneContainerRoot(proposedNewModel);
                if (readOnlyNewModel.isReadOnly())
                {
                    readOnlyNewModel = (ContainerRoot)kevoreeFactory.createModelCloner().clone(readOnlyNewModel, false);
                    readOnlyNewModel.setGenerated_KMF_ID(nodeName + "@" + callerPath + "#" + java.lang.System.nanoTime());
                    readOnlyNewModel = (ContainerRoot)kevoreeFactory.createModelCloner().clone(readOnlyNewModel, true);
                }
                else
                {
                    readOnlyNewModel.setGenerated_KMF_ID(nodeName + "@" + callerPath + "#" + java.lang.System.nanoTime());
                }
                pending = proposedNewModel;
                // Model check is OK.
                ContainerRoot currentModel;
                if (this.model != null)
                {

                    var serialized = this.model.getModel().serialize();
                    var kf = new org.kevoree.factory.DefaultKevoreeFactory();
                    currentModel = (ContainerRoot)kf.createJSONLoader().loadModelFromString(serialized).get(0);
                }
                else
                {
                    currentModel = null;
                }
                UpdateContext updateContext = new UpdateContext(new ContainerRootMarshalled(currentModel), new ContainerRootMarshalled(readOnlyNewModel), callerPath);
                bool preCheckResult = modelListeners.preUpdate(updateContext);
                bool initUpdateResult = modelListeners.initUpdate(updateContext);
                if (preCheckResult && initUpdateResult)
                {
                    IContainerRootMarshalled newmodel = new ContainerRootMarshalled(readOnlyNewModel);
                    // CHECK FOR HARA KIRI
                    IContainerRootMarshalled previousHaraKiriModel = null;
                    // Checks and bootstrap the node
                    checkBootstrapNode(newmodel);
                    if (this.model != null)
                    {
                        var serialized = this.model.getModel().serialize();
                        var kf = new org.kevoree.factory.DefaultKevoreeFactory();
                        currentModel = (ContainerRoot)kf.createJSONLoader().loadModelFromString(serialized).get(0);
                    }
                    else
                    {
                        currentModel = null;
                    }
                    long milli = java.lang.System.currentTimeMillis();

                    bool deployResult;
                    try
                    {
                        if (nodeInstance != null)
                        {
                            // Compare the two models and plan the adaptation
                            // Log.info("Comparing models and planning
                            // adaptation.")

                            var dkf = new DefaultKevoreeFactory();
                            var modelCompare = dkf.createModelCompare();

                            // TODO : clean up -> cloned
                            var newmodel2 = CloneContainerRoot(newmodel);

                            var traces = modelCompare.diff(currentModel, newmodel2);
                            AdaptationModel adaptationModel = nodeInstance.plan(new ContainerRootMarshalled(currentModel), newmodel, new TracesMarshalled(traces));
                            // Execution of the adaptation
                            updateContext = new UpdateContext(new ContainerRootMarshalled(currentModel), new ContainerRootMarshalled(newmodel2), callerPath);

                            UpdateContext final_updateContext = updateContext;
                            Func<bool> afterUpdateTest = () => { return modelListeners.afterUpdate(final_updateContext); };
                            Func<bool> postRollbackTest = () =>
                            {
                                modelListeners.postRollback(final_updateContext);
                                return true;
                            };

                            Func<bool> preCmdPreRollbackTest = getPreCmdPreRollbackTest(updateContext, modelListeners);

                            IContainerNodeMarshalled rootNode = newmodel.findNodesByID(getNodeName());
                            deployResult = PrimitiveCommandExecutionHelper.execute(this, rootNode,
                                    adaptationModel, nodeInstance, afterUpdateTest, preCmdPreRollbackTest,
                                    postRollbackTest);

                            if (deployResult)
                            {
                                this.model = new UUIDModelImpl(Guid.NewGuid(), newmodel);
                            }
                        }
                        else
                        {
                            deployResult = false;
                        }
                    }
                    catch (Exception e)
                    {
                        loggerMaster.Error(e.StackTrace);
                        deployResult = false;
                    }
                    if (deployResult)
                    {
                        switchToNewModel(newmodel);
                    }
                    else
                    {
                        // KEEP FAIL MODEL, TODO
                        // IF HARAKIRI
                        if (previousHaraKiriModel != null)
                        {
                            internalUpdateModel(previousHaraKiriModel, callerPath);
                            previousHaraKiriModel = null; // CLEAR
                        }
                    }
                    long milliEnd = java.lang.System.currentTimeMillis() - milli;
                    //pending = null;
                    return deployResult;

                }
                else
                {
                    return false;
                }

            }
            catch (java.lang.Throwable)
            {
                return false;
            }
        }
 private Func<bool> getPreCmdPreRollbackTest(UpdateContext updateContext, KevoreeListeners modelListeners)
 {
     var alreadyCalled = false;
     return () =>
     {
         if (!alreadyCalled)
         {
             modelListeners.preRollback(updateContext);
             alreadyCalled = true;
         }
         return true;
     };
 }