// prevent instantiation by others
  private ApplicationLogic() {
    if (analyticsServer == null) analyticsServer = AuctionServerMain.getAnalyticsServer();

    if (billingServer == null) {
      billingServer = AuctionServerMain.getBillingServer();
      try {
        billingServer.login("auctionserver", "auctionserver");
      } catch (RemoteException e) {
        log.error("could not login on billingserver, billing users will not work!!!");
      }
    }
  }
  /**
   * Ends the given auction and sends the notifications
   *
   * @param auction
   */
  public synchronized void endAuction(Auction auction) {
    if (null != AuctionManager.getInstance().getAuctionById(auction.getId())) {
      AuctionManager.getInstance().removeAuction(auction);

      try {
        Bid highestBid = auction.getHighestBid();
        if (highestBid != null) {
          try {
            billingServer.billAuction(
                auction.getCreator().getUsername(),
                auction.getId(),
                auction.getHighestBid().getAmount());
          } catch (RemoteException e) {
            log.warn("could not bill auction: " + e.getMessage());
          }
        }

        analyticsServer.processEvent(AuctionEvent.createAuctionEnded(auction.getId()));

        List<StatisticEvent> events;

        if (highestBid != null) {
          analyticsServer.processEvent(
              BidEvent.createBidWonEvent(
                  highestBid.getBidder().getUsername(),
                  highestBid.getAuction().getId(),
                  highestBid.getAmount()));

          // create successful auction_ended events
          events = StatisticEvent.createEventsOnAuctionEnded((long) auction.getDuration(), true);
        } else {
          // unsuccessful auction_ended events, because no bid
          events = StatisticEvent.createEventsOnAuctionEnded((long) auction.getDuration(), false);
        }

        for (StatisticEvent e : events) analyticsServer.processEvent(e);

      } catch (RemoteException e) {
        log.warn("could not process event: " + e.getMessage());
      }

      notifyAuctionEnded(auction);
    }
  }