public synchronized void openMarket() throws Exception {
    Price bestBuyPrice = buySide.topOfBookPrice();
    Price bestSellPrice = sellSide.topOfBookPrice();

    if (bestBuyPrice != null && bestSellPrice != null) {
      while (bestBuyPrice.greaterOrEqual(bestSellPrice)
          || bestBuyPrice.isMarket()
          || bestSellPrice.isMarket()) {
        ArrayList<Tradable> topOfBuySide = buySide.getEntriesAtPrice(bestBuyPrice);
        ArrayList<Tradable> toRemove = new ArrayList<Tradable>();
        HashMap<String, FillMessage> allFills = null;

        for (Tradable t : topOfBuySide) {
          allFills = sellSide.tryTrade(t);
          if (t.getRemainingVolume() == 0) {
            toRemove.add(t);
          }
        }

        for (Tradable t : toRemove) {
          buySide.removeTradable(t);
        }
        updateCurrentMarket();

        Price lastSalePrice = this.determineLastSalePrice(allFills);
        int lastSaleVolume = this.determineLastSaleQuantity(allFills);

        LastSalePublisher.getInstance()
            .publishLastSale(productSymbol, lastSalePrice, lastSaleVolume);

        bestBuyPrice = buySide.topOfBookPrice();
        bestSellPrice = sellSide.topOfBookPrice();

        if (bestBuyPrice == null || bestSellPrice == null) break;
      }
    }
  }