/**
   * Remove the given bundle from the list. Returns true if the bundle was successfully removed,
   * false otherwise.
   *
   * @param free whether to free the bundle. This freeing will remove Bundle from storage including
   *     its payload
   */
  public boolean erase(Bundle bundle, boolean free) {
    if (bundle == null) {
      return false;
    }
    lock_.lock();

    // "Now we need to take the bundle lock in order to search through
    // its mappings" [DTN2]
    bundle.get_lock().lock();

    try {
      int pos = list_.indexOf(bundle);
      if (pos == -1) return false;

      Bundle b = del_bundle(pos, free);
      assert (b == bundle);

      return true;

    } catch (BundleListLockNotHoldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
      return false;
    } finally {
      bundle.get_lock().unlock();
      lock_.unlock();
    }
  }
  /**
   * Remove (and return) the last bundle on the list.
   *
   * @param free whether to free the bundle. This freeing will remove Bundle from storage including
   *     its payload
   */
  public Bundle pop_back(boolean free) {
    lock_.lock();
    try {
      if (list_.isEmpty()) return null;

      Bundle ret = del_bundle(list_.size() - 1, free);

      return ret;
    } catch (BundleListLockNotHoldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
      return null;
    } finally {
      lock_.unlock();
    }
  }
  /** "As a testing hook, insert the given bundle into a random location in the list." [DTN2] */
  public void insert_random(Bundle bundle) {

    lock_.lock();
    int s = 222;
    if (!lock_.isHeldByCurrentThread()) s = 1;
    try {
      int random_position = (int) (Math.random() * this.size());
      add_bundle(bundle, random_position);
    } catch (BundleLockNotHeldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
    } catch (InterruptedException e) {
      Log.e(TAG, e.getMessage());
    } catch (BundleListLockNotHoldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
    } finally {
      lock_.unlock();
    }
  }
  /** Add a new bundle to the front of the list. */
  public boolean push_front(Bundle bundle) {

    lock_.lock();
    bundle.get_lock().lock();
    try {
      add_bundle(bundle, 0);
      return true;
    } catch (BundleLockNotHeldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
    } catch (InterruptedException e) {
      Log.e(TAG, e.getMessage());
    } catch (BundleListLockNotHoldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
    } finally {
      bundle.get_lock().unlock();
      lock_.unlock();
    }
    return true;
  }
 /** Insert the given bundle sorted by the given sort method. */
 public boolean insert_sorted(Bundle bundle, Comparator<Bundle> sort_comparator) {
   lock_.lock();
   bundle.get_lock().lock();
   try {
     add_bundle(bundle, list_.size());
     Collections.sort(this.list_, sort_comparator);
     return true;
   } catch (BundleLockNotHeldByCurrentThread e) {
     Log.e(TAG, e.getMessage());
     return false;
   } catch (InterruptedException e) {
     Log.e(TAG, e.getMessage());
     return false;
   } catch (BundleListLockNotHoldByCurrentThread e) {
     Log.e(TAG, e.getMessage());
     return false;
   } finally {
     bundle.get_lock().unlock();
     lock_.unlock();
   }
 }