public String check(IEObjectDescription input) {
   if (input instanceof IValidatedEObjectDescription) {
     final IValidatedEObjectDescription validatedDescription =
         (IValidatedEObjectDescription) input;
     JvmIdentifiableElement identifiable = validatedDescription.getEObjectOrProxy();
     if (identifiable.eIsProxy())
       identifiable = (JvmIdentifiableElement) EcoreUtil.resolve(identifiable, context);
     String issueCode;
     if (identifiable.eIsProxy()) issueCode = UNRESOLVABLE_PROXY;
     else if (!validatedDescription.isValid()) {
       if (Strings.isEmpty(validatedDescription.getIssueCode())) issueCode = FEATURE_NOT_VISIBLE;
       else return validatedDescription.getIssueCode();
     } else issueCode = dispatcher.invoke(identifiable, context, reference, validatedDescription);
     validatedDescription.setIssueCode(issueCode);
     return issueCode;
   }
   return null;
 }
/**
 * Synthetizes {@link Class} objects from deltas
 *
 * @author bettini
 */
public class DeltaJClassBuilder {

  @Inject protected DeltasToApplyFinder deltasToApplyFinder = new DeltasToApplyFinder();

  @Inject protected OriginalPreProcessor originalPreProcessor = new OriginalPreProcessor();

  private PolymorphicDispatcher<Boolean> modifyClassDispatcher =
      PolymorphicDispatcher.createForSingleTarget("modifyClassCase", 2, 2, this);

  public ClassCollection classesToGenerate(Product product) {

    DeltasToApply deltas = deltasToApplyFinder.getDeltas(product);
    return buildClasses(deltas);
  }

  public ClassCollection buildClasses(DeltasToApply deltas) {

    ClassCollection classes = new ClassCollection();
    for (DeltaModule delta : deltas) {
      buildClasses(classes, delta);
    }
    return classes;
  }

  public void buildClasses(ClassCollection currentClasses, DeltaModule deltaToApply) {

    currentClasses.addAll(getCopyOfAddedClasses(deltaToApply));
    removeClasses(currentClasses, deltaToApply);
    modifyClasses(currentClasses, deltaToApply);
  }

  public List<Class> getCopyOfAddedClasses(DeltaModule delta) {

    List<Class> addedClasses = DeltaJUtils.getAddedClasses(delta);
    List<Class> copy = new LinkedList<Class>();
    for (Class class1 : addedClasses) {
      copy.add(EcoreUtil2.clone(class1));
    }
    return copy;
  }

  public void removeClasses(ClassCollection collection, DeltaModule deltaToApply) {

    List<String> classesToRemove = DeltaJUtils.getClassesToRemove(deltaToApply);
    for (String classToRemove : classesToRemove) {
      removeClassByName(collection, classToRemove);
    }
  }

  public void removeClassByName(ClassCollection collection, String classToRemove) {

    for (Class class1 : collection) {
      if (class1.getName().equals(classToRemove)) {
        collection.remove(class1);
        return;
      }
    }
  }

  public void modifyClasses(ClassCollection collection, DeltaModule delta) {

    List<ClassModification> modifiesClasses = DeltaJUtils.getDeltaModifies(delta);
    for (ClassModification modifiesClass : modifiesClasses) {
      Class classToModify = DeltaJUtils.classByName(collection, modifiesClass.getName());
      if (classToModify != null) modifyClass(classToModify, modifiesClass);
    }
  }

  public void modifyClass(Class classToModify, ClassModification modifiesClass) {

    if (modifiesClass.getExtends() != null) classToModify.setExtends(modifiesClass.getExtends());
    for (DeltaSubAction modifiesClassAction : modifiesClass.getSubActions())
      modifyClass(classToModify, modifiesClassAction);
  }

  public void modifyClass(Class classToModify, DeltaSubAction modifiesClassAction) {

    modifyClassDispatcher.invoke(classToModify, modifiesClassAction);
  }

  protected void modifyClassCase(Class classToModify, FieldAddition addsField) {

    addClonedField(classToModify, addsField.getField());
  }

  protected void addClonedField(Class classToModify, Field field) {

    classToModify.getFields().add(EcoreUtil2.clone(field));
  }

  protected void modifyClassCase(Class classToModify, MethodAddition addsMethod) {

    addClonedMethod(classToModify, addsMethod.getMethod());
  }

  protected void addClonedMethod(Class classToModify, Method method) {

    classToModify.getMethods().add(EcoreUtil2.clone(method));
  }

  protected void modifyClassCase(Class classToModify, FieldRemoval removesField) {

    Field fieldToRemove = DeltaJUtils.fieldByName(classToModify, removesField.getName());
    if (fieldToRemove != null) classToModify.getFields().remove(fieldToRemove);
  }

  protected void modifyClassCase(Class classToModify, MethodRemoval removesMethod) {

    removeMethod(classToModify, removesMethod.getName());
  }

  protected Method removeMethod(Class classToModify, String methodName) {

    Method methodToRemove = DeltaJUtils.methodByName(classToModify, methodName);
    if (methodToRemove != null) classToModify.getMethods().remove(methodToRemove);
    return methodToRemove;
  }

  protected void modifyClassCase(Class classToModify, MethodModification modifiesMethod) {

    replaceMethod(classToModify, modifiesMethod.getMethod());
  }

  public void replaceMethod(Class classToModify, Method method) {

    Method methodToReplace = removeMethod(classToModify, method.getName());
    if (methodToReplace != null) {
      boolean originalReferenced = originalPreProcessor.preprocess(methodToReplace, method);
      if (originalReferenced) classToModify.getMethods().add(methodToReplace);
    }
    addClonedMethod(classToModify, method);
  }
}
  public void modifyClass(Class classToModify, DeltaSubAction modifiesClassAction) {

    modifyClassDispatcher.invoke(classToModify, modifiesClassAction);
  }
 protected boolean doSemanticFormat(
     EObject semantic, StyleSet styleSet, IDomNode node, ITextFlow flow, ILayoutContext context) {
   return formatDispatcher.invoke(semantic, styleSet, node, flow, context);
 }
 protected void doSemanticBefore(
     EObject semantic, StyleSet styleSet, IDomNode node, ITextFlow flow, ILayoutContext context) {
   beforeDispatcher.invoke(semantic, styleSet, node, flow, context);
 }