% Version: $Revision: 6177 $

\begin{verbatim}
import weka.core.*;
import weka.core.Capabilities.*;
import java.util.Random;

public class BatchFilter3 extends Filter {

  protected int m_Seed;
  protected Random m_Random;

  public String globalInfo() {
    return   "A batch filter that adds an attribute 'blah' at the end "
           + "containing a random number. The output format cannot be collected "
           + "immediately.";
  }

  public Capabilities getCapabilities() {
    Capabilities result = super.getCapabilities();
    result.enableAllAttributes();
    result.enableAllClasses();
    result.enable(Capability.NO_CLASS);  // filter doesn't need class to be set
    return result;
  }

  public boolean input(Instance instance) throws Exception {
    if (getInputFormat() = null)
      throw new NullPointerException("No input instance format defined");
    if (isNewBatch()) {
      resetQueue();
      m_NewBatch = false;
    }
    if (isFirstBatchDone())
      convertInstance(instance);
    else
      bufferInput(instance);
    return isFirstBatchDone();
  }

  public boolean batchFinished() throws Exception {
    if (getInputFormat() = null)
      throw new NullPointerException("No input instance format defined");
    // output format still needs to be set (random number generator is seeded
    // with number of instances of first batch)
    if (!isFirstBatchDone()) {
      m_Seed = getInputFormat().numInstances();
      Instances outFormat = new Instances(getInputFormat(), 0);
      outFormat.insertAttributeAt(new Attribute(
          "blah-" + getInputFormat().numInstances()), outFormat.numAttributes());
      setOutputFormat(outFormat);
    }
    Instances inst = getInputFormat();
    for (int i = 0; i < inst.numInstances(); i++) {
      convertInstance(inst.instance(i));
    }
    flushInput();
    m_NewBatch = true;
    m_FirstBatchDone = true;
    m_Random = null;
    return (numPendingOutput() != 0);
  }

  protected void convertInstance(Instance instance) {
    if (m_Random = null)
      m_Random = new Random(m_Seed);
    double[] newValues = new double[instance.numAttributes() + 1];
    double[] oldValues = instance.toDoubleArray();
    newValues[newValues.length - 1] = m_Random.nextInt();
    System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
    push(new Instance(1.0, newValues));
  }

  public static void main(String[] args) {
    runFilter(new BatchFilter3(), args);
  }
}
\end{verbatim}
