/**
   * Tries to passivate the instance. If the instance is in use and passivateAfterCommit parameter
   * is true then the instance will passivated after the transaction commits. Otherwise, the
   * instance will be passivated later according to the container's commit option and max age.
   */
  protected void tryToPassivate(EnterpriseContext ctx, boolean passivateAfterCommit) {
    Object id = ctx.getId();
    if (id == null) return;
    BeanLock lock = getContainer().getLockManager().getLock(id);
    boolean lockedBean = false;
    try {
      /* If this is a BeanLockExt only attempt the lock as the call to
      remove is going to have to acquire the cache lock, but this may already
      be held since this method is called by passivation policies without
      the cache lock. This can lead to a deadlock as in the case of a size based
      eviction during a cache get attempts to lock the bean that has been
      locked by an age based background thread as seen in bug 987389 on
      sourceforge.
      */
      if (lock instanceof BeanLockExt) {
        BeanLockExt lock2 = (BeanLockExt) lock;
        lockedBean = lock2.attemptSync();
        if (lockedBean == false) {
          unableToPassivateDueToCtxLock(ctx, passivateAfterCommit);
          return;
        }
      } else {
        // Use the blocking sync
        lock.sync();
        lockedBean = true;
      }

      if (canPassivate(ctx)) {
        try {
          remove(id);
          passivate(ctx);
          freeContext(ctx);
        } catch (Exception ignored) {
          log.warn("failed to passivate, id=" + id, ignored);
        }
      } else {
        // Touch the entry to make it MRU
        synchronized (getCacheLock()) {
          getCache().get(id);
        }

        unableToPassivateDueToCtxLock(ctx, passivateAfterCommit);
      }
    } finally {
      if (lockedBean) lock.releaseSync();
      getContainer().getLockManager().removeLockRef(id);
    }
  }
 protected void unableToPassivateDueToCtxLock(
     EnterpriseContext ctx, boolean passivateAfterCommit) {
   log.warn("Unable to passivate due to ctx lock, id=" + ctx.getId());
 }