/***************************************************************************
 * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
 * 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
 *    Simon McDuff - http://bugs.eclipse.org/226778
 *    Simon McDuff - http://bugs.eclipse.org/230832
 *    Simon McDuff - http://bugs.eclipse.org/233490
 *    Simon McDuff - http://bugs.eclipse.org/213402
 *    Victor Roldan Betancort - maintenance
 **************************************************************************/
package org.eclipse.emf.internal.cdo;

import org.eclipse.emf.cdo.CDOCollectionLoadingPolicy;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOSession;
import org.eclipse.emf.cdo.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.CDOTimeStampContext;
import org.eclipse.emf.cdo.CDOView;
import org.eclipse.emf.cdo.CDOSession.Repository;
import org.eclipse.emf.cdo.common.CDODataInput;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.id.CDOIDLibraryDescriptor;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDObject;
import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.id.CDOIDTempMeta;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.util.CDOPackageRegistry;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.protocol.CDOClientProtocol;
import org.eclipse.emf.internal.cdo.protocol.LoadLibrariesRequest;
import org.eclipse.emf.internal.cdo.protocol.OpenSessionRequest;
import org.eclipse.emf.internal.cdo.protocol.OpenSessionResult;
import org.eclipse.emf.internal.cdo.protocol.RepositoryTimeRequest;
import org.eclipse.emf.internal.cdo.protocol.RepositoryTimeResult;
import org.eclipse.emf.internal.cdo.protocol.SetPassiveUpdateRequest;
import org.eclipse.emf.internal.cdo.protocol.SyncRevisionRequest;
import org.eclipse.emf.internal.cdo.util.CDOPackageRegistryImpl;
import org.eclipse.emf.internal.cdo.util.ModelUtil;
import org.eclipse.emf.internal.cdo.util.SessionUtil;

import org.eclipse.net4j.channel.IChannel;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.concurrent.QueueRunner;
import org.eclipse.net4j.util.container.Container;
import org.eclipse.net4j.util.event.Event;
import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.event.Notifier;
import org.eclipse.net4j.util.io.ExtendedDataInput;
import org.eclipse.net4j.util.io.ExtendedDataOutput;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.io.StringCompressor;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.options.IOptions;
import org.eclipse.net4j.util.options.IOptionsContainer;
import org.eclipse.net4j.util.options.OptionsEvent;

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public class CDOSessionImpl extends Container<CDOView> implements InternalCDOSession, Repository
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SESSION, CDOSessionImpl.class);

  private int sessionID;

  private CDOClientProtocol protocol;

  @ExcludeFromDump
  private IListener protocolListener = new LifecycleEventAdapter()
  {
    @Override
    protected void onDeactivated(ILifecycle lifecycle)
    {
      close();
    }
  };

  private String repositoryName;

  private String repositoryUUID;

  private long repositoryCreationTime;

  private RepositoryTimeResult repositoryTimeResult;

  private boolean repositorySupportingAudits;

  private CDOPackageRegistry packageRegistry;

  private CDOSessionPackageManagerImpl packageManager;

  private CDORevisionManagerImpl revisionManager;

  private Set<InternalCDOView> views = new HashSet<InternalCDOView>();

  private QueueRunner invalidationRunner;

  private Object invalidationRunnerLock = new Object();

  @ExcludeFromDump
  private transient Map<CDOID, InternalEObject> idToMetaInstanceMap = new HashMap<CDOID, InternalEObject>();

  @ExcludeFromDump
  private transient Map<InternalEObject, CDOID> metaInstanceToIDMap = new HashMap<InternalEObject, CDOID>();

  @ExcludeFromDump
  private transient int lastViewID;

  @ExcludeFromDump
  private transient int lastTempMetaID;

  @ExcludeFromDump
  private transient StringCompressor packageURICompressor;

  @ExcludeFromDump
  private CDOIDObjectFactory cdoidObjectFactory;

  /**
   * @since 2.0
   */
  protected IOptions options = new OptionsImpl();

  public CDOSessionImpl()
  {
    protocol = new CDOClientProtocol();
    protocol.setInfraStructure(this);

    packageManager = createPackageManager();
    revisionManager = createRevisionManager();
  }

  public int getSessionID()
  {
    return sessionID;
  }

  /**
   * @since 2.0
   */
  public Options options()
  {
    return (Options)options;
  }

  /**
   * @since 2.0
   */
  public Repository repository()
  {
    return this;
  }

  /**
   * @since 2.0
   */
  public String getUserID()
  {
    IChannel channel = protocol.getChannel();
    return channel == null ? null : channel.getUserID();
  }

  public CDOIDObject createCDOIDObject(ExtendedDataInput in)
  {
    return cdoidObjectFactory.createCDOIDObject(in);
  }

  /**
   * @since 2.0
   */
  public CDOIDObject createCDOIDObject(String in)
  {
    return cdoidObjectFactory.createCDOIDObject(in);
  }

  public CDOClientProtocol getProtocol()
  {
    return protocol;
  }

  /**
   * @since 2.0
   */
  public String getName()
  {
    return repositoryName;
  }

  public void setRepositoryName(String repositoryName)
  {
    this.repositoryName = repositoryName;
  }

  /**
   * @since 2.0
   */
  public String getUUID()
  {
    return repositoryUUID;
  }

  /**
   * @since 2.0
   */
  public long getCreationTime()
  {
    checkActive();
    return repositoryCreationTime;
  }

  /**
   * @since 2.0
   */
  public long getCurrentTime()
  {
    return getCurrentTime(false);
  }

  /**
   * @since 2.0
   */
  public long getCurrentTime(boolean forceRefresh)
  {
    checkActive();
    if (repositoryTimeResult == null || forceRefresh)
    {
      repositoryTimeResult = sendRepositoryTimeRequest();
    }

    return repositoryTimeResult.getAproximateRepositoryTime();
  }

  private RepositoryTimeResult sendRepositoryTimeRequest()
  {
    try
    {
      return new RepositoryTimeRequest(protocol).send();
    }
    catch (Exception ex)
    {
      throw WrappedException.wrap(ex);
    }
  }

  /**
   * @since 2.0
   */
  public boolean isSupportingAudits()
  {
    return repositorySupportingAudits;
  }

  public void close()
  {
    deactivate();
  }

  /**
   * @since 2.0
   */
  public boolean isClosed()
  {
    return !isActive();
  }

  /**
   * @since 2.0
   */
  public void setPackageRegistry(CDOPackageRegistry packageRegistry)
  {
    this.packageRegistry = packageRegistry;
  }

  public CDOPackageRegistry getPackageRegistry()
  {
    return packageRegistry;
  }

  public CDOSessionPackageManagerImpl getPackageManager()
  {
    return packageManager;
  }

  public CDORevisionManagerImpl getRevisionManager()
  {
    return revisionManager;
  }

  /**
   * @since 2.0
   */
  public InternalCDOTransaction openTransaction(ResourceSet resourceSet)
  {
    checkActive();
    InternalCDOTransaction transaction = createTransaction();
    initView(transaction, resourceSet);
    return transaction;
  }

  /**
   * @since 2.0
   */
  public InternalCDOTransaction openTransaction()
  {
    return openTransaction(createResourceSet());
  }

  /**
   * @since 2.0
   */
  protected InternalCDOTransaction createTransaction()
  {
    return new CDOTransactionImpl();
  }

  /**
   * @since 2.0
   */
  public InternalCDOView openView(ResourceSet resourceSet)
  {
    checkActive();
    InternalCDOView view = createView();
    initView(view, resourceSet);
    return view;
  }

  /**
   * @since 2.0
   */
  public InternalCDOView openView()
  {
    return openView(createResourceSet());
  }

  /**
   * @since 2.0
   */
  protected InternalCDOView createView()
  {
    return new CDOViewImpl();
  }

  public CDOAuditImpl openAudit(ResourceSet resourceSet, long timeStamp)
  {
    checkActive();
    CDOAuditImpl audit = createAudit(timeStamp);
    initView(audit, resourceSet);
    return audit;
  }

  public CDOAuditImpl openAudit(long timeStamp)
  {
    return openAudit(createResourceSet(), timeStamp);
  }

  /**
   * @since 2.0
   */
  protected CDOAuditImpl createAudit(long timeStamp)
  {
    return new CDOAuditImpl(timeStamp);
  }

  /**
   * @since 2.0
   */
  public void viewDetached(InternalCDOView view)
  {
    // Detach viewset from the view
    view.getViewSet().remove(view);
    synchronized (views)
    {
      if (!views.remove(view))
      {
        return;
      }
    }

    if (isActive())
    {
      try
      {
        LifecycleUtil.deactivate(view);
        // new ViewsChangedRequest(protocol, view.getViewID(), CDOProtocolConstants.VIEW_CLOSED,
        // CDOProtocolView.UNSPECIFIED_DATE).send();
      }
      catch (Exception ex)
      {
        throw WrappedException.wrap(ex);
      }
    }

    fireElementRemovedEvent(view);
  }

  public CDOView getView(int viewID)
  {
    checkActive();
    for (InternalCDOView view : getViews())
    {
      if (view.getViewID() == viewID)
      {
        return view;
      }
    }

    return null;
  }

  /**
   * @since 2.0
   */
  public InternalCDOView[] getViews()
  {
    checkActive();
    synchronized (views)
    {
      return views.toArray(new InternalCDOView[views.size()]);
    }
  }

  public CDOView[] getElements()
  {
    return getViews();
  }

  @Override
  public boolean isEmpty()
  {
    checkActive();
    return views.isEmpty();
  }

  public synchronized CDOIDMetaRange getTempMetaIDRange(int count)
  {
    CDOIDTemp lowerBound = CDOIDUtil.createTempMeta(lastTempMetaID + 1);
    lastTempMetaID += count;
    return CDOIDUtil.createMetaRange(lowerBound, count);
  }

  public InternalEObject lookupMetaInstance(CDOID id)
  {
    InternalEObject metaInstance = idToMetaInstanceMap.get(id);
    if (metaInstance == null)
    {
      CDOPackage[] cdoPackages = packageManager.getPackages();
      for (CDOPackage cdoPackage : cdoPackages)
      {
        CDOIDMetaRange metaIDRange = cdoPackage.getMetaIDRange();
        if (metaIDRange != null && metaIDRange.contains(id))
        {
          EPackage ePackage = ModelUtil.getEPackage(cdoPackage, packageRegistry);
          registerEPackage(ePackage);
          metaInstance = idToMetaInstanceMap.get(id);
          break;
        }
      }
    }

    return metaInstance;
  }

  public CDOID lookupMetaInstanceID(InternalEObject metaInstance)
  {
    return metaInstanceToIDMap.get(metaInstance);
  }

  public void registerEPackage(EPackage ePackage, CDOIDMetaRange metaIDRange)
  {
    if (metaIDRange.isTemporary())
    {
      throw new IllegalArgumentException("metaIDRange.isTemporary()");
    }

    CDOIDMetaRange range = CDOIDUtil.createMetaRange(metaIDRange.getLowerBound(), 0);
    range = SessionUtil
        .registerMetaInstance((InternalEObject)ePackage, range, idToMetaInstanceMap, metaInstanceToIDMap);
    if (range.size() != metaIDRange.size())
    {
      throw new IllegalStateException("range.size() != metaIDRange.size()");
    }
  }

  public CDOIDMetaRange registerEPackage(EPackage ePackage)
  {
    CDOIDMetaRange range = SessionUtil.registerEPackage(ePackage, lastTempMetaID + 1, idToMetaInstanceMap,
        metaInstanceToIDMap);
    lastTempMetaID = ((CDOIDTempMeta)range.getUpperBound()).getIntValue();
    return range;
  }

  public void remapMetaInstance(CDOID oldID, CDOID newID)
  {
    InternalEObject metaInstance = idToMetaInstanceMap.remove(oldID);
    if (metaInstance == null)
    {
      throw new IllegalArgumentException("Unknown meta instance id: " + oldID);
    }

    if (TRACER.isEnabled())
    {
      TRACER.format("Remapping meta instance: {0} --> {1} <-> {2}", oldID, newID, metaInstance);
    }

    idToMetaInstanceMap.put(newID, metaInstance);
    metaInstanceToIDMap.put(metaInstance, newID);
  }

  /**
   * @since 2.0
   */
  public void handleSyncResponse(long timestamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects)
  {
    handleCommitNotification(timestamp, dirtyOIDs, detachedObjects, null, null, true, false);
  }

  /**
   * @since 2.0
   */
  public void handleCommitNotification(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
      final Collection<CDOID> detachedObjects, final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView)
  {
    handleCommitNotification(timeStamp, dirtyOIDs, detachedObjects, deltas, excludedView, options()
        .isPassiveUpdateEnabled(), true);
  }

  private void handleCommitNotification(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
      final Collection<CDOID> detachedObjects, final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView,
      final boolean passiveUpdate, boolean async)
  {
    if (passiveUpdate)
    {
      updateRevisionForRemoteChanges(timeStamp, dirtyOIDs, detachedObjects, excludedView);
    }

    final Set<CDOIDAndVersion> finalDirtyOIDs = Collections.unmodifiableSet(dirtyOIDs);
    final Collection<CDOID> finalDetachedObjects = Collections.unmodifiableCollection(detachedObjects);
    final boolean skipChangeSubscription = (deltas == null || deltas.size() <= 0)
        && (detachedObjects == null || detachedObjects.size() <= 0);

    for (final InternalCDOView view : getViews())
    {
      if (view != excludedView)
      {
        Runnable runnable = new Runnable()
        {
          public void run()
          {
            try
            {
              Set<CDOObject> conflicts = null;
              if (passiveUpdate)
              {
                conflicts = view.handleInvalidation(timeStamp, finalDirtyOIDs, finalDetachedObjects);
              }

              if (!skipChangeSubscription)
              {
                view.handleChangeSubscription(deltas, detachedObjects);
              }

              if (conflicts != null)
              {
                ((InternalCDOTransaction)view).handleConflicts(conflicts);
              }
            }
            catch (RuntimeException ex)
            {
              OM.LOG.error(ex);
            }
          }
        };

        if (async)
        {
          QueueRunner runner = getInvalidationRunner();
          runner.addWork(runnable);
        }
        else
        {
          runnable.run();
        }
      }
    }

    fireInvalidationEvent(timeStamp, dirtyOIDs, detachedObjects, excludedView);
  }

  private void updateRevisionForRemoteChanges(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
      Collection<CDOID> detachedObjects, InternalCDOView excludedView)
  {
    // revised is done automatically when postCommit is CDOTransaction.postCommit is happening
    // Detached are not revised through postCommit
    if (excludedView == null || timeStamp == CDORevision.UNSPECIFIED_DATE)
    {
      for (CDOIDAndVersion dirtyOID : dirtyOIDs)
      {
        CDOID id = dirtyOID.getID();
        int version = dirtyOID.getVersion();
        InternalCDORevision revision = revisionManager.getRevisionByVersion(id, 0, version, false);
        if (timeStamp == CDORevision.UNSPECIFIED_DATE)
        {
          revisionManager.removeCachedRevision(revision.getID(), revision.getVersion());
        }
        else if (revision != null)
        {
          revision.setRevised(timeStamp - 1);
        }
      }
    }

    for (CDOID id : detachedObjects)
    {
      InternalCDORevision revision = revisionManager.getRevision(id, 0, false);
      if (timeStamp == CDORevision.UNSPECIFIED_DATE)
      {
        revisionManager.removeCachedRevision(revision.getID(), revision.getVersion());
      }
      else if (revision != null)
      {
        revision.setRevised(timeStamp - 1);
      }
    }
  }

  private QueueRunner getInvalidationRunner()
  {
    synchronized (invalidationRunnerLock)
    {
      if (invalidationRunner == null)
      {
        invalidationRunner = new QueueRunner();
        invalidationRunner.activate();
      }
    }

    return invalidationRunner;
  }

  /**
   * @since 2.0
   */
  public void fireInvalidationEvent(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
      InternalCDOView excludedView)
  {
    fireEvent(new InvalidationEvent(excludedView, timeStamp, dirtyOIDs, detachedObjects));
  }

  /**
   * @since 2.0
   */
  public void writePackageURI(ExtendedDataOutput out, String uri) throws IOException
  {
    packageURICompressor.write(out, uri);
  }

  /**
   * @since 2.0
   */
  public String readPackageURI(ExtendedDataInput in) throws IOException
  {
    return packageURICompressor.read(in);
  }

  @Override
  public String toString()
  {
    IChannel channel = protocol.getChannel();
    return MessageFormat.format("CDOSession[{0}/{1}]", channel, repositoryName);
  }

  /**
   * @since 2.0
   */
  protected CDOPackageRegistry createPackageRegistry()
  {
    return new CDOPackageRegistryImpl();
  }

  protected CDOSessionPackageManagerImpl createPackageManager()
  {
    return new CDOSessionPackageManagerImpl(this);
  }

  protected CDORevisionManagerImpl createRevisionManager()
  {
    return new CDORevisionManagerImpl(this);
  }

  protected ResourceSet createResourceSet()
  {
    return new ResourceSetImpl();
  }

  /**
   * @since 2.0
   */
  protected void initView(InternalCDOView view, ResourceSet resourceSet)
  {
    InternalCDOViewSet viewSet = SessionUtil.prepareResourceSet(resourceSet);
    synchronized (views)
    {
      view.setSession(this);
      view.setViewID(++lastViewID);
      views.add(view);
    }

    // Link ViewSet with View
    view.setViewSet(viewSet);
    viewSet.add(view);

    try
    {
      view.activate();
      fireElementAddedEvent(view);
    }
    catch (RuntimeException ex)
    {
      synchronized (views)
      {
        views.remove(view);
      }

      viewSet.remove(view);
      throw ex;
    }
  }

  @Override
  protected void doBeforeActivate() throws Exception
  {
    super.doBeforeActivate();
    checkState(repositoryName, "repositoryName == null");
  }

  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();
    if (packageRegistry == null)
    {
      packageRegistry = createPackageRegistry();
    }

    packageRegistry.setSession(this);
    protocol.open();

    boolean passiveUpdateEnabled = options().isPassiveUpdateEnabled();
    OpenSessionResult result = new OpenSessionRequest(protocol, repositoryName, passiveUpdateEnabled).send();
    sessionID = result.getSessionID();
    repositoryUUID = result.getRepositoryUUID();
    repositoryCreationTime = result.getRepositoryCreationTime();
    repositoryTimeResult = result.getRepositoryTimeResult();
    repositorySupportingAudits = result.isRepositorySupportingAudits();
    handleLibraryDescriptor(result.getLibraryDescriptor());
    packageURICompressor = result.getCompressor();
    packageManager.addPackageProxies(result.getPackageInfos());
    packageManager.activate();
    revisionManager.activate();
    EventUtil.addListener(protocol, protocolListener);
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    for (InternalCDOView view : views.toArray(new InternalCDOView[views.size()]))
    {
      try
      {
        view.close();
      }
      catch (RuntimeException ignore)
      {
      }
    }

    views.clear();
    views = null;

    if (invalidationRunner != null)
    {
      invalidationRunner.deactivate();
      invalidationRunner = null;
    }

    revisionManager.deactivate();
    revisionManager = null;

    packageManager.deactivate();
    packageManager = null;

    EventUtil.removeListener(protocol, protocolListener);
    protocol.close();
    protocol = null;
    super.doDeactivate();
  }

  private void handleLibraryDescriptor(CDOIDLibraryDescriptor libraryDescriptor) throws Exception
  {
    String factoryName = libraryDescriptor.getFactoryName();
    if (TRACER.isEnabled())
    {
      TRACER.format("Using CDOID factory: {0}", factoryName);
    }

    File cacheFolder = getCacheFolder();
    ClassLoader classLoader = OM.class.getClassLoader();

    Set<String> neededLibraries = createSet(libraryDescriptor.getLibraryNames());
    if (!neededLibraries.isEmpty())
    {

      IOUtil.mkdirs(cacheFolder);
      Set<String> existingLibraries = createSet(cacheFolder.list());
      Set<String> missingLibraries = new HashSet<String>(neededLibraries);
      missingLibraries.removeAll(existingLibraries);
      if (!missingLibraries.isEmpty())
      {
        new LoadLibrariesRequest(protocol, missingLibraries, cacheFolder).send();
      }
    }

    int i = 0;
    URL[] urls = new URL[neededLibraries.size()];
    for (String neededLibrary : neededLibraries)
    {
      File lib = new File(cacheFolder, neededLibrary);
      if (TRACER.isEnabled())
      {
        TRACER.format("Using CDOID library: {0}", lib.getAbsolutePath());
      }

      urls[i++] = new URL("file:///" + lib.getAbsolutePath());
    }

    classLoader = new URLClassLoader(urls, classLoader);
    Class<?> factoryClass = classLoader.loadClass(factoryName);
    cdoidObjectFactory = (CDOIDObjectFactory)factoryClass.newInstance();
  }

  private File getCacheFolder()
  {
    String stateLocation = OM.BUNDLE.getStateLocation();
    File repos = new File(stateLocation, "repos");
    return new File(repos, repositoryUUID);
  }

  private Set<String> createSet(String[] fileNames)
  {
    Set<String> set = new HashSet<String>();
    for (String fileName : fileNames)
    {
      if (fileName.endsWith(".jar"))
      {
        set.add(fileName);
      }
    }

    return set;
  }

  private Map<CDOID, CDORevision> getAllRevisions()
  {
    Map<CDOID, CDORevision> uniqueObjects = new HashMap<CDOID, CDORevision>();
    for (InternalCDOView view : getViews())
    {
      for (InternalCDOObject internalCDOObject : view.getObjectsArray())
      {
        if (internalCDOObject.cdoRevision() != null && !internalCDOObject.cdoID().isTemporary()
            && !uniqueObjects.containsKey(internalCDOObject.cdoID()))
        {
          uniqueObjects.put(internalCDOObject.cdoID(), internalCDOObject.cdoRevision());
        }
      }
    }

    // Need to add Revision from revisionManager since we do not have all objects in view.
    for (CDORevision revision : getRevisionManager().getCachedRevisions())
    {
      if (!uniqueObjects.containsKey(revision.getID()))
      {
        uniqueObjects.put(revision.getID(), revision);
      }
    }

    return uniqueObjects;
  }

  /**
   * @since 2.0
   */
  public Collection<CDOTimeStampContext> refresh()
  {
    // If passive update is turned on we don`t need to refresh.
    // We do not throw an exception since the client could turn
    // that feature on or off without affecting their code.
    checkActive();
    if (!options().isPassiveUpdateEnabled())
    {
      Map<CDOID, CDORevision> allRevisions = getAllRevisions();

      try
      {
        if (!allRevisions.isEmpty())
        {
          int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize();
          return new SyncRevisionRequest(protocol, this, allRevisions, initialChunkSize).send();
        }
      }
      catch (Exception ex)
      {
        throw WrappedException.wrap(ex);
      }
    }

    return Collections.emptyList();
  }

  /**
   * @author Eike Stepper
   */
  private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
  {
    private static final long serialVersionUID = 1L;

    private InternalCDOView view;

    private long timeStamp;

    private Set<CDOIDAndVersion> dirtyOIDs;

    private Collection<CDOID> detachedObjects;

    public InvalidationEvent(InternalCDOView view, long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
        Collection<CDOID> detachedObjects)
    {
      super(CDOSessionImpl.this);
      this.view = view;
      this.timeStamp = timeStamp;
      this.dirtyOIDs = dirtyOIDs;
      this.detachedObjects = detachedObjects;
    }

    public CDOSession getSession()
    {
      return (CDOSession)getSource();
    }

    public InternalCDOView getView()
    {
      return view;
    }

    public long getTimeStamp()
    {
      return timeStamp;
    }

    public Set<CDOIDAndVersion> getDirtyOIDs()
    {
      return dirtyOIDs;
    }

    public Collection<CDOID> getDetachedObjects()
    {
      return detachedObjects;
    }

    @Override
    public String toString()
    {
      return "CDOSessionInvalidationEvent: " + dirtyOIDs;
    }
  }

  /**
   * @author Eike Stepper
   * @since 2.0
   */
  protected class OptionsImpl extends Notifier implements Options
  {
    private boolean passiveUpdateEnabled = true;

    private CDOCollectionLoadingPolicy collectionLoadingPolicy;

    private CDORevisionFactory revisionFactory;

    public OptionsImpl()
    {
      // TODO Remove preferences from core
      int value = OM.PREF_COLLECTION_LOADING_CHUNK_SIZE.getValue();
      collectionLoadingPolicy = CDOUtil.createCollectionLoadingPolicy(value, value);
    }

    public IOptionsContainer getContainer()
    {
      return CDOSessionImpl.this;
    }

    public void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
    {
      if (this.passiveUpdateEnabled != passiveUpdateEnabled)
      {
        this.passiveUpdateEnabled = passiveUpdateEnabled;

        // Need to refresh if we change state
        Map<CDOID, CDORevision> allRevisions = getAllRevisions();

        try
        {
          if (!allRevisions.isEmpty())
          {
            new SetPassiveUpdateRequest(protocol, CDOSessionImpl.this, allRevisions, collectionLoadingPolicy
                .getInitialChunkSize(), passiveUpdateEnabled).send();
          }
        }
        catch (Exception ex)
        {
          throw WrappedException.wrap(ex);
        }

        fireEvent(new PassiveUpdateEventImpl());
      }
    }

    public boolean isPassiveUpdateEnabled()
    {
      return passiveUpdateEnabled;
    }

    public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
    {
      return collectionLoadingPolicy;
    }

    public void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy)
    {
      if (policy == null)
      {
        policy = CDOCollectionLoadingPolicy.DEFAULT;
      }

      if (collectionLoadingPolicy != policy)
      {
        collectionLoadingPolicy = policy;
        fireEvent(new CollectionLoadingPolicyEventImpl());
      }
    }

    public synchronized CDORevisionFactory getRevisionFactory()
    {
      if (revisionFactory == null)
      {
        revisionFactory = new CDORevisionFactory()
        {
          public CDORevision createRevision(CDOClass cdoClass, CDOID id)
          {
            return CDORevisionUtil.create(cdoClass, id);
          }

          public CDORevision createRevision(CDODataInput in) throws IOException
          {
            return CDORevisionUtil.read(in);
          }

          @Override
          public String toString()
          {
            return "DefaultRevisionFactory";
          }
        };
      }

      return revisionFactory;
    }

    public synchronized void setRevisionFactory(CDORevisionFactory revisionFactory)
    {
      if (this.revisionFactory != revisionFactory)
      {
        this.revisionFactory = revisionFactory;
        fireEvent(new RevisionFactoryEventImpl());
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent
    {
      private static final long serialVersionUID = 1L;

      public PassiveUpdateEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
    {
      private static final long serialVersionUID = 1L;

      public CollectionLoadingPolicyEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class RevisionFactoryEventImpl extends OptionsEvent implements RevisionFactoryEvent
    {
      private static final long serialVersionUID = 1L;

      public RevisionFactoryEventImpl()
      {
        super(OptionsImpl.this);
      }
    }
  }
}
