/**
  * Returns the source of a relation. The source of a relation is defined as the modelelement that
  * propagates this relation. If there are more then 1 sources, only the first is returned. If
  * there is no source, null is returned. Examples of sources include classifiers that are types to
  * associationends, usecases that are bases to extend and include relations and so on.
  *
  * @param relation
  * @return MModelElement
  */
 public MModelElement getSource(MRelationship relation) {
   if (relation instanceof MAssociation) {
     MAssociation assoc = (MAssociation) relation;
     List conns = assoc.getConnections();
     if (conns.isEmpty()) return null;
     return ((MAssociationEnd) conns.get(0)).getType();
   }
   if (relation instanceof MGeneralization) {
     MGeneralization gen = (MGeneralization) relation;
     return gen.getParent();
   }
   if (relation instanceof MDependency) {
     MDependency dep = (MDependency) relation;
     Collection col = dep.getSuppliers();
     if (col.isEmpty()) return null;
     return (MModelElement) (col.toArray())[0];
   }
   if (relation instanceof MFlow) {
     MFlow flow = (MFlow) relation;
     Collection col = flow.getSources();
     if (col.isEmpty()) return null;
     return (MModelElement) (col.toArray())[0];
   }
   if (relation instanceof MExtend) {
     MExtend extend = (MExtend) relation;
     return extend.getExtension(); // we have to follow the arrows..
   }
   if (relation instanceof MInclude) {
     MInclude include = (MInclude) relation;
     return include.getBase();
   }
   return null;
 }
 /**
  * Returns the destination of a relation. The destination of a relation is defined as the
  * modelelement that receives this relation. If there are more then 1 destinations, only the first
  * is returned. If there is no destination, null is returned. Examples of sources include
  * classifiers that are types to associationends, usecases that are bases to extend and include
  * relations and so on. In the case of an association, the destination is defined as the type of
  * the second element in the connections list.
  *
  * @param relation
  * @return MModelElement
  */
 public MModelElement getDestination(MRelationship relation) {
   if (relation instanceof MAssociation) {
     MAssociation assoc = (MAssociation) relation;
     List conns = assoc.getConnections();
     if (conns.size() <= 1) return null;
     return ((MAssociationEnd) conns.get(1)).getType();
   }
   if (relation instanceof MGeneralization) {
     MGeneralization gen = (MGeneralization) relation;
     return gen.getChild();
   }
   if (relation instanceof MDependency) {
     MDependency dep = (MDependency) relation;
     Collection col = dep.getClients();
     if (col.isEmpty()) return null;
     return (MModelElement) (col.toArray())[0];
   }
   if (relation instanceof MFlow) {
     MFlow flow = (MFlow) relation;
     Collection col = flow.getTargets();
     if (col.isEmpty()) return null;
     return (MModelElement) (col.toArray())[0];
   }
   if (relation instanceof MExtend) {
     MExtend extend = (MExtend) relation;
     return extend.getBase();
   }
   if (relation instanceof MInclude) {
     MInclude include = (MInclude) relation;
     return include.getAddition();
   }
   return null;
 }
 private boolean isValidNamespace(MGeneralization gen, MNamespace ns) {
   if (gen.getParent() == null || gen.getChild() == null) return true;
   MNamespace ns1 = gen.getParent().getNamespace();
   MNamespace ns2 = gen.getChild().getNamespace();
   if (ns == getFirstSharedNamespace(ns1, ns2)) return true;
   return false;
 }
 /**
  * Gets the generalization between two generalizable elements. Returns null if there is none.
  *
  * @param child
  * @param parent
  * @return MGeneralization
  */
 public MGeneralization getGeneralization(
     MGeneralizableElement child, MGeneralizableElement parent) {
   if (child == null || parent == null) return null;
   Iterator it = child.getGeneralizations().iterator();
   while (it.hasNext()) {
     MGeneralization gen = (MGeneralization) it.next();
     if (gen.getParent() == parent) {
       return gen;
     }
   }
   return null;
 }
  /**
   * This method returns all Classifiers of which this class is a direct supertype.
   *
   * @param cls the class you want to have the children for
   * @return a collection of the children, each of which is a {@link MGeneralizableElement
   *     MGeneralizableElement}
   */
  public Collection getSubtypes(MClassifier cls) {

    Collection result = new Vector();
    Collection gens = cls.getSpecializations();
    Iterator genIterator = gens.iterator();

    while (genIterator.hasNext()) {
      MGeneralization next = (MGeneralization) genIterator.next();
      result.add(next.getChild());
    }
    return result;
  }
  /**
   * This method returns all Classifiers of which this class is a direct subtype.
   *
   * @param cls the class you want to have the parents for
   * @return a collection of the parents, each of which is a {@link MGeneralizableElement
   *     MGeneralizableElement}
   */
  public Collection getSupertypes(MClassifier cls) {

    Collection result = new HashSet();
    Collection gens = cls.getGeneralizations();
    Iterator genIterator = gens.iterator();

    while (genIterator.hasNext()) {
      MGeneralization next = (MGeneralization) genIterator.next();
      result.add(next.getParent());
    }
    return result;
  }
 /**
  * Returns all classifiers that extend some classifier clazz.
  *
  * @param clazz
  * @return Collection
  */
 public Collection getExtendingClassifiers(MClassifier clazz) {
   if (clazz == null) return new ArrayList();
   Iterator it = clazz.getSpecializations().iterator();
   List list = new ArrayList();
   while (it.hasNext()) {
     MGeneralization gen = (MGeneralization) it.next();
     MGeneralizableElement client = gen.getChild();
     if (client instanceof MClassifier) {
       list.add(client);
     }
   }
   return list;
 }
 /**
  * Returns all classes some generalizable element clazz extends.
  *
  * @param clazz
  * @return Collection
  */
 public Collection getExtendedClassifiers(MGeneralizableElement clazz) {
   if (clazz == null) return new ArrayList();
   Iterator it = clazz.getGeneralizations().iterator();
   List list = new ArrayList();
   while (it.hasNext()) {
     MGeneralization gen = (MGeneralization) it.next();
     MGeneralizableElement parent = gen.getParent();
     if (parent != null) {
       list.add(parent);
     }
   }
   return list;
 }
 public java.util.Enumeration gen(Object o) {
   MClass c = (MClass) o;
   Vector specs = new Vector(c.getSpecializations());
   if (specs == null) {
     return EnumerationEmpty.theInstance();
   }
   // TODO: it would be nice to have a EnumerationXform
   // and a Functor object in uci.util
   Vector specClasses = new Vector(specs.size());
   java.util.Enumeration enum = specs.elements();
   while (enum.hasMoreElements()) {
     MGeneralization g = (MGeneralization) enum.nextElement();
     MGeneralizableElement ge = g.getChild();
     // assert: ge != null
     if (ge != null) specClasses.addElement(ge);
   }
   return specClasses.elements();
 }