@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 handleEOperations(
     List<EOperation> operations, Set<EPackage> visitedPackages, Set<Object> visited) {
   if (operations != null) {
     for (EOperation operation : operations) {
       handleEGenericType(operation.getEGenericType(), visitedPackages, visited);
       handleETypeParameters(operation.getETypeParameters(), visitedPackages, visited);
       handleEParameters(operation.getEParameters(), visitedPackages, visited);
       handleEGenericTypes(operation.getEGenericExceptions(), 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;
 }
  private String matches(
      org.eclipse.emf.ecore.EObject element, String identifier, boolean matchFuzzy) {
    // first check for attributes that have set the ID flag to true
    java.util.List<org.eclipse.emf.ecore.EStructuralFeature> features =
        element.eClass().getEStructuralFeatures();
    for (org.eclipse.emf.ecore.EStructuralFeature feature : features) {
      if (feature instanceof org.eclipse.emf.ecore.EAttribute) {
        org.eclipse.emf.ecore.EAttribute attribute = (org.eclipse.emf.ecore.EAttribute) feature;
        if (attribute.isID()) {
          Object attributeValue = element.eGet(attribute);
          String match = matches(identifier, attributeValue, matchFuzzy);
          if (match != null) {
            return match;
          }
        }
      }
    }

    // then check for an attribute that is called 'name'
    org.eclipse.emf.ecore.EStructuralFeature nameAttr =
        element.eClass().getEStructuralFeature(NAME_FEATURE);
    if (nameAttr instanceof org.eclipse.emf.ecore.EAttribute) {
      Object attributeValue = element.eGet(nameAttr);
      return matches(identifier, attributeValue, matchFuzzy);
    } else {
      // try any other string attribute found
      for (org.eclipse.emf.ecore.EAttribute stringAttribute :
          element.eClass().getEAllAttributes()) {
        if ("java.lang.String".equals(stringAttribute.getEType().getInstanceClassName())) {
          Object attributeValue = element.eGet(stringAttribute);
          String match = matches(identifier, attributeValue, matchFuzzy);
          if (match != null) {
            return match;
          }
        }
      }

      for (org.eclipse.emf.ecore.EOperation o : element.eClass().getEAllOperations()) {
        if (o.getName().toLowerCase().endsWith(NAME_FEATURE) && o.getEParameters().size() == 0) {
          String result = (String) ssl.resource.ssl.util.SslEObjectUtil.invokeOperation(element, o);
          String match = matches(identifier, result, matchFuzzy);
          if (match != null) {
            return match;
          }
        }
      }
    }
    return null;
  }
  /**
   * Returns a list of potential identifiers that may be used to reference the given element. This
   * method can be overridden to customize the identification of elements.
   */
  public List<String> getNames(EObject element) {
    List<String> names = new ArrayList<String>();

    // first check for attributes that have set the ID flag to true
    List<EAttribute> attributes = element.eClass().getEAllAttributes();
    for (EAttribute attribute : attributes) {
      if (attribute.isID()) {
        Object attributeValue = element.eGet(attribute);
        if (attributeValue != null) {
          names.add(attributeValue.toString());
        }
      }
    }

    // then check for an attribute that is called 'name'
    EStructuralFeature nameAttr = element.eClass().getEStructuralFeature(NAME_FEATURE);
    if (nameAttr instanceof EAttribute) {
      Object attributeValue = element.eGet(nameAttr);
      if (attributeValue != null) {
        names.add(attributeValue.toString());
      }
    } else {
      // try any other string attribute found
      for (EAttribute attribute : attributes) {
        if ("java.lang.String".equals(attribute.getEType().getInstanceClassName())) {
          Object attributeValue = element.eGet(attribute);
          if (attributeValue != null) {
            names.add(attributeValue.toString());
          }
        }
      }

      // try operations without arguments that return strings and which have a name that
      // ends with 'name'
      for (EOperation operation : element.eClass().getEAllOperations()) {
        if (operation.getName().toLowerCase().endsWith(NAME_FEATURE)
            && operation.getEParameters().size() == 0) {
          Object result =
              org.emftext.sdk.concretesyntax.resource.cs.util.CsEObjectUtil.invokeOperation(
                  element, operation);
          if (result != null) {
            names.add(result.toString());
          }
        }
      }
    }
    return names;
  }
  private String getCallLabel() {
    String name = null;
    Activity activity = (Activity) getRealModel().getCallee();
    if (activity != null) {
      EOperation operation = activity.getOwningOperation().getOperation();
      if (!activity.getOutParameters().isEmpty()) {
        EParameter param = activity.getOutParameters().get(0);
        for (ParameterBinding binding : getRealModel().getOwnedParameterBindings()) {
          if (binding.getParameter() == param) {
            name = Expr2String.toString(binding.getValueExpression()) + " := ";
          }
        }

        if (name == null) {
          name = "";
        }
      } else {
        name = "void ";
      }

      name += operation.getName() + "(";
      for (EParameter param : operation.getEParameters()) {
        boolean found = false;
        for (ParameterBinding binding : getRealModel().getOwnedParameterBindings()) {
          if (binding.getParameter() == param) {
            name += Expr2String.toString(binding.getValueExpression()) + ",";
            found = true;
          }
        }

        if (!found) {
          name += "null,";
        }
      }
      int lastComma = name.lastIndexOf(",");
      if (lastComma > -1) {
        name = name.substring(0, lastComma);
      }
      name += ")";
    } else {
      name = "select activity to call";
    }
    return name;
  }
 private String getName(ReferenceType element) {
   org.eclipse.emf.ecore.EStructuralFeature nameAttr =
       element.eClass().getEStructuralFeature(NAME_FEATURE);
   if (element.eIsProxy()) {
     String fragment = ((org.eclipse.emf.ecore.InternalEObject) element).eProxyURI().fragment();
     if (fragment != null
         && fragment.startsWith(
             ssl.resource.ssl.ISslContextDependentURIFragment.INTERNAL_URI_FRAGMENT_PREFIX)) {
       fragment =
           fragment.substring(
               ssl.resource.ssl.ISslContextDependentURIFragment.INTERNAL_URI_FRAGMENT_PREFIX
                   .length());
       fragment = fragment.substring(fragment.indexOf("_") + 1);
     }
     return fragment;
   } else if (nameAttr instanceof org.eclipse.emf.ecore.EAttribute) {
     return (String) element.eGet(nameAttr);
   } else {
     // try any other string attribute found
     for (org.eclipse.emf.ecore.EAttribute strAttribute : element.eClass().getEAllAttributes()) {
       if (!strAttribute.isMany()
           && strAttribute.getEType().getInstanceClassName().equals("String")) {
         return (String) element.eGet(strAttribute);
       }
     }
     for (org.eclipse.emf.ecore.EOperation o : element.eClass().getEAllOperations()) {
       if (o.getName().toLowerCase().endsWith(NAME_FEATURE) && o.getEParameters().size() == 0) {
         String result = (String) ssl.resource.ssl.util.SslEObjectUtil.invokeOperation(element, o);
         if (result != null) {
           return result;
         }
       }
     }
   }
   return null;
 }
  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();
    }
  }