/**
   * Persists components. Stores EventBComponents as an extension in a machine.
   *
   * @param document
   */
  private void doSaveComponents(IDocument document) {
    ComponentDiagram diagram =
        (ComponentDiagram) ((IDiagramDocument) document).getDiagram().getElement();
    final TransactionalEditingDomain domain = ((IDiagramDocument) document).getEditingDomain();
    CompoundCommand compoundCmd = new CompoundCommand();

    for (final Component comp : diagram.getComponents()) {
      if (comp instanceof EventBComponent && ((EventBComponent) comp).getMachine() != null) {

        // adds command to extend Event-B machine with component config
        // NOTE: replaces existing extension of the same id
        compoundCmd.append(
            new RecordingCommand(domain) {
              @Override
              protected void doExecute() {
                EventBComponent compCopy = (EventBComponent) EcoreUtil.copy(comp);
                try {
                  Resource resource =
                      domain.getResourceSet().getResource(compCopy.getMachine().getURI(), true);

                  if (resource != null && resource.isLoaded()) {
                    Machine machine = (Machine) resource.getContents().get(0);

                    // remove any existing extensions of the same id (EventB component)
                    Iterator<AbstractExtension> it = machine.getExtensions().iterator();
                    while (it.hasNext()) {
                      if (ComponentsPackage.EVENTB_COMPONENT_EXTENSION_ID.equals(
                          it.next().getExtensionId())) {
                        it.remove();
                      }
                    }
                    //								compCopy.setReference(ComponentsPackage.EVENTB_COMPONENT_EXTENSION_ID
                    //										+ "." + EcoreUtil.generateUUID());
                    machine.getExtensions().add(compCopy);
                    resource.save(Collections.EMPTY_MAP);
                  }
                } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                }
              }
            });
      }
    }
    domain.getCommandStack().execute(compoundCmd);
  }
  /**
   * Loads FMU for FMU components from their path attribute. If loading fails adds an error marker
   * (planned to be implemented).
   *
   * @param domain
   * @param diagram
   */
  private void loadFmuPath(TransactionalEditingDomain domain, Diagram diagram) {
    ComponentDiagram cd = (ComponentDiagram) diagram.getElement();
    for (Component comp : cd.getComponents()) {
      if (comp instanceof FMUComponent) {
        final FMUComponent fmuComponent = (FMUComponent) comp;
        final String path = fmuComponent.getPath();

        if (path == null) {
          // TODO: show validation error marker
          return;
        }

        if (path != null) {
          RecordingCommand cmd =
              new RecordingCommand(domain) {
                @Override
                protected void doExecute() {
                  try {
                    FMU fmu = new FMU(path);
                    fmuComponent.setFmu(fmu);
                    FMIModelDescription md = fmu.getModelDescription();

                    // map variables by name
                    Map<String, FMIScalarVariable> varMap =
                        new HashMap<String, FMIScalarVariable>(md.modelVariables.size());
                    for (FMIScalarVariable var : md.modelVariables) {
                      varMap.put(var.name, var);
                    }

                    // set initial values
                    for (AbstractVariable var : fmuComponent.getVariables()) {
                      FMIScalarVariable scalar = varMap.get(var.getName());
                      assert (scalar != null);
                      FmiUtil.getVariableType(scalar, var);
                    }
                  } catch (IOException e) {
                    // TODO add validation marker
                    e.printStackTrace();
                  }
                }
              };
          domain.getCommandStack().execute(cmd);
        }
      }
    }
  }