/*
   * (non-Javadoc)
   *
   * @see de.parsemis.strategy.Strategy#search(de.parsemis.miner.Algorithm,
   *      int)
   */
  public Collection<Fragment<NodeType, EdgeType>> search(final Algorithm<NodeType, EdgeType> algo) {
    final String filename = LocalEnvironment.env(this).objectFileName;

    final MiningStack<NodeType, EdgeType> mine =
        new LocalStack<NodeType, EdgeType>(0, this, LocalEnvironment.env(this));
    for (final Iterator<SearchLatticeNode<NodeType, EdgeType>> it = algo.initialNodes();
        it.hasNext(); ) {
      mine.push(it.next());
    }

    // initialize worker for the current thread
    answers[0] =
        (filename != null
            ? new FileSerializeCollection<Fragment<NodeType, EdgeType>>(filename)
            : new ArrayList<Fragment<NodeType, EdgeType>>());
    final Worker<NodeType, EdgeType> me =
        new Worker<NodeType, EdgeType>(mine, answers[0], algo.getExtender(0), 0);

    // initialize worker for further threads
    for (int i = 1; i < answers.length; ++i) {
      answers[i] =
          (filename != null
              ? new FileSerializeCollection<Fragment<NodeType, EdgeType>>(filename + "_" + i)
              : new HashSet<Fragment<NodeType, EdgeType>>());
      threads[i] = new SMPThread<NodeType, EdgeType>(i, algo, this, answers[i]);
    }

    // start other workers
    if (INFO) {
      stats.distributedTime -= System.currentTimeMillis();
    }
    for (int i = 1; i < answers.length; ++i) {
      threads[i].start();
    }

    // start local worker
    me.run();

    // wait for others
    for (int i = 1; i < answers.length; ++i) {
      try {
        threads[i].join();
      } catch (final InterruptedException ie) {
        if (WARN) {
          err.println(ie);
        }
      }
    }
    if (INFO) {
      stats.distributedTime += System.currentTimeMillis();
    }

    // collect data
    for (int i = 1; i < answers.length; ++i) {
      answers[0].addAll(answers[i]);
    }

    return answers[0];
  }
 /*
  * (non-Javadoc)
  *
  * @see de.parsemis.general.StackList#split(de.parsemis.general.MiningStack)
  */
 public synchronized boolean split(final MiningStack<NodeType, EdgeType> empty) {
   if (INFO) {
     stats.splitTime -= System.currentTimeMillis();
   }
   for (ListItem<MiningStack<NodeType, EdgeType>> ack = this.next; ack != this; ack = ack.next) {
     if (ack.elem.split(empty)) {
       _remove(ack);
       _add(ack);
       if (INFO) {
         stats.splitTime += System.currentTimeMillis();
       }
       return true;
     }
   }
   if (INFO) {
     stats.splitTime += System.currentTimeMillis();
   }
   return false;
 }