/** Return a Fig that can be used to represent the given edge */
  public FigEdge getFigEdgeFor(GraphModel gm, Layer lay, Object edge) {
    if (edge instanceof MDependency) {

      MDependency dep = (MDependency) edge;
      FigDependency depFig = new FigDependency(dep);

      MModelElement supplier = (MModelElement) ((dep.getSuppliers().toArray())[0]);
      MModelElement client = (MModelElement) ((dep.getClients().toArray())[0]);

      FigNode supFN = (FigNode) lay.presentationFor(supplier);
      FigNode cliFN = (FigNode) lay.presentationFor(client);

      depFig.setSourcePortFig(cliFN);
      depFig.setSourceFigNode(cliFN);
      depFig.setDestPortFig(supFN);
      depFig.setDestFigNode(supFN);
      depFig.getFig().setLayer(lay);
      depFig.getFig().setDashed(true);
      return depFig;
    }

    if (edge instanceof MAssociation) {
      MAssociation asc = (MAssociation) edge;
      FigAssociation ascFig = new FigAssociation(asc, lay);
      Collection connections = asc.getConnections();
      if (connections == null) System.out.println("null connections....");
      Object[] connArray = connections.toArray();
      MAssociationEnd fromEnd = (MAssociationEnd) connArray[0];
      MClassifier fromCls = (MClassifier) fromEnd.getType();
      MAssociationEnd toEnd = (MAssociationEnd) connArray[1];
      MClassifier toCls = (MClassifier) toEnd.getType();
      FigNode fromFN = (FigNode) lay.presentationFor(fromCls);
      FigNode toFN = (FigNode) lay.presentationFor(toCls);
      ascFig.setSourcePortFig(fromFN);
      ascFig.setSourceFigNode(fromFN);
      ascFig.setDestPortFig(toFN);
      ascFig.setDestFigNode(toFN);
      ascFig.getFig().setLayer(lay);
      return ascFig;
    }
    return null;
  }
  /**
   * Create an edge of the given type and connect it to the given nodes.
   *
   * @param graphModel the graph model in which to create the connection element
   * @param edgeType the UML object type of the connection
   * @param sourceFig the FigNode for the source element
   * @param destFig the FigNode for the destination element
   * @return The FigEdge representing the newly created model element
   */
  @Override
  protected FigEdge buildConnection(
      MutableGraphModel graphModel, Object edgeType, Fig sourceFig, Fig destFig) {
    try {
      Object associationEnd =
          Model.getUmlFactory()
              .buildConnection(
                  edgeType, sourceFig.getOwner(), null, destFig.getOwner(), null, null, null);

      final FigNode sourceFigNode = convertToFigNode(sourceFig);
      final FigNode destFigNode = convertToFigNode(destFig);

      graphModel.addEdge(associationEnd);

      setNewEdge(associationEnd);

      // Calling connect() will add the edge to the GraphModel and
      // any LayerPersectives on that GraphModel will get a
      // edgeAdded event and will add an appropriate FigEdge
      // (determined by the GraphEdgeRenderer).

      if (getNewEdge() != null) {
        sourceFigNode.damage();
        destFigNode.damage();
        Layer lay = editor.getLayerManager().getActiveLayer();
        FigEdge fe = (FigEdge) lay.presentationFor(getNewEdge());
        _newItem.setLineColor(Color.black);
        fe.setFig(_newItem);
        fe.setSourcePortFig(sourceFigNode);
        fe.setSourceFigNode(sourceFigNode);
        fe.setDestPortFig(destFigNode);
        fe.setDestFigNode(destFigNode);
        return fe;
      } else {
        return null;
      }
    } catch (IllegalModelElementConnectionException e) {
      // We have already confirmed the connection is valid
      return null;
    }
  }
  /**
   * Return a Fig that can be used to represent the given edge.
   *
   * <p>Generally the same code as for the ClassDiagram, since it's very related to it. Deal with
   * each of the edge types in turn.
   *
   * <p>
   *
   * @param gm The graph model for which we are rendering.
   * @param lay The layer in the graph on which we want this figure.
   * @param edge The edge to be rendered (an model element object)
   * @param styleAttributes an optional map of attributes to style the fig
   * @return The fig to be used, or <code>null</code> if we can't create one.
   * @see org.tigris.gef.graph.GraphEdgeRenderer#getFigEdgeFor( org.tigris.gef.graph.GraphModel,
   *     org.tigris.gef.base.Layer, java.lang.Object, java.util.Map)
   */
  public FigEdge getFigEdgeFor(GraphModel gm, Layer lay, Object edge, Map styleAttributes) {

    if (LOG.isDebugEnabled()) {
      LOG.debug("making figedge for " + edge);
    }

    if (edge == null) {
      throw new IllegalArgumentException("A model edge must be supplied");
    }

    FigEdgeModelElement newEdge = null;

    if (Model.getFacade().isAAssociation(edge)) {
      // If the edge is an association, we'll need a FigAssociation
      Object asc = /*(MAssociation)*/ edge;
      FigAssociation ascFig = new FigAssociation(asc, lay);

      newEdge = ascFig;
    } else if (Model.getFacade().isAGeneralization(edge)) {
      // Generalization needs a FigGeneralization
      Object gen = /*(MGeneralization)*/ edge;
      FigGeneralization genFig = new FigGeneralization(gen, lay);
      newEdge = genFig;
    } else if (Model.getFacade().isAExtend(edge)) {
      // Extend relationship
      Object ext = /*(MExtend)*/ edge;
      FigExtend extFig = new FigExtend(ext);

      // The nodes at the two ends

      Object base = Model.getFacade().getBase(ext);
      Object extension = Model.getFacade().getExtension(ext);

      // The figs for the two end nodes

      FigNode baseFN = (FigNode) lay.presentationFor(base);
      FigNode extensionFN = (FigNode) lay.presentationFor(extension);

      // Link the new extend relationship in to the ends. Remember we
      // draw from the extension use case to the base use case.

      extFig.setSourcePortFig(extensionFN);
      extFig.setSourceFigNode(extensionFN);

      extFig.setDestPortFig(baseFN);
      extFig.setDestFigNode(baseFN);

      newEdge = extFig;
    } else if (Model.getFacade().isAInclude(edge)) {
      // Include relationship is very like extend.
      Object inc = /*(MInclude)*/ edge;
      FigInclude incFig = new FigInclude(inc);

      Object base = Model.getFacade().getBase(inc);
      Object addition = Model.getFacade().getAddition(inc);

      // The figs for the two end nodes

      FigNode baseFN = (FigNode) lay.presentationFor(base);
      FigNode additionFN = (FigNode) lay.presentationFor(addition);

      // Link the new include relationship in to the ends

      incFig.setSourcePortFig(baseFN);
      incFig.setSourceFigNode(baseFN);

      incFig.setDestPortFig(additionFN);
      incFig.setDestFigNode(additionFN);

      newEdge = incFig;
    } else if (Model.getFacade().isADependency(edge)) {
      // Dependency needs a FigDependency
      Object dep = /*(MDependency)*/ edge;
      FigDependency depFig = new FigDependency(dep);

      // Where there is more than one supplier or client, take the first
      // element in each case. There really ought to be a check that
      // there are some here for safety.

      Object supplier = ((Model.getFacade().getSuppliers(dep).toArray())[0]);
      Object client = ((Model.getFacade().getClients(dep).toArray())[0]);

      // The figs for the two end nodes

      FigNode supplierFN = (FigNode) lay.presentationFor(supplier);
      FigNode clientFN = (FigNode) lay.presentationFor(client);

      // Link the new dependency in to the ends

      depFig.setSourcePortFig(clientFN);
      depFig.setSourceFigNode(clientFN);

      depFig.setDestPortFig(supplierFN);
      depFig.setDestFigNode(supplierFN);

      newEdge = depFig;
    } else if (edge instanceof CommentEdge) {
      newEdge = new FigEdgeNote(edge, lay);
    }

    if (newEdge == null) {
      throw new IllegalArgumentException(
          "Don't know how to create FigEdge for model type " + edge.getClass().getName());
    } else {
      setPorts(lay, newEdge);
    }

    lay.add(newEdge);
    newEdge.setDiElement(GraphChangeAdapter.getInstance().createElement(gm, edge));

    return newEdge;
  }