/**
   * Return a Fig that can be used to represent the given node.
   *
   * <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 node The node 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.
   */
  public FigNode getFigNodeFor(GraphModel gm, Layer lay, Object node, Map styleAttributes) {

    FigNodeModelElement figNode = null;

    // Create a new version of the relevant fig

    if (Model.getFacade().isAActor(node)) {
      figNode = new FigActor(gm, node);
    } else if (Model.getFacade().isAUseCase(node)) {
      figNode = new FigUseCase(gm, node);
    } else if (Model.getFacade().isAComment(node)) {
      figNode = new FigComment(gm, node);
    } else if (Model.getFacade().isAPackage(node)) {
      figNode = new FigPackage(gm, node);
    } else {
      LOG.debug(
          this.getClass().toString()
              + ": getFigNodeFor("
              + gm.toString()
              + ", "
              + lay.toString()
              + ", "
              + node.toString()
              + ") - cannot create this sort of node.");
      return null;
      // TODO: Shouldn't we throw an excdeption here?!?!
    }

    lay.add(figNode);
    figNode.setDiElement(GraphChangeAdapter.getInstance().createElement(gm, node));

    return figNode;
  }
  /**
   * 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;
  }