public Server(
      int port,
      IServiceLayer serviceLayer,
      Set<ConfiguredServer> configuredServers,
      boolean isWhiteListed,
      int maximumThreads) {

    if (configuredServers == null) {

      throw new IllegalArgumentException("The configuredServers argument is invalid (null).");
    }

    this.isServerRunning = true;
    this.threads = new LinkedList<Connection>();

    // Properties
    this.port = port;
    this.configuredServers = configuredServers;
    this.maximumThreads = maximumThreads;
    this.handshakeTimeOutInMilliseconds = 1000;
    this.frameTimeOutToleranceInMilliseconds = 3000;
    this.maximumFragmentationSize = 2;
    this.checkOrigin = true;
    this.pingable = true;
    this.serviceLayer = serviceLayer;

    if (isWhiteListed) {
      this.whitelist = new HashSet<String>();
      if (!loadWhiteList()) {
        // TODO: Create the white-list.txt and bail.
        Logger.severe("The white-list was not found...");
      }
    }

    // Let the user know that they have not configured any servers in the config.yml.
    if (this.configuredServers.size() == 0) {

      Logger.info(
          "Warning: Either no servers have been configured in the config.yml to communicate with the bridge or all servers are set to restricted access.");
    }
  }
  /** Attempts to load the white-list. */
  private boolean loadWhiteList() {

    File whitelistFile = new File(Globals.PLUGIN_FOLDER + "/" + Globals.WHITE_LIST_FILENAME);

    if (whitelistFile.exists()) {
      BufferedReader br = null;
      try {

        // --- CR (10-14/12) --- Removed the try-with-resources block to support backwards
        // compatibility.
        // try (BufferedReader br = new BufferedReader(new FileReader(whitelistFile)))
        br = new BufferedReader(new FileReader(whitelistFile));
        if (br != null) {
          String domain;
          while ((domain = br.readLine()) != null) {
            if (domain != "") {
              this.whitelist.add(domain.toUpperCase());
            }
          }
        }

        br.close();

        return true;
      } catch (FileNotFoundException fnfe) {
      } catch (IOException io) {
      } finally {
        try {
          br.close();
        } catch (IOException io) {

        }
      }
    } else {
      // The white-list was not found so create it.
      try {
        whitelistFile.createNewFile();
      } catch (IOException io) {
        Logger.debug(
            MessageFormat.format(
                "Cannot create \"{0}/{1}\".", Globals.PLUGIN_FOLDER, Globals.WHITE_LIST_FILENAME));
      }
    }
    // END OF if(whitelistFile.exists())...

    return false;
  }
  /** Begin running the websocket server. */
  @Override
  public void run() {

    try {

      Logger.info(
          MessageFormat.format("WebSocketServerBridge listening on port {0}...", this.port));

      serverSocket = new ServerSocket(this.port);

      // Waiting for the server socket to close or until the server is shutdown manually.
      while ((this.isServerRunning) && (!serverSocket.isClosed())) {

        // Wait for incoming connections.
        Socket socket = serverSocket.accept();

        // Try to reclaim any threads if we are exceeding our maximum.
        // TimeComplexity: O(n) -- Where n is the number of threads valid or invalid.
        // NOTE: Minimal unit testing has been done here...more testing is required.
        if (threads.size() + 1 > this.getMaximumThreads()) {
          for (int i = 0; i < threads.size(); i++) {
            if (!threads.get(i).isAlive()) {
              threads.remove(i);
            }
          }
        }

        // Make sure we have enough threads before accepting.
        // NOTE: Minimal unit testing has been done here...more testing is required.
        if ((threads.size() + 1) <= this.getMaximumThreads()) {

          Connection t = new Connection(socket, this.serviceLayer, this);
          t.start();
          threads.add(t);

        } else {
          Logger.debug("The server has reached its thread maximum...");
        }
      }
      // END OF while ( (this.isServerRunning) && (!serverSocket.isClosed()) )...

      Logger.info("WebSocket server stopping...");

    } catch (IOException ioException) {

      // --- CR (8/10/13) --- Only log the event if the server is still running.  This should
      // prevent an error message from appearing when the server is restarted.
      if (this.isServerRunning) {

        Logger.info(
            MessageFormat.format("The port {0} could not be opened for WebSockets.", this.port));
        Logger.debug(ioException.getMessage());
      }

      // Close all threads.
      // TimeComplexity: O(n) -- Where n is the number of threads valid or invalid.
      for (Connection t : threads) {
        if (t.isAlive()) {
          t.close();
        }
      }
    }
  }