static StringCounter getInstance(QvtOperationalEvaluationEnv env) {
      env.getThisOfType(QvtOperationalStdLibrary.INSTANCE.getStdLibModule());
      // FIXME - this way we have String counters in global only, should be done
      // per Stdlib instance (every aggregated transformation)
      StringCounter counters = (StringCounter) env.getContext().getSessionData().getValue(DATA_KEY);
      if (counters == null) {
        counters = new StringCounter();
        env.getContext().getSessionData().setValue(DATA_KEY, counters);
      }

      return counters;
    }
  public void run() {
    QvtOperationalEvaluationEnv oldEvalEnv = myVisitor.getOperationalEvaluationEnv();
    myVisitor.setOperationalEvaluationEnv(myEvalEnv);
    Object resolveResult = getResolveResult();

    try {
      AssignExp assignExp = QvtResolveUtil.getDeferredAssignmentFor(myResolveExp);
      if (assignExp != null && myLvalue != null) {
        myEvalEnv.callSetter(
            myLvalue.getEObject(),
            myLvalue.getEStructuralFeature(),
            resolveResult,
            QvtOperationalUtil.isUndefined(resolveResult, myEvalEnv),
            assignExp.isIsReset());

        if (myListener != null) {
          myListener.notifyAfterDeferredAssign(assignExp, resolveResult);
        }
      } else {
        // there was not appropriate assignment to receive the value
      }
    } finally {
      myVisitor.setOperationalEvaluationEnv(oldEvalEnv);
    }
  }
  private static Object callOperation(
      QvtOperationalEvaluationEnv evalEnv,
      LibraryOperation libOp,
      Object source,
      Object[] args,
      Class<?> returnClass) {

    if (source == null || source == CallHandlerAdapter.getInvalidResult(evalEnv)) {
      return CallHandlerAdapter.getInvalidResult(evalEnv);
    }

    // reset OclInvalid to 'null'
    Object[] callArgs = null;
    if (args != null) {
      for (int i = 0; i < args.length; i++) {
        if (evalEnv.isOclInvalid(args[i])) {
          if (callArgs == null) {
            callArgs = new Object[args.length];
            System.arraycopy(args, 0, callArgs, 0, args.length);
          }
          callArgs[i] = null;
        }
      }
      callArgs = (callArgs == null) ? args : callArgs;
    }

    Object result = libOp.run(source, callArgs, new Object[0], returnClass);
    if (result == null) {
      return QvtOperationalUtil.getInvalid(evalEnv);
    }
    return result;
  }
  public AbstractLateResolveTask(
      ResolveExp resolveExp,
      EObjectEStructuralFeaturePair lvalue,
      QvtOperationalEvaluationVisitor visitor,
      QvtOperationalEvaluationEnv evalEnv,
      DeferredAssignmentListener deferredListener) {
    myResolveExp = resolveExp;
    myLvalue = lvalue;
    myVisitor = visitor;
    myEvalEnv = evalEnv.createDeferredExecutionEnvironment();
    if (myResolveExp.getSource() != null) {
      mySourceObj = myResolveExp.getSource().accept(visitor);
    }

    myListener = deferredListener;
  }