/**
   * Constructs new operation call for the given operation and execution context.
   *
   * @param operation a valid AST operation to be called. <code>Note:</code> This must be an
   *     operation owned by a valid QVT Library module
   * @param context non-QVT transformation context in which this operation will be called
   * @exception IllegalArgumentException If the passed <code>operation</code> or <code>context
   *     </code> are <code>null</code>; or the operation is not valid AST element for construction
   *     of the call
   */
  HelperOperationCall(Helper operation, NonTransformationExecutionContext context) {
    if (operation == null || context == null) {
      throw new IllegalArgumentException();
    }

    fOwningModule = QvtOperationalParserUtil.getOwningModule(operation);
    if (fOwningModule == null) {
      throw new IllegalArgumentException("Not a library query or helper"); // $NON-NLS-1$
    }

    fOperation = operation;
    fContextType = QvtOperationalParserUtil.getContextualType(fOperation);

    fArgumentTypes = new ArrayList<EClassifier>(fOperation.getEParameters().size());
    for (EParameter eParam : fOperation.getEParameters()) {
      EClassifier paramType = eParam.getEType();
      if (paramType == null) {
        throw new IllegalArgumentException("Parameter with no type"); // $NON-NLS-1$
      }

      fArgumentTypes.add(paramType);
    }

    fContext = context;
  }
    @Override
    public EOperation define(EcoreEnvironment env) {
      EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
      eOperation.setName(fName);
      int pos = 0;
      for (EClassifier cls : fParamTypes) {
        EParameter eParam = EcoreFactory.eINSTANCE.createEParameter();
        String paramName = cls.getName();
        if (fParamNames != null) {
          paramName = fParamNames[pos++];
        }

        eParam.setName(paramName);
        eParam.setEType(cls);
        eOperation.getEParameters().add(eParam);
      }

      eOperation.setEType(fReturnType);

      assert fContextType instanceof EClass;
      ((EClass) fContextType).getEOperations().add(eOperation);

      CallHandlerAdapter.attach(eOperation, fDispatcher);
      return eOperation;
    }
 protected void handleEParameters(
     List<EParameter> parameters, Set<EPackage> visitedPackages, Set<Object> visited) {
   if (parameters != null) {
     for (EParameter parameter : parameters) {
       handleEClassifier(parameter.getEType(), visitedPackages, visited);
       handleEGenericType(parameter.getEGenericType(), visitedPackages, visited);
     }
   }
 }
 @Override
 public Object caseEOperation(EOperation object) {
   Operation operation = new Operation(object.getName());
   operation.type = getType(object.getEType());
   operation.setBounds(object.getLowerBound(), object.getUpperBound());
   operation.setStatic(false);
   operation.setScope(Scope.PUBLIC);
   for (EParameter epar : object.getEParameters()) {
     TypedElement fpar = new TypedElement(epar.getName());
     fpar.type = getType(epar.getEType());
     operation.addFormalParameter(fpar);
   }
   return operation;
 }
  @Override
  public String getColumnText(Object element, int index) {
    if (element instanceof EParameter) {
      EParameter eParameter = (EParameter) element;

      StringBuilder builder = new StringBuilder();

      builder.append(eParameter.getName());

      builder.append(' ');
      builder.append(':');
      builder.append(' ');

      return EcoreTextUtil.append(builder, eParameter.getEType()).toString();
    }
    return getText(element);
  }
  @Override
  public Image getColumnImage(Object element, int index) {
    if (element instanceof EParameter) {
      EParameter eParameter = (EParameter) element;

      if (eParameter.eContainer() instanceof Activity) {
        Activity activity = (Activity) eParameter.eContainer();
        if (isOutgoing && activity.getInParameters().contains(eParameter)) {
          return DiagramImages.getImage(DiagramImages.EPARAMETER_OUT_REF);
        } else if (!isOutgoing && activity.getOutParameters().contains(eParameter)) {
          return DiagramImages.getImage(DiagramImages.EPARAMETER_IN_REF);
        }
      }

      if (isOutgoing) {
        return DiagramImages.getImage(DiagramImages.EPARAMETER_OUT);
      } else {
        return DiagramImages.getImage(DiagramImages.EPARAMETER_IN);
      }
    }
    return null;
  }
 /**
  * Returns the {@link EStructuralFeature} and {@link EOperation} syntax completion proposals for
  * the given prefix and root.
  *
  * @param prefix the syntax prefix
  * @param root the root AST node
  * @param propertyCallType the {@link PropertyCallType}
  * @return the syntax completion proposals
  */
 protected List<SyntaxCompletionProposal> getEFeatureProposals(
     final String prefix, final EObject root, final PropertyCallType propertyCallType) {
   if (propertyCallType != PropertyCallType.REGULAR
       || !(root instanceof org.eclipselabs.simpleocl.Module)) {
     return Collections.<SyntaxCompletionProposal>emptyList();
   }
   final String strippedPrefix = stripPropertyCallPrefix(prefix);
   final SortedSet<String> features = new TreeSet<String>();
   final Map<String, URL> images = new HashMap<String, URL>();
   final Map<String, String> displayStrings = new HashMap<String, String>();
   final org.eclipselabs.simpleocl.Module module = (org.eclipselabs.simpleocl.Module) root;
   final ExecEnv env = EmftvmFactory.eINSTANCE.createExecEnv();
   loadMetamodels(module, env);
   for (OclMetamodel metamodel : module.getMetamodels()) {
     try {
       final URI emfURI = URI.createURI(metamodel.getUri());
       final ResourceSet rs = new ResourceSetImpl();
       final Resource resource = rs.getResource(emfURI, true);
       for (EObject eObject : new ResourceIterable(resource)) {
         if (!(eObject.eContainer() instanceof EClassifier)) {
           continue;
         }
         if (eObject instanceof EStructuralFeature || eObject instanceof EOperation) {
           String name = ((ETypedElement) eObject).getName();
           if (strippedPrefix.isEmpty() || name.startsWith(strippedPrefix)) {
             StringBuilder sb = new StringBuilder(name);
             StringBuilder displayString = new StringBuilder(name);
             if (eObject instanceof EOperation) {
               sb.append('(');
               displayString.append('(');
               boolean first = true;
               for (EParameter par : ((EOperation) eObject).getEParameters()) {
                 if (!first) {
                   sb.append(", ");
                   displayString.append(", ");
                 }
                 sb.append(par.getName());
                 displayString
                     .append(par.getName())
                     .append(" : ")
                     .append(toPrettyString(par, env));
                 first = false;
               }
               sb.append(')');
               displayString.append(')');
             }
             displayString
                 .append(" : ")
                 .append(toPrettyString((ETypedElement) eObject, env))
                 .append(" - ")
                 .append(EMFTVMUtil.toPrettyString(eObject.eContainer(), env));
             features.add(sb.toString());
             ItemProviderAdapter itemProviderAdapter =
                 (ItemProviderAdapter) ecoreItemProviderFactory.createAdapter(eObject);
             images.put(
                 sb.toString(), getItemProviderImageURL(itemProviderAdapter.getImage(eObject)));
             displayStrings.put(sb.toString(), displayString.toString());
           }
         }
       }
     } catch (RuntimeException e) {
       SimpleoclUIPlugin.logError(e.getLocalizedMessage(), e);
     }
   }
   return buildProposals(prefix, root, features, images, displayStrings);
 }
  public void propagateEOperations(JavaResource resource, GenClass genClass) {
    GenPackage genPackage = genClass.getGenPackage();
    EPackage ePackage = genPackage.getEcorePackage();
    if (resource.getContents().isEmpty()
        || !(resource.getContents().get(0) instanceof CompilationUnit)) {
      return;
    }
    CompilationUnit cu = (CompilationUnit) resource.getContents().get(0);
    Class customClass = (Class) cu.getClassifiers().get(0);
    EClass eClass = genClass.getEcoreClass();

    if (eClass == null) {
      return;
    }

    Set<Method> annotatedMethods = getAnnotatedMethods(customClass);

    for (Method method : annotatedMethods) {
      for (AnnotationInstanceOrModifier modifier : method.getAnnotationsAndModifiers()) {
        if (modifier instanceof Public) {
          EOperation newEOperation = EcoreFactory.eINSTANCE.createEOperation();
          newEOperation.setName(method.getName());
          Type opType = method.getTypeReference().getTarget();
          newEOperation.setEType(
              eClassifierForCustomClass(opType, method.getTypeReference(), ePackage));
          if (isMulti(opType)) {
            newEOperation.setUpperBound(-1);
          }
          for (Parameter parameter : method.getParameters()) {
            EParameter newEParameter = EcoreFactory.eINSTANCE.createEParameter();
            newEParameter.setName(parameter.getName());
            Type paramType = parameter.getTypeReference().getTarget();
            newEParameter.setEType(
                eClassifierForCustomClass(paramType, parameter.getTypeReference(), ePackage));
            // TODO generics, ...
            newEOperation.getEParameters().add(newEParameter);
          }
          // TODO @jendrik: why is that needed?
          //					for (AnnotationInstanceOrModifier annotationInstance :
          // method.getAnnotationsAndModifiers()) {
          //						if (annotationInstance instanceof AnnotationInstance) {
          //							Classifier javaAnnotation = ((AnnotationInstance)
          // annotationInstance).getAnnotation();
          //							if (javaAnnotation.eIsProxy()) {
          //								continue;
          //							}
          //							EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
          //							eAnnotation.setSource(javaAnnotation.getContainingCompilationUnit(
          //									).getNamespacesAsString() + javaAnnotation.getName());
          //							newEOperation.getEAnnotations().add(eAnnotation);
          //						}
          //					}
          boolean operationAlreadyExists = false;
          List<EOperation> operations = eClass.getEOperations();
          List<EOperation> existingOperations = new ArrayList<EOperation>(operations);
          // must be done here already for ensuring that compared operations have the same parent
          eClass.getEOperations().add(newEOperation);
          for (EOperation existingOperation : existingOperations) {
            boolean removed = removeAnnotation(existingOperation);
            if (EcoreUtil.equals(existingOperation, newEOperation)) {
              operationAlreadyExists = true;
              removeAnnotation(existingOperation);
              annotateAsGenerated(existingOperation);
              break;
            }
            if (removed) {
              annotateAsGenerated(existingOperation);
            }
          }
          if (!operationAlreadyExists) {
            annotateAsGenerated(newEOperation);
          } else {
            eClass.getEOperations().remove(newEOperation);
          }
          break;
        }
      }
    }

    try {
      Resource ecoreResource = ePackage.eResource();
      URI originalURI = ecoreResource.getURI();
      if (originalURI.isFile()) {
        String workspacePath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString();
        URI platformURI =
            URI.createPlatformResourceURI(
                originalURI.toFileString().substring(workspacePath.length()), true);
        ecoreResource.setURI(platformURI);
      }
      new ResourceSaver().saveResource(ecoreResource);
      ecoreResource.setURI(originalURI);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }