private void deployNode(
      InstanceSpecification mainInstance,
      Model existingModel,
      Model tmpModel,
      InstanceSpecification newRootIS,
      EList<InstanceSpecification> nodes,
      int nodeIndex,
      InstanceSpecification node)
      throws TransformationException, InterruptedException {
    ModelManagement genModelManagement =
        createTargetModel(existingModel, MapUtil.rootModelName, false);
    Model generatedModel = genModelManagement.getModel();

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    // new model has name "root" and contains a package with the
    // existing model
    // Package originalRoot = genModel.createNestedPackage
    // (existingModel.getName ());
    LazyCopier targetCopy = new LazyCopier(tmpModel, generatedModel, true, true);
    // TODO: distribution to nodes is currently not done. How
    // can it be realized with a copy filter ?
    targetCopy.preCopyListeners.add(FilterStateMachines.getInstance());
    targetCopy.preCopyListeners.add(FilterRuleApplication.getInstance());

    monitor.setTaskName(
        String.format(Messages.InstantiateDepPlan_InfoDeployingForNode, node.getName()));

    ILangSupport langSupport = configureLanguageSupport(mainInstance, existingModel, node);
    if (langSupport == null) {
      return;
    }

    Deploy deployment = new Deploy(targetCopy, langSupport, node, nodeIndex, nodes.size());
    InstanceSpecification nodeRootIS = deployment.distributeToNode(newRootIS);
    TransformationUtil.updateDerivedInterfaces(nodeRootIS);

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    removeDerivedInterfacesInRoot(generatedModel);

    CompImplTrafos.transform(
        deployment.getBootloader(), targetCopy, generatedModel, modelIsObjectOriented);

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    destroyDeploymentPlanFolder(generatedModel);

    if (generateCode) {
      GenerateCode codeGenerator =
          new GenerateCode(langSupport.getProject(), langSupport, genModelManagement, monitor);
      boolean option = (generationOptions & GenerationOptions.ONLY_CHANGED) != 0;
      codeGenerator.generate(node, getTargetLanguage(mainInstance), option);
    }

    genModelManagement.dispose();
  }
  /**
   * Create a new empty model from an existing model that applies the same profiles and has the same
   * imports
   *
   * @param existingModel
   * @return
   */
  public ModelManagement createTargetModel(Model existingModel, String name, boolean copyImports)
      throws TransformationException {
    ModelManagement mm = new ModelManagement();
    Model newModel = mm.getModel();
    newModel.setName(name);

    try {
      // copy profile application
      for (Profile profile : existingModel.getAppliedProfiles()) {
        // reload profile in resource of new model
        monitor.subTask(Messages.InstantiateDepPlan_InfoApplyProfile + profile.getQualifiedName());

        if (profile.eResource() == null) {
          String profileName = profile.getQualifiedName();
          if (profileName == null) {
            if (profile instanceof MinimalEObjectImpl.Container) {
              URI uri = ((MinimalEObjectImpl.Container) profile).eProxyURI();
              if (uri != null) {
                throw new TransformationException(
                    String.format(Messages.InstantiateDepPlan_CheckInputModelProfileNoRes, uri));
              }
            }
            throw new TransformationException(
                Messages.InstantiateDepPlan_CheckInputModelProfileNoResNoName);
          }
          throw new TransformationException(
              String.format(Messages.InstantiateDepPlan_CheckInputModelProfile3, profileName));
        }

        Resource profileResource = null;
        try {
          profileResource =
              ModelManagement.getResourceSet().getResource(profile.eResource().getURI(), true);
        } catch (WrappedException e) {
          // read 2nd time (some diagnostic errors are raised only
          // once)
          Log.log(
              IStatus.WARNING,
              Log.DEPLOYMENT,
              "Warning: exception in profile.eResource() " + e.getMessage()); // $NON-NLS-1$
          profileResource =
              ModelManagement.getResourceSet().getResource(profile.eResource().getURI(), true);
        }
        Profile newProfileTop = (Profile) profileResource.getContents().get(0);
        Profile newProfile;
        String qname = profile.getQualifiedName();
        if ((qname != null) && qname.contains("::")) { // $NON-NLS-1$
          // profile is a sub-profile within same resource
          // TODO: should Copy class copy profile applications?
          // Should be handled in shallowContainer class.
          // if we put profile/newProfile pair into copy map, copy
          // would find (and copy profile
          // applications in sub-folders
          qname = qname.substring(qname.indexOf("::") + 2); // $NON-NLS-1$
          newProfile = (Profile) Utils.getQualifiedElement(newProfileTop, qname);
        } else {
          newProfile = newProfileTop;
        }
        newProfile.getMember("dummy"); // force profile loading //$NON-NLS-1$
        newModel.applyProfile(newProfile);
      }
    } catch (IllegalArgumentException e) {
      throw new TransformationException(
          Messages.InstantiateDepPlan_IllegalArgumentDuringCopy + e.toString());
    }

    // copy imports (and load resources associated - TODO: might not be
    // necessary)
    // While this is useful in general, it implies that code for imported
    // models
    // has been generated and compiled (for the right target) into a
    // library. This may be
    // quite tedious, unless automatically managed.
    // Therefore we do not activate this option in a first pass of the model
    // transformations.
    if (copyImports) {
      for (Package importedPackage : existingModel.getImportedPackages()) {
        if (importedPackage == null) {
          throw new TransformationException(Messages.InstantiateDepPlan_CheckInputImportPkg);
        }
        if (importedPackage.eResource() == null) {
          String errorMsg = Messages.InstantiateDepPlan_CheckInputImportPkgNoRes;
          if (importedPackage instanceof MinimalEObjectImpl.Container) {
            URI uri = ((MinimalEObjectImpl.Container) importedPackage).eProxyURI();
            if (uri != null) {
              errorMsg += " - URI: " + uri.devicePath(); // $NON-NLS-1$
            }
          }
          throw new TransformationException(errorMsg);
        }
        newModel.createPackageImport(importedPackage);
        monitor.subTask(
            String.format(
                Messages.InstantiateDepPlan_InfoImportPackage, importedPackage.getName()));

        try {
          importedPackage.eResource().load(null);
          newModel.getMember("dummy"); // force loading of model //$NON-NLS-1$
        } catch (IOException e) {
          throw new TransformationException(e.getMessage());
        }
      }
    }

    StUtils.copyStereotypes(existingModel, newModel);

    return mm;
  }
  protected void executeTransformation() throws Exception {
    modelIsObjectOriented = true;
    ModelManagement intermediateModelManagement = null;

    InstanceSpecification mainInstance = DepUtils.getMainInstance(srcModelComponentDeploymentPlan);
    EList<InstanceSpecification> nodes = AllocUtils.getAllNodes(mainInstance);

    initiateProgressMonitor(generateCode, nodes);

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    // 1a: create a new model (and applies same profiles / imports)
    Model existingModel = srcModelComponentDeploymentPlan.getModel();
    TransformationContext.sourceRoot = existingModel;

    intermediateModelManagement = createTargetModel(existingModel, existingModel.getName(), true);

    // Declare that the new model is a derivedElement (kind of hack,
    // since the source element (attribute of derive element) remains
    // undefined). This is used to deactivate automatic transformations
    // that should not be applied to the generated model.

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    // get the temporary model
    Model intermediateModel = intermediateModelManagement.getModel();

    // create a package for global enumerations that are used by Acceleo code
    EnumService.createEnumPackage(intermediateModel);

    // create a lazy copier towards the intermediate model
    LazyCopier intermediateModelCopier =
        new LazyCopier(existingModel, intermediateModel, false, true);
    // add pre-copy and post-copy listeners to the copier
    intermediateModelCopier.preCopyListeners.add(FilterTemplate.getInstance());

    // 1b: reify the connectors "into" the new model
    monitor.subTask(Messages.InstantiateDepPlan_InfoExpandingConnectors);

    // obtain the component deployment plan in target model
    Package intermediateModelComponentDeploymentPlan =
        (Package) intermediateModelCopier.shallowCopy(srcModelComponentDeploymentPlan);
    intermediateModelCopier.createShallowContainer(srcModelComponentDeploymentPlan);

    AbstractContainerTrafo.init();
    InstanceConfigurator.onNodeModel = false;
    MainModelTrafo mainModelTrafo =
        new MainModelTrafo(intermediateModelCopier, intermediateModelComponentDeploymentPlan);
    InstanceSpecification newMainInstance = mainModelTrafo.transformInstance(mainInstance, null);

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    TransformationUtil.applyInstanceConfigurators(newMainInstance);

    FlattenInteractionComponents.getInstance().flattenAssembly(newMainInstance, null);

    TransformationUtil.propagateAllocation(newMainInstance);

    intermediateModelManagement.saveModel(project, TEMP_MODEL_FOLDER, TEMP_MODEL_POSTFIX);

    // --------------------------------------------------------------------
    checkProgressStatus();
    // --------------------------------------------------------------------

    if (!generateCACOnly) {
      deployOnNodes(mainInstance, existingModel, intermediateModel, newMainInstance);
    }

    intermediateModelManagement.dispose();

    if (AcceleoDriver.hasErrors()) {
      throw new AcceleoException();
    }
  }