public void act(BucketbotBase self) {

      // make sure bucketbot is in vacinity of station, otherwise go there
      if (self.getDistance(station.getX(), station.getY())
          > SimulationWorldSimpleExample.getSimulationWorld().getMap().getTolerance()) {
        stateQueue.add(0, new BucketbotMove(station.getX(), station.getY()));
        return;
      }

      // if it's the first time, request the letters be taken
      if (!requested_letters_take) {
        station.requestLetterTake(self, letter, null);
        requested_letters_take = true;
      }

      if (self.getBucket() == null) {
        // something wrong happened... don't have a bucket!
        SimulationWorldSimpleExample.getSimulationWorld()
            .bucketbotManager
            .taskAborted(self, getCurrentTask());
        stateQueue.remove(0);
        if (stateQueue.size() > 0) stateQueue.get(0).act(self);
        return;
      }

      // see if letter has been taken from the bucket
      if (!self.getBucket().containsLetter(letter)) {
        stateQueue.remove(0);
        if (stateQueue.size() > 0) stateQueue.get(0).act(self);
        return;
      }
    }
  /* (non-Javadoc)
   * @see alphabetsoup.framework.Updateable#update(double, double)
   */
  public void update(double last_time, double cur_time) {
    curTime = cur_time;

    WordList wl = SimulationWorldMarketTaskAllocation.getSimulationWorld().getWordList();
    LetterManager lm =
        ((LetterManager)
            ((SimulationWorldMarketTaskAllocation)
                    SimulationWorldMarketTaskAllocation.getSimulationWorld())
                .letterManager);

    // see if all done
    if (wl.getAvailableWords().size() == 0) return;

    // see if have all the words on the market,
    // if not, add them
    if (wordMarket.size() < wl.getAvailableWords().size()) {
      for (Word w : wl.getAvailableWords())
        if (!wordMarket.containsKey(w)) addNewWordToWordMarket(w);
    }

    // check every word station to see if it's in need of a new word
    for (WordStation ws :
        SimulationWorldMarketTaskAllocation.getSimulationWorld().getWordStations()) {
      // give the station words if it needs them and is currently winning it
      // if a word station is winning more than one, then choose the one
      // that has the largest bid-ask spread, that is, the one that it can do most efficiently
      if (ws.getAssignedWords().size() < ws.getCapacity()) {

        // of all words, see if this word station is currently winning any auctions
        // and if so, choose the one that takes the least cost
        int best_word_index = -1;
        float largest_spread = 0.0f;
        WordStationAgent wsa = (WordStationAgent) ws;
        for (int word_index = 0; word_index < wl.getAvailableWords().size(); word_index++) {
          Word w = wl.getAvailableWords().get(word_index);
          DoubleAuction<Word, WordStationAgent, WordOrderManager> market = wordMarket.get(w);

          // only look at winning results
          if (!market.isSellerInTradingSet(wsa)) continue;

          // if the profit for this word is best, then use it
          float spread = market.getAskPrice() - market.getBidPrice();
          if (spread > largest_spread) {
            largest_spread = spread;
            best_word_index = word_index;
          }
        }

        // this word station wasn't winning anything
        if (best_word_index == -1) continue;

        // a word exchange is taking place!
        Word w = wl.takeAvailableWord(best_word_index);
        // make a market for the new word that came in by taking a word
        if (wl.getAvailableWords().size() > 0)
          addNewWordToWordMarket(wl.getAvailableWords().get(wl.getAvailableWords().size() - 1));

        // get exchange, and then get rid of the market for that word
        Exchange e = wordMarket.get(w).acceptNextSellerExchange(wsa);
        wordMarket.remove(w);

        // assign the word
        wsa.assignWord(w);
        wsa.setProfit(wsa.getProfit() + e.value);

        setProfit(getProfit() - e.value);

        // let other things know that the word has been assigned
        lm.newWordAssignedToStation(ws, w);
      }

      // can't continue if out of words
      if (wl.getAvailableWords().size() == 0) return;
    }
  }