public synchronized void removeDataAccessController(DataAccessController controller) {
    List<DataAccessController> oldControllers, newControllers;

    int index = controllers.indexOf(controller);
    if (index >= 0) {
      oldControllers = new ArrayList<DataAccessController>(controllers);
      // get the next available controller's index
      int nextIndex = controllers.size() - 1 > index ? index : index - 1;
      controllers.remove(controller);
      if (foregroundController != null && foregroundController.equals(controller)) {
        setForegroundDataAccessController(nextIndex >= 0 ? controllers.get(nextIndex) : null);
      }
      controller.close();
      newControllers = new ArrayList<DataAccessController>(controllers);

      EventBus.publish(
          new RemoveDataSourceEvent<DataAccessController>(this, oldControllers, newControllers));
    }
  }
  /**
   * Replace one data access controller with another, and retain the position in the
   * DataAccessMonitor.
   *
   * @param original original data access controller
   * @param replacement replacement data access controller
   */
  public synchronized void replaceDataAccessController(
      DataAccessController original, DataAccessController replacement) {
    List<DataAccessController> oldControllers, newControllers;

    int index = controllers.indexOf(original);
    if (index >= 0) {
      oldControllers = new ArrayList<DataAccessController>(controllers);
      controllers.add(index, replacement);
      controllers.remove(original);
      if (foregroundController != null && foregroundController.equals(original)) {
        setForegroundDataAccessController(replacement);
      }
      original.close();
      newControllers = new ArrayList<DataAccessController>(controllers);
      // notify others
      EventBus.publish(
          new AddDataSourceEvent<DataAccessController>(this, oldControllers, newControllers));
    } else {
      // add as a new data access controller
      addDataAccessController(replacement);
    }
  }
 /**
  * Check whether the given data access controller is foreground data access controller
  *
  * @param controller data access controller
  * @return boolean true if it is foreground data access controller
  */
 public synchronized boolean isForegroundDataAccessController(DataAccessController controller) {
   return foregroundController != null && foregroundController.equals(controller);
 }