protected void addMissingVariables(IEntity contextModel, MissingVariableException e) {
    String[] varNames = e.getVariableNames();
    EnvironmentEntityFactory ef = EnvironmentEntityFactory.instance;

    for (String varName : varNames) {
      Name var = ef.createName(varName);
      IEntity find = Matcher.find(var, contextModel, false);
      if (find == null)
        contextModel.wAdd(
            ef.createBinding(
                var,
                CommonsEntityAdapterFactory.createResolver(EnvironmentEntityDescriptorEnum.Value)));
    }
  }
  public static IEntity cloneArtifact(IEntity artifact, IEntity appendChild) {
    IEntityFactory ef = GenericEntityFactory.instance(RegistryConfigurations.RESOLVER);
    EntityDescriptor<?> ed = artifact.wGetEntityDescriptor();

    IEntity newArtifact = ef.create(ed);
    for (FeatureDescriptor fd : ed.getEntityFeatureDescriptors()) {
      if (artifacts.equals(fd) || projects.equals(fd)) {
        IEntity composite = newArtifact.wGet(fd);
        if (appendChild != null) composite.wAdd(appendChild);
        else composite.wResolveWith(fd.getEntityDescriptor());
      } else newArtifact.wSet(fd, EntityUtils.clone(artifact.wGet(fd)));
    }
    return newArtifact;
  }
  @Override
  public void run(IOperationProgressMonitor pm)
      throws InvocationTargetException, InterruptedException {
    IEntity selfEntity =
        EntityUtils.mapEntity(selfModel, EntityUtils.clone(EntityUtils.getCompoundRoot(selfModel)));

    Set<String> initialNames = bm.wNames();

    pm.beginTask("Executing sample...", IOperationProgressMonitor.TOTAL_WORK);

    behaviorModel =
        BehaviorUtils.apply(
            "whole:org.whole.lang.ui.views:SamplePerspectiveSemantics#SampleViewBehavior",
            behaviorModel,
            bm);

    IEntity derivedModel = null;
    try {
      IEntityIterator<?> iterator = BehaviorUtils.lazyEvaluate(behaviorModel, 0, bm);
      iterator.setBindings(selfBindings);
      iterator.reset(selfEntity);

      if (iterator.getClass().equals(ConstantIterator.class)) {
        IEntity result = iterator.next();
        if (result == null || !EntityUtils.isData(result)) derivedModel = result;
        else {
          Object resultValue = result.wGetValue();
          derivedModel =
              IVisitor.class.isInstance(resultValue)
                  ? BindingManagerFactory.instance.createValue(
                      Matcher.match((IVisitor) resultValue, selfEntity))
                  : result;
        }
      } else if (iterator.hasNext()) {
        derivedModel = MiscEntityFactory.instance.createMisc(0);

        ITransactionScope transactionScope =
            BindingManagerFactory.instance.createTransactionScope();
        bm.wEnterScope(transactionScope);
        try {
          for (IEntity result : iterator) {
            transactionScope.commit();
            derivedModel.wAdd(
                GenericEntityFactory.instance.create(
                    CommonsEntityDescriptorEnum.SameStageFragment,
                    // CommonsEntityFactory.instance.createSameStageFragment(
                    EntityUtils.clone(result))); // TODO substitute with a no containment fragment
          }
        } finally {
          transactionScope.rollback();
          bm.wExitScope();
        }
      }
    } catch (MissingVariableException e) {
      addMissingVariables(contextModel, e);
    } catch (OperationCanceledException e) {
      // gracefully terminate execution
    } catch (Exception e) {
      if (e.getCause() instanceof MissingVariableException)
        addMissingVariables(contextModel, (MissingVariableException) e.getCause());
    } finally {
      pm.endTask();
    }

    IEntity variablesModel = null;
    if (derivedModel != null) {
      EnvironmentEntityFactory ef = EnvironmentEntityFactory.instance;
      variablesModel = ef.createBindings(0);
      for (String name : new TreeSet<String>(bm.wLocalNames()))
        if (!initialNames.contains(name))
          variablesModel.wAdd(
              ef.createBinding(ef.createName(name), ef.createValue(BindingUtils.wGet(bm, name))));

      final IEntity contents = derivedModel;
      final IEntity variables = variablesModel;
      context
          .get(UISynchronize.class)
          .asyncExec(
              new Runnable() {
                public void run() {
                  context.get(IEntityPartViewer.class).setContents(null, contents);
                  context
                      .get(IEventBroker.class)
                      .post(IUIConstants.TOPIC_UPDATE_VARIABLES, variables);
                }
              });
    }
  }