/*
 * Copyright (c) 2010-2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Christian W. Damus (CEA LIST) - bug 399306
 */
package org.eclipse.emf.internal.cdo.session;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.lob.CDOLob;
import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.security.CDOPermission;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSession.ExceptionHandler;
import org.eclipse.emf.cdo.session.remote.CDORemoteSession;
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
import org.eclipse.emf.cdo.spi.common.CDORawReplicationContext;
import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import org.eclipse.net4j.util.concurrent.IExecutorServiceProvider;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.OMMonitor;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.spi.cdo.AbstractQueryIterator;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDORemoteSessionManager;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction.InternalCDOCommitContext;
import org.eclipse.emf.spi.cdo.InternalCDOXATransaction.InternalCDOXACommitContext;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;

/**
 * @author Eike Stepper
 */
public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionProtocol, IExecutorServiceProvider
{
  private CDOSessionProtocol delegate;

  private ExceptionHandler exceptionHandler;

  @ExcludeFromDump
  private IListener delegateListener = new LifecycleEventAdapter()
  {
    @Override
    protected void onDeactivated(ILifecycle lifecycle)
    {
      DelegatingSessionProtocol.this.deactivate();
    }
  };

  public DelegatingSessionProtocol(CDOSessionProtocol delegate, ExceptionHandler handler)
  {
    this.delegate = delegate;
    exceptionHandler = handler;
    activate();
  }

  public CDOSessionProtocol getDelegate()
  {
    return delegate;
  }

  public void setDelegate(CDOSessionProtocol delegate)
  {
    if (delegate != null)
    {
      unhookDelegate();
      if (LifecycleUtil.isActive(this.delegate))
      {
        LifecycleUtil.deactivate(this.delegate);
      }
    }

    this.delegate = delegate;
    hookDelegate();
  }

  public CDOSession getSession()
  {
    return (CDOSession)delegate.getSession();
  }

  public ExecutorService getExecutorService()
  {
    return ConcurrencyUtil.getExecutorService(delegate);
  }

  public boolean cancelQuery(int queryId)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.cancelQuery(queryId);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void changeSubscription(int viewID, List<CDOID> ids, boolean subscribeMode, boolean clear)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.changeSubscription(viewID, ids, subscribeMode, clear);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void openView(int viewID, boolean readOnly, CDOBranchPoint branchPoint)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.openView(viewID, readOnly, branchPoint);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CDOBranchPoint openView(int viewID, boolean readOnly, String durableLockingID)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.openView(viewID, readOnly, durableLockingID);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void switchTarget(int viewID, CDOBranchPoint branchPoint, List<InternalCDOObject> invalidObjects,
      List<CDORevisionKey> allChangedObjects, List<CDOIDAndVersion> allDetachedObjects, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.switchTarget(viewID, branchPoint, invalidObjects, allChangedObjects, allDetachedObjects, monitor);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void closeView(int viewID)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        if (delegate != null)
        {
          delegate.closeView(viewID);
        }

        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public List<byte[]> queryLobs(Set<byte[]> ids)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.queryLobs(ids);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void loadLob(CDOLobInfo info, Object outputStreamOrWriter)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.loadLob(info, outputStreamOrWriter);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
      CDORevisionHandler handler)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.handleRevisions(eClass, branch, exactBranch, timeStamp, exactTime, handler);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Deprecated
  public CommitTransactionResult commitTransaction(int transactionID, String comment, boolean releaseLocks,
      CDOIDProvider idProvider, CDOCommitData commitData, Collection<CDOLob<?>> lobs, OMMonitor monitor)
  {
    throw new UnsupportedOperationException();
  }

  public CommitTransactionResult commitTransaction(InternalCDOCommitContext context, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.commitTransaction(context, monitor);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Deprecated
  public CommitTransactionResult commitDelegation(CDOBranch branch, String userID, String comment,
      CDOCommitData commitData, Map<CDOID, EClass> detachedObjectTypes, Collection<CDOLob<?>> lobs, OMMonitor monitor)
  {
    throw new UnsupportedOperationException();
  }

  public CommitTransactionResult commitDelegation(InternalCDOCommitContext context, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.commitDelegation(context, monitor);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CommitTransactionResult commitXATransactionCancel(InternalCDOXACommitContext xaContext, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.commitXATransactionCancel(xaContext, monitor);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CommitTransactionResult commitXATransactionPhase1(InternalCDOXACommitContext xaContext, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.commitXATransactionPhase1(xaContext, monitor);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CommitTransactionResult commitXATransactionPhase2(InternalCDOXACommitContext xaContext, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.commitXATransactionPhase2(xaContext, monitor);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CommitTransactionResult commitXATransactionPhase3(InternalCDOXACommitContext xaContext, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.commitXATransactionPhase3(xaContext, monitor);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public RepositoryTimeResult getRepositoryTime()
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.getRepositoryTime();
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void openedSession()
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.openedSession();
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Deprecated
  public CDOLockState[] getLockStates(int viewID, Collection<CDOID> ids)
  {
    return getLockStates(viewID, ids, CDOLockState.DEPTH_NONE);
  }

  public CDOLockState[] getLockStates(int viewID, Collection<CDOID> ids, int depth)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.getLockStates(viewID, ids, depth);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void enableLockNotifications(int viewID, boolean enable)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.enableLockNotifications(viewID, enable);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public boolean isObjectLocked(CDOView view, CDOObject object, LockType lockType, boolean byOthers)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.isObjectLocked(view, object, lockType, byOthers);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public String changeLockArea(CDOView view, boolean create)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.changeLockArea(view, create);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadPackages(packageUnit);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.createBranch(branchID, branchInfo);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public BranchInfo loadBranch(int branchID)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadBranch(branchID);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public SubBranchInfo[] loadSubBranches(int branchID)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadSubBranches(branchID);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadBranches(startID, endID, branchHandler);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Deprecated
  public void deleteBranch(int branchID)
  {
    throw new UnsupportedOperationException();
  }

  @Deprecated
  public void renameBranch(int branchID, String newName)
  {
    throw new UnsupportedOperationException();
  }

  public void renameBranch(int branchID, String oldName, String newName)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.renameBranch(branchID, oldName, newName);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.loadCommitInfos(branch, startTime, endTime, handler);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CDOCommitData loadCommitData(long timeStamp)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadCommitData(timeStamp);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex,
      int fromIndex, int toIndex)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadChunk(revision, feature, accessIndex, fetchIndex, fromIndex, toIndex);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public List<RevisionInfo> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint, int referenceChunk,
      int prefetchDepth)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadRevisions(infos, branchPoint, referenceChunk, prefetchDepth);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadRevisionByVersion(id, branchVersion, referenceChunk);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CDOBranchPointRange loadObjectLifetime(CDOID id, CDOBranchPoint branchPoint)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadObjectLifetime(id, branchPoint);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Deprecated
  public LockObjectsResult lockObjects(List<InternalCDORevision> viewedRevisions, int viewID, CDOBranch viewedBranch,
      LockType lockType, long timeout) throws InterruptedException
  {
    throw new UnsupportedOperationException();
  }

  /**
   * @since 4.1
   */
  public LockObjectsResult lockObjects2(List<CDORevisionKey> revisionKeys, int viewID, CDOBranch viewedBranch,
      LockType lockType, boolean recursive, long timeout) throws InterruptedException

  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.lockObjects2(revisionKeys, viewID, viewedBranch, lockType, recursive, timeout);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public LockObjectsResult delegateLockObjects(String lockAreaID, List<CDORevisionKey> revisionKeys,
      CDOBranch viewedBranch, LockType lockType, boolean recursive, long timeout) throws InterruptedException
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.delegateLockObjects(lockAreaID, revisionKeys, viewedBranch, lockType, recursive, timeout);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public UnlockObjectsResult delegateUnlockObjects(String lockAreaID, Collection<CDOID> objectIDs, LockType lockType,
      boolean recursive)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.delegateUnlockObjects(lockAreaID, objectIDs, lockType, recursive);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void query(CDOView view, AbstractQueryIterator<?> queryResult)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.query(view, queryResult);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void disablePassiveUpdate()
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.disablePassiveUpdate();
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void setPassiveUpdateMode(PassiveUpdateMode mode)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.setPassiveUpdateMode(mode);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void setLockNotificationMode(LockNotificationMode mode)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.setLockNotificationMode(mode);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public RefreshSessionResult refresh(long lastUpdateTime,
      Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions, int initialChunkSize,
      boolean enablePassiveUpdates)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.refresh(lastUpdateTime, viewedRevisions, initialChunkSize, enablePassiveUpdates);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Deprecated
  public void unlockObjects(CDOView view, Collection<CDOID> objectIDs, LockType lockType)
  {
    throw new UnsupportedOperationException();
  }

  public UnlockObjectsResult unlockObjects2(CDOView view, Collection<CDOID> objectIDs, LockType lockType,
      boolean recursive)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.unlockObjects2(view, objectIDs, lockType, recursive);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.getRemoteSessions(manager, subscribe);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, List<CDORemoteSession> recipients)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.sendRemoteMessage(message, recipients);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public boolean unsubscribeRemoteSessions()
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.unsubscribeRemoteSessions();
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void replicateRepository(CDOReplicationContext context, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.replicateRepository(context, monitor);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void replicateRepositoryRaw(CDORawReplicationContext context, OMMonitor monitor)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.replicateRepositoryRaw(context, monitor);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public CDOChangeSetData[] loadChangeSets(CDOBranchPointRange... ranges)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadChangeSets(ranges);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public Set<CDOID> loadMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadMergeData(targetInfo, sourceInfo, targetBaseInfo, sourceBaseInfo);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public Map<CDORevision, CDOPermission> loadPermissions(InternalCDORevision[] revisions)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        return delegate.loadPermissions(revisions);
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void requestChangeCredentials()
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.requestChangeCredentials();
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  public void requestResetCredentials(String userID)
  {
    int attempt = 0;
    for (;;)
    {
      try
      {
        delegate.requestResetCredentials(userID);
        return;
      }
      catch (Exception ex)
      {
        handleException(++attempt, ex);
      }
    }
  }

  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();
    hookDelegate();
  }

  private void hookDelegate()
  {
    EventUtil.addListener(delegate, delegateListener);
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    unhookDelegate();
    LifecycleUtil.deactivate(delegate);
    delegate = null;
    super.doDeactivate();
  }

  private void unhookDelegate()
  {
    EventUtil.removeListener(delegate, delegateListener);
  }

  private void handleException(int attempt, Exception exception)
  {
    try
    {
      exceptionHandler.handleException(getSession(), attempt, exception);
    }
    catch (Exception ex)
    {
      throw WrappedException.wrap(ex);
    }
  }
}
