@Override
 public @Nullable Object evaluate(
     @NonNull Executor executor, @NonNull TypeId returnTypeId, @Nullable Object sourceValue) {
   IdResolver idResolver = executor.getIdResolver();
   Property oppositeProperty = idResolver.getProperty(oppositePropertyId);
   ModelManager.ModelManagerExtension modelManager =
       (ModelManager.ModelManagerExtension) executor.getModelManager();
   Type thatType = ClassUtil.nonNullModel(oppositeProperty.getType());
   if (thatType instanceof CollectionType) {
     thatType = ((CollectionType) thatType).getElementType();
   }
   List<Object> results = new ArrayList<Object>();
   if (thatType instanceof org.eclipse.ocl.pivot.Class) {
     for (@NonNull
     Object eObject :
         modelManager.get((org.eclipse.ocl.pivot.Class) thatType)) { // FIXME Use a cache
       EClass eClass = modelManager.eClass(eObject);
       EStructuralFeature eFeature = eClass.getEStructuralFeature(oppositeProperty.getName());
       assert eFeature != null;
       Object eGet = modelManager.eGet(eObject, eFeature);
       if (eGet == sourceValue) {
         results.add(eObject);
       }
     }
   }
   return results;
 }
 /** Tests the basic name accesses */
 @Test
 public void test_container_navigation() throws InvocationTargetException {
   TestOCL ocl = createOCL();
   initFruitPackage(ocl);
   MetamodelManagerInternal metamodelManager = ocl.getMetamodelManager();
   IdResolver idResolver = ocl.getIdResolver();
   metamodelManager.addGlobalNamespace("fruit", fruitPackage);
   //
   //	Simple model: aTree contains redApple
   //
   EObject redApple = fruitEFactory.create(apple);
   redApple.eSet(fruit_color, color_red);
   //		EObject greenApple = fruitEFactory.create(apple);
   //		greenApple.eSet(fruit_color, color_green);
   EObject aTree = fruitEFactory.create(tree);
   @SuppressWarnings("unchecked")
   List<Object> treeFruits = (List<Object>) aTree.eGet(tree_fruits);
   treeFruits.add(redApple);
   //
   Type pivotTree = metamodelManager.getASOfEcore(Type.class, tree);
   //
   ocl.assertQueryEquals(redApple, color_red, "let aFruit : fruit::Fruit = self in aFruit.color");
   ocl.assertQueryEquals(
       aTree,
       idResolver.createOrderedSetOfEach(null, redApple),
       "let aTree : fruit::Tree = self in aTree.fruits");
   ocl.assertQueryEquals(aTree, idResolver.createOrderedSetOfEach(null, redApple), "self.fruits");
   ocl.assertQueryEquals(aTree, idResolver.createOrderedSetOfEach(null, redApple), "fruits");
   ocl.assertQueryEquals(redApple, aTree, "self.oclContainer()");
   ocl.assertQueryEquals(redApple, aTree, "self.Tree");
   //
   //	type/property ambiguity is resolved to type.
   //
   ocl.assertQueryEquals(redApple, pivotTree, "Tree");
   //
   //	type/property ambiguity is resolved to type.
   //
   ocl.assertQueryInvalid(redApple, "self.oclAsType(Tree)");
   //		ocl.assertQueryEquals(aTree, ValuesUtil.createOrderedSetValue(null, redApple),
   // "self.oclAsType(Tree).fruits");
   ocl.dispose();
 }
 /** Tests the nested name accesses */
 @Test
 public void test_nested_names() throws InvocationTargetException {
   TestOCL ocl = createOCL();
   initFruitPackage(ocl);
   MetamodelManagerInternal metamodelManager = ocl.getMetamodelManager();
   IdResolver idResolver = ocl.getIdResolver();
   org.eclipse.ocl.pivot.Class appleType =
       metamodelManager.getASOfEcore(org.eclipse.ocl.pivot.Class.class, apple);
   //
   //	Simple model: appleTree contains redApple
   //
   EObject redApple = fruitEFactory.create(apple);
   redApple.eSet(fruit_color, color_red);
   redApple.eSet(fruit_name, "RedApple");
   EObject appleTree = fruitEFactory.create(tree);
   appleTree.eSet(tree_name, "AppleTree");
   @SuppressWarnings("unchecked")
   List<Object> treeFruits = (List<Object>) appleTree.eGet(tree_fruits);
   treeFruits.add(redApple);
   //
   ocl.assertQueryEquals(redApple, "RedApple", "self.name");
   ocl.assertQueryEquals(redApple, "RedApple", "self.Fruit::name");
   ocl.assertQueryEquals(redApple, "RedApple", "self.Apple::name");
   ocl.assertValidationErrorQuery(
       appleType,
       "self.Tree::name",
       PivotMessages.ValidationConstraintIsNotSatisfied_ERROR_,
       PivotTables.STR_PropertyCallExp_c_c_NonStaticSourceTypeIsConformant,
       "self.name");
   ocl.assertQueryEquals(redApple, redApple, "self.oclAsType(Apple)");
   ocl.assertQueryEquals(redApple, redApple, "self.oclAsType(fruit::Apple)");
   ocl.assertQueryEquals(
       redApple, idResolver.createSetOfEach(null, redApple), "self->oclAsType(Set(Fruit))");
   ocl.assertQueryEquals(
       redApple, idResolver.createSetOfEach(null, redApple), "self->oclAsType(Set(fruit::Apple))");
   ocl.assertSemanticErrorQuery(
       appleType,
       "self.oclAsType(fruit::fruit::Apple)",
       PivotMessagesInternal.UnresolvedNamespace_ERROR_,
       "",
       "fruit"); // Demonstrates Bug 353985
   ocl.assertSemanticErrorQuery(
       appleType,
       "self->oclAsType(Set(fruit::apple::BadApple))",
       PivotMessagesInternal.UnresolvedType_ERROR_,
       "",
       "BadApple");
   ocl.assertSemanticErrorQuery(
       appleType,
       "self->oclAsType(Set(fruit::apple::BadApple))",
       PivotMessagesInternal.UnresolvedType_ERROR_,
       "",
       "BadApple");
   ocl.assertSemanticErrorQuery(
       appleType,
       "self->oclAsType(Set(fruit::badapple::BadApple))",
       PivotMessagesInternal.UnresolvedNamespace_ERROR_,
       "",
       "badapple");
   ocl.assertSemanticErrorQuery(
       appleType,
       "self->oclAsType(Set(badfruit::badapple::BadApple))",
       PivotMessagesInternal.UnresolvedNamespace_ERROR_,
       "",
       "badfruit");
   ocl.assertQueryInvalid(redApple, "self->oclAsType(Set(fruit::apple::EatingApple))");
   ocl.assertQueryInvalid(redApple, "self->oclAsType(Set(fruit::Tree))");
   //
   ocl.assertQueryEquals(
       redApple, idResolver.createSetOfEach(null, appleTree), "Tree.allInstances()");
   ocl.assertQueryEquals(
       redApple, idResolver.createSetOfEach(null, appleTree), "fruit::Tree.allInstances()");
   ocl.assertQueryEquals(null, ocl.getEmptySetValue(), "fruit::Tree.allInstances()");
   //
   metamodelManager.addGlobalNamespace("zz", fruitPackage);
   ocl.assertQueryEquals(
       redApple, idResolver.createSetOfEach(null, appleTree), "zz::Tree.allInstances()");
   //
   ocl.assertQueryEquals(
       redApple,
       idResolver.createBagOfEach(null, redApple),
       "Fruit.allInstances().oclAsType(Apple)");
   ocl.assertQueryEquals(
       redApple,
       idResolver.createSetOfEach(null, redApple),
       "Fruit.allInstances()->oclAsType(Set(Apple))");
   ocl.dispose();
 }
 /**
  * Executes the query for the specified <tt>target</tt> object. The result is the OCL evaluation
  * result which may be a Number, String, Collection or other object for normal returns or a
  * NullLiteralExp for null, or an InvalidLiteralExp for invalid.
  *
  * @param target the object on which to execute the query; this must be an instance of the context
  *     with which the delegate was created
  * @param arguments a map of variable names to values; these must correspond to the variables with
  *     which the delegate was created
  * @return the query's result
  * @throws InvocationTargetException in case of failure to prepare or execute the query, usually
  *     because of an exception
  */
 @Override
 public Object execute(@Nullable Object target, Map<String, ?> arguments)
     throws InvocationTargetException {
   @SuppressWarnings("null")
   @NonNull
   Map<String, ?> nonNullArguments =
       (arguments != null ? arguments : (Map<String, ?>) Collections.<String, Object>emptyMap());
   try {
     if (specification == null) {
       prepare();
     }
     @SuppressWarnings("null")
     @NonNull
     ExpressionInOCL nonNullSpecification = specification;
     OCL ocl = delegateDomain.getOCL();
     IdResolver idResolver = ocl.getIdResolver();
     Object targetValue = idResolver.boxedValueOf(target);
     org.eclipse.ocl.pivot.Class targetType = idResolver.getStaticTypeOf(targetValue);
     Type requiredType = nonNullSpecification.getOwnedContext().getType();
     if ((requiredType == null)
         || !targetType.conformsTo(ocl.getStandardLibrary(), requiredType)) {
       String message =
           StringUtil.bind(
               PivotMessagesInternal.WrongContextClassifier_ERROR_, targetType, requiredType);
       throw new OCLDelegateException(new SemanticException(message));
     }
     List<Variable> parameterVariables = nonNullSpecification.getOwnedParameters();
     int argCount = arguments != null ? arguments.size() : 0;
     if (parameterVariables.size() != argCount) {
       String message =
           StringUtil.bind(
               PivotMessagesInternal.MismatchedArgumentCount_ERROR_,
               argCount,
               parameterVariables.size());
       throw new OCLDelegateException(new SemanticException(message));
     }
     Query query = ocl.createQuery(nonNullSpecification);
     EvaluationEnvironment env = query.getEvaluationEnvironment(target);
     for (Variable parameterVariable : parameterVariables) {
       // bind arguments to parameter names
       String name = parameterVariable.getName();
       Object object = nonNullArguments.get(name);
       if ((object == null) && !nonNullArguments.containsKey(name)) {
         String message =
             StringUtil.bind(
                 PivotMessagesInternal.EvaluationResultIsInvalid_ERROR_,
                 nonNullSpecification.getBody());
         throw new OCLDelegateException(new SemanticException(message));
       }
       Object value = idResolver.boxedValueOf(object);
       targetType = idResolver.getStaticTypeOf(value);
       requiredType = ClassUtil.nonNullModel(parameterVariable.getType());
       if (!targetType.conformsTo(ocl.getStandardLibrary(), requiredType)) {
         String message =
             StringUtil.bind(
                 PivotMessagesInternal.MismatchedArgumentType_ERROR_,
                 name,
                 targetType,
                 requiredType);
         throw new OCLDelegateException(new SemanticException(message));
       }
       env.add(parameterVariable, value);
     }
     Object result = evaluate(query, target);
     //			if (result.isInvalid()) {
     //				String message = ClassUtil.bind(OCLMessages.EvaluationResultIsInvalid_ERROR_,
     // getOperationName());
     //				throw new OCLDelegateException(message);
     //			}
     //		if ((result == null) / * || ocl.isInvalid(result) * /) {
     //			String message = ClassUtil.bind(OCLMessages.EvaluationResultIsNull_ERROR_,
     // getOperationName());
     //			throw new OCLDelegateException(message);
     //		}
     //		return converter.convert(ocl, result);
     //			if (result == null) {
     //				String message = NLS.bind(OCLMessages.EvaluationResultIsInvalid_ERROR_,
     // PivotUtil.getBody(specification));
     //				throw new InvocationTargetException(new OCLDelegateException(message));
     //			}
     return idResolver.ecoreValueOf(null, result);
   } catch (InvocationTargetException e) {
     throw e;
   } catch (EvaluationException e) {
     String message =
         StringUtil.bind(
             PivotMessagesInternal.EvaluationResultIsInvalid_ERROR_, specification.getBody());
     throw new InvocationTargetException(new EvaluationException(message));
   } catch (WrappedException e) {
     throw new InvocationTargetException(e.getCause());
   } catch (Exception e) {
     throw new InvocationTargetException(e);
   }
 }