/** "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();
   }
 }
  /**
   * Helper routine to remove a bundle from the indicated position. This is called by other public
   * functions such as pop_front This is the function will actually post the bundle free event to
   * the Bundle daemon
   *
   * @param pos Position to delete a flag indicate whether to free the bundle as well
   * @param free whether to free the bundle. This freeing will remove Bundle from storage including
   *     its payload
   * @throws BundleListLockNotHoldByCurrentThread
   * @returns the bundle that, before this call, was at the position
   */
  private Bundle del_bundle(final int pos, boolean free)
      throws BundleListLockNotHoldByCurrentThread {

    Bundle b = list_.get(pos);
    assert (lock_.isHeldByCurrentThread());

    if (!lock_.isHeldByCurrentThread()) throw new BundleListLockNotHoldByCurrentThread();

    b.get_lock().lock();

    try {

      Log.d(
          TAG,
          String.format("bundle id %d del_bundle: deleting mapping [%s]", b.bundleid(), name_));

      if (!b.mappings().contains(this)) {
        Log.e(
            TAG,
            String.format(
                "ERROR in del bundle: " + "bundle id %d has no mapping for list [%s]",
                b.bundleid(), name_));
      } else {
        b.mappings().remove(this);
      }

      // "remove the bundle from the list" [DTN2]
      list_.remove(b);

      if (free) BundleDaemon.getInstance().post(new BundleFreeEvent(b));

      return b;
    } catch (BundleLockNotHeldByCurrentThread e) {
      Log.e(TAG, e.getMessage());
      return null;

    } finally {
      b.get_lock().unlock();
    }
  }