/**
   * Execute the filter model on each input array element until it gets as many elements as
   * specified by the <i>maxOutputLength</i> parameter. If there are no enough elements satisfying
   * the filter model, then only output all the satisfied elements. Before running the filter model,
   * this method update the filter model's <i>inputArrayElement</i> parameter for each array
   * element. After running the filter model, this method looks for the <i>evaluatedValue</i>
   * parameter and keep the input element if the evaluated value is ture, otherwise, skip the
   * element.
   *
   * @exception IllegalActionException If there is no director, or if the director's action methods
   *     throw it.
   */
  public void fire() throws IllegalActionException {
    super.fire();

    if (_model instanceof CompositeActor) {
      CompositeActor executable = (CompositeActor) _model;

      _manager = executable.getManager();

      if (_manager == null) {
        throw new InternalErrorException("No manager!");
      }

      if (_debugging) {
        _manager.addDebugListener(this);

        Director director = executable.getDirector();

        if (director != null) {
          director.addDebugListener(this);
        }
      } else {
        _manager.removeDebugListener(this);

        Director director = executable.getDirector();

        if (director != null) {
          director.removeDebugListener(this);
        }
      }

      int i = 0;
      int j = 0;
      LinkedList list = new LinkedList();
      ArrayToken array = (ArrayToken) inputArray.get(0);

      while ((i < _outputLength) && (j < array.length())) {
        Token t = array.getElement(j);
        _updateParameter(t);

        if (_debugging) {
          _debug("** Executing filter model.");
        }

        try {
          _manager.execute();
        } catch (KernelException ex) {
          throw new IllegalActionException(this, ex, "Execution failed.");
        }

        if (_getResult()) {
          i++;
          list.add(t);
        }

        j++;
      }

      Token[] result = new Token[list.size()];

      for (i = 0; i < list.size(); i++) {
        result[i] = (Token) list.get(i);
      }

      outputArray.send(0, new ArrayToken(array.getElementType(), result));
    }
  }