/**
   * "Helper routine to add a bundle at the indicated position." [DTN2]
   *
   * @throws BundleLockNotHeldByCurrentThread
   * @throws InterruptedException
   */
  private void add_bundle(final Bundle b, final int pos)
      throws BundleListLockNotHoldByCurrentThread, BundleLockNotHeldByCurrentThread,
          InterruptedException {
    if (!lock_.isHeldByCurrentThread()) throw new BundleListLockNotHoldByCurrentThread();
    if (!b.get_lock().isHeldByCurrentThread()) throw new BundleLockNotHeldByCurrentThread();

    if (b.is_queued_on(this)) {
      Log.e(
          TAG,
          String.format(
              "ERROR in add bundle: " + "bundle id %d already on list [%s]", b.bundleid(), name_));

      return;
    }

    list_.add(pos, b);

    b.mappings().add(this);

    Log.d(
        TAG,
        String.format(
            "bundle id %d is added to list [%s] , the size become",
            b.bundleid(), name_, list_.size()));
  }
  /**
   * 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();
    }
  }