/**
   * Update the Flash animation. This generates the flash code and writes it to the temporary file.
   */
  public void update(View view) {

    // Create a new network.
    Network network = null;
    Module module = null;
    if (view.getElement() instanceof Connector) {
      Connector connector = (Connector) view.getElement();
      network = new Network(connector);
      module = connector.getModule();
    }
    if (view.getElement() instanceof Component) {
      Component component = (Component) view.getElement();
      network = new Network(component);
      module = component.getModule();
    }

    if (module == null || network == null) {
      return; // Abort.
    }

    // Module scope?
    if (ReoPreferences.useModuleScope()) {
      network = new Network(module);
    }

    // Check if all component ends are connected.
    for (Component component : network.getAllComponents()) {
      for (PrimitiveEnd end : component.getAllEnds()) {
        if (end.getNode() == null) return; // Abort.
      }
    }

    // Do the actual job.
    update(network, null);
  }
  /**
   * Compute the animation table for a connector.
   *
   * @param connector Connector.
   * @param engine Colouring engine.
   * @param cache Colouring cache.
   * @param monitor Monitor.
   * @return The compiled animation table.
   */
  public static AnimationTable computeAnimations(
      Connector connector, ColouringEngine engine, ColouringCache cache, IProgressMonitor monitor) {

    List<Colourable> elements = new ArrayList<Colourable>();
    elements.addAll(connector.getPrimitives());
    elements.addAll(connector.getNodes());

    List<Connectable> border = new ArrayList<Connectable>();
    border.addAll(connector.getForeignPrimitives());
    border.addAll(connector.getForeignNodes());

    return computeAnimations(elements, border, engine, cache, monitor);
  }
  @Override
  public Pair<Node, Node> transform(Connector connector) {
    Node bNode = new Node("b " + flowName);
    sNode = new Node("start " + flowName);
    eNode = new Node("end " + flowName);
    Node mNode = new Node("mid " + flowName);
    connector.getNodes().add(sNode);
    connector.getNodes().add(eNode);
    connector.getNodes().add(bNode);
    connector.getNodes().add(mNode);

    Channel s2b = new FIFO(sNode, bNode);
    connector.getPrimitives().add(s2b);

    Channel b2m = new SyncDrain(bNode, mNode);
    connector.getPrimitives().add(b2m);

    Channel m2e = new Sync(eNode, mNode);
    connector.getPrimitives().add(m2e);

    Node lst = null;
    for (Pair<Node, Node> pair : list) {
      Channel s2smid = new FIFO(sNode, pair.getFirst());
      connector.getPrimitives().add(s2smid);
      Node xNode = new Node("x");
      connector.getNodes().add(xNode);
      Channel emid2x = new FIFO(pair.getSecond(), xNode);
      connector.getPrimitives().add(emid2x);
      // Channel x2e = new Sync(xNode, eNode);
      // connector.getPrimitives().add(x2e);
      if (lst != null) {
        Channel chl = new SyncDrain(lst, xNode);
        connector.getPrimitives().add(chl);
      } else {
        ///////////////////// ?????????????		Channel x2m = new Sync(xNode, mNode);
        /////////// connector.getPrimitives().add(x2m);
      }
      lst = xNode;
    }
    Channel lst2e = new Sync(lst, eNode);
    connector.getPrimitives().add(lst2e);

    Activator.logger.log(
        Level.INFO, "Transforming: Flow instance named '" + flowName + "' transformed.");
    return new Pair<Node, Node>(sNode, eNode);
  }
  /**
   * Call-back function that is needed to determine the root view. In this case we want connector
   * nodes as root.
   */
  public boolean isValidRoot(View view) {

    Connector connector = null;
    Component component = null;

    if (view.getElement() instanceof Connector) {
      connector = (Connector) view.getElement();
    }

    if (view.getElement() instanceof Component) {
      component = (Component) view.getElement();
    }

    // Only top-level connectors / components.
    if (connector != null && !connector.isSubConnector()) return true;
    if (component != null && !component.isInternal()) return true;

    return false;
  }