@Override
  public Object caseEClass(EClass object) {
    Type type = getType(object);

    if (object.isInterface()) {
    } else { // class
      Class clazz = (Class) type;
      clazz.setAbstract(object.isAbstract());
    }

    Set<Type> assocAndGen = new HashSet<>();
    Set<Type> dependencies = new HashSet<>();

    for (EClass eSuperType : object.getESuperTypes()) {
      Type superType = getType(eSuperType);
      assocAndGen.add(superType);

      if (eSuperType.isInterface()) {
        type.addInterface((Interface) superType);
      } else {
        type.addSuperClass((Class) superType);
      }
    }

    for (EStructuralFeature eFeature : object.getEStructuralFeatures()) {
      Attribute attr = (Attribute) doSwitch(eFeature);
      type.addAttribute(attr);

      assocAndGen.add(attr.type);
    }
    for (EOperation eOperation : object.getEOperations()) {
      Operation op = (Operation) doSwitch(eOperation);
      type.addOperation(op);

      dependencies.add(op.type);
      for (TypedElement fpar : op.formalParameters()) {
        dependencies.add(fpar.type);
      }
    }
    dependencies.removeAll(assocAndGen);
    for (Type dep : dependencies) {
      type.addDependency(dep);
    }

    return type;
  }
 @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;
 }