/*******************************************************************************
 * Copyright (c) 2014, 2016 1C-Soft LLC 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:
 *     Vladimir Piskarev (1C) - initial API and implementation
 *******************************************************************************/
package org.eclipse.handly.model.impl;

import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT;
import static org.eclipse.handly.context.Contexts.of;
import static org.eclipse.handly.context.Contexts.with;
import static org.eclipse.handly.model.IElementDeltaConstants.F_WORKING_COPY;
import static org.eclipse.handly.util.ToStringOptions.FORMAT_STYLE;
import static org.eclipse.handly.util.ToStringOptions.FormatStyle.MEDIUM;

import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.handly.buffer.IBuffer;
import org.eclipse.handly.context.IContext;
import org.eclipse.handly.internal.Activator;
import org.eclipse.handly.model.IElement;
import org.eclipse.handly.snapshot.ISnapshot;
import org.eclipse.handly.snapshot.ISnapshotProvider;
import org.eclipse.handly.snapshot.NonExpiringSnapshot;
import org.eclipse.handly.util.Property;
import org.eclipse.handly.util.TextRange;

/**
 * Common superclass for source files.
 * <p>
 * This abstract implementation doesn't depend on a specific representation for
 * the underlying file, like <code>IFile</code> or <code>IFileStore</code>.
 * The binding has to be made in a subclass.
 * </p>
 * <p>
 * If a notification manager is registered in the model context, this class
 * will take advantage of it to send out working copy notifications. See
 * {@link #hWorkingCopyModeChanged()} and {@link NotifyingReconcileOperation}.
 * </p>
 *
 * @see WorkspaceSourceFile
 */
public abstract class SourceFile
    extends SourceElement
    implements ISourceFileImpl
{
    /**
     * Constructs a handle for a source file with the given parent element and
     * the given name.
     *
     * @param parent the parent of the element,
     *  or <code>null</code> if the element has no parent
     * @param name the name of the element, or <code>null</code>
     *  if the element has no name
     */
    public SourceFile(Element parent, String name)
    {
        super(parent, name);
    }

    @Override
    public final IBuffer hBuffer(IContext context, IProgressMonitor monitor)
        throws CoreException
    {
        if (monitor == null)
            monitor = new NullProgressMonitor();
        monitor.beginTask("", 100); //$NON-NLS-1$
        try
        {
            WorkingCopyInfo info = hAcquireExistingWorkingCopy(
                new SubProgressMonitor(monitor, 10));
            if (info == null)
            {
                return hFileBuffer(context, new SubProgressMonitor(monitor,
                    90));
            }
            else
            {
                try
                {
                    IBuffer buffer = info.getBuffer();
                    buffer.addRef();
                    return buffer;
                }
                finally
                {
                    hReleaseWorkingCopy();
                }
            }
        }
        finally
        {
            monitor.done();
        }
    }

    /**
     * If this source file is not already in working copy mode, switches it
     * into a working copy, associates it with a working copy buffer via a new
     * working copy info, and acquires an independent ownership of the working
     * copy (and, hence, of the working copy buffer). Performs atomically.
     * <p>
     * In working copy mode the source file's structure and properties
     * shall no longer correspond to the underlying resource contents
     * and must no longer be updated by a resource delta processor.
     * Instead, the source file's structure and properties can be explicitly
     * {@link #hReconcile(IContext, IProgressMonitor) reconciled} with the
     * current contents of the working copy buffer.
     * </p>
     * <p>
     * This method supports the following options, which may be specified
     * in the given context:
     * </p>
     * <ul>
     * <li>
     * {@link #WORKING_COPY_BUFFER} - Specifies the working copy buffer.
     * If not set, a default buffer is associated with the working copy.
     * </li>
     * <li>
     * {@link #WORKING_COPY_INFO_FACTORY} - Specifies the working copy info factory.
     * If not set, a default factory is used for obtaining a new working copy info.
     * </li>
     * </ul>
     * <p>
     * If the source file was already in working copy mode, this method acquires
     * a new independent ownership of the working copy by incrementing an internal
     * counter and returns the info associated with the working copy; the given
     * context is ignored. The returned info is owned by the working copy and
     * must not be explicitly disposed by the client.
     * </p>
     * <p>
     * Each successful call to this method must ultimately be followed
     * by exactly one call to <code>hReleaseWorkingCopy</code>.
     * </p>
     *
     * @param context the operation context (not <code>null</code>)
     * @param monitor a progress monitor, or <code>null</code>
     *  if progress reporting is not desired
     * @return the working copy info previously associated with
     *  this source file, or <code>null</code> if there was no
     *  working copy info for this source file
     * @throws CoreException if the working copy could not be created successfully
     * @throws OperationCanceledException if this method is canceled
     * @see #hReleaseWorkingCopy()
     * @see #hAcquireExistingWorkingCopy(IProgressMonitor)
     */
    public final WorkingCopyInfo hBecomeWorkingCopy(IContext context,
        IProgressMonitor monitor) throws CoreException
    {
        if (context == null)
            throw new IllegalArgumentException();
        IBuffer buffer = context.get(WORKING_COPY_BUFFER);
        if (buffer == null)
        {
            try (IBuffer defaultBuffer = hFileBuffer(context, monitor))
            {
                return hBecomeWorkingCopy(with(of(WORKING_COPY_BUFFER,
                    defaultBuffer), context), monitor);
            }
        }
        WorkingCopyProvider provider = new WorkingCopyProvider()
        {
            @Override
            protected WorkingCopyInfo doAcquireWorkingCopy()
            {
                return hElementManager().putWorkingCopyInfoIfAbsent(
                    SourceFile.this, buffer, context.get(
                        WORKING_COPY_INFO_FACTORY));
            }

            @Override
            protected boolean isCanceled()
            {
                if (monitor == null)
                    return false;
                return monitor.isCanceled();
            }
        };
        WorkingCopyInfo oldInfo = provider.acquireWorkingCopy();
        if (oldInfo == null)
        {
            boolean success = false;
            try
            {
                WorkingCopyInfo newInfo =
                    hElementManager().peekAtWorkingCopyInfo(this);
                newInfo.initTask.execute(context, monitor);
                success = true;
            }
            finally
            {
                if (!success)
                    hReleaseWorkingCopy();
            }
        }
        return oldInfo;
    }

    /**
     * Specifies the working copy buffer.
     * @see #hBecomeWorkingCopy(IContext, IProgressMonitor)
     */
    public static final Property<IBuffer> WORKING_COPY_BUFFER = Property.get(
        SourceFile.class.getName() + ".workingCopyBuffer", IBuffer.class); //$NON-NLS-1$
    /**
     * Specifies the working copy info factory.
     * @see #hBecomeWorkingCopy(IContext, IProgressMonitor)
     */
    public static final Property<WorkingCopyInfo.Factory> WORKING_COPY_INFO_FACTORY =
        Property.get(SourceFile.class.getName() + ".workingCopyInfoFactory", //$NON-NLS-1$
            WorkingCopyInfo.Factory.class);

    /**
     * If this source file is in working copy mode, acquires a new independent
     * ownership of the working copy by incrementing an internal counter and
     * returns the info associated with the working copy. The returned info is
     * owned by the working copy and must not be explicitly disposed by the client.
     * Returns <code>null</code> if this source file is not a working copy.
     * Performs atomically.
     * <p>
     * Each successful call to this method that did not return <code>null</code>
     * must ultimately be followed by exactly one call to <code>hReleaseWorkingCopy</code>.
     * </p>
     *
     * @return the working copy info for this source file,
     *  or <code>null</code> if this source file is not a working copy
     * @see #hReleaseWorkingCopy()
     * @see #hBecomeWorkingCopy(IContext, IProgressMonitor)
     */
    public final WorkingCopyInfo hAcquireExistingWorkingCopy(
        IProgressMonitor monitor)
    {
        WorkingCopyProvider provider = new WorkingCopyProvider()
        {
            @Override
            protected WorkingCopyInfo doAcquireWorkingCopy()
            {
                return hElementManager().getWorkingCopyInfo(SourceFile.this);
            }

            @Override
            protected boolean isCanceled()
            {
                if (monitor == null)
                    return false;
                return monitor.isCanceled();
            }
        };
        return provider.acquireWorkingCopy();
    }

    /**
     * Relinquishes an independent ownership of the working copy by decrementing
     * an internal counter. If there are no remaining owners of the working copy,
     * switches this source file from working copy mode back to its original mode
     * and releases the working copy buffer. Performs atomically.
     * <p>
     * Each independent ownership of the working copy must ultimately end
     * with exactly one call to this method. Clients that do not own the
     * working copy must not call this method.
     * </p>
     *
     * @return <code>true</code> if this source file was switched from
     *  working copy mode back to its original mode, <code>false</code>
     *  otherwise
     */
    public final boolean hReleaseWorkingCopy()
    {
        WorkingCopyInfo info = hElementManager().releaseWorkingCopyInfo(this);
        if (info == null)
            throw new IllegalStateException("Not a working copy: " + hToString( //$NON-NLS-1$
                of(FORMAT_STYLE, MEDIUM)));
        if (info.isDisposed() && info.created)
        {
            hWorkingCopyModeChanged();
            return true;
        }
        return false;
    }

    /**
     * If this source file is in working copy mode, returns the working copy info
     * without acquiring an independent ownership of the working copy. The
     * returned info is owned by the working copy and must not be explicitly
     * disposed by the client. Returns <code>null</code> if this source file
     * is not a working copy.
     * <p>
     * Note that if this method is invoked by a client that does not own the
     * working copy, the returned info may get disposed from another thread.
     * </p>
     *
     * @return the working copy info for this source file,
     *  or <code>null</code> if this source file is not a working copy
     * @see #hAcquireExistingWorkingCopy(IProgressMonitor)
     * @see #hBecomeWorkingCopy(IContext, IProgressMonitor)
     */
    public final WorkingCopyInfo hWorkingCopyInfo()
    {
        WorkingCopyInfo info = hElementManager().peekAtWorkingCopyInfo(this);
        if (info == null)
            return null;
        if (info.created)
            return info;
        // special case: wc creation is in progress on the current thread
        if (this.equals(CURRENTLY_RECONCILED.get()))
            return info;
        return null;
    }

    @Override
    public final boolean hIsWorkingCopy()
    {
        return hWorkingCopyInfo() != null;
    }

    @Override
    public final boolean hNeedsReconciling()
    {
        WorkingCopyInfo info = hAcquireExistingWorkingCopy(null);
        if (info == null)
            return false;
        else
        {
            try
            {
                return info.needsReconciling();
            }
            finally
            {
                hReleaseWorkingCopy();
            }
        }
    }

    @Override
    public final void hReconcile(IContext context, IProgressMonitor monitor)
        throws CoreException
    {
        if (monitor == null)
            monitor = new NullProgressMonitor();
        monitor.beginTask("", 100); //$NON-NLS-1$
        try
        {
            WorkingCopyInfo info = hAcquireExistingWorkingCopy(
                new SubProgressMonitor(monitor, 10));
            if (info == null)
                return; // not a working copy
            else
            {
                try
                {
                    info.reconcile(context, new SubProgressMonitor(monitor,
                        90));
                }
                finally
                {
                    hReleaseWorkingCopy();
                }
            }
        }
        finally
        {
            monitor.done();
        }
    }

    /**
     * Returns a reconcile operation for this source file.
     * <p>
     * This implementation returns a new instance of {@link
     * NotifyingReconcileOperation} if there is a notification manager
     * registered in the model context. Otherwise, a new instance of
     * {@link ReconcileOperation} is returned.
     * </p>
     * <p>
     * Clients are not intended to invoke this method, but may override it.
     * </p>
     *
     * @return a reconcile operation for this source file (not <code>null</code>)
     */
    protected ReconcileOperation hReconcileOperation()
    {
        if (hModel().getModelContext().get(INotificationManager.class) != null)
            return new NotifyingReconcileOperation();

        return new ReconcileOperation();
    }

    /**
     * Returns a context to be associated with a new working copy of this
     * source file. The given operation context is propagated from the
     * {@link #hBecomeWorkingCopy} method.
     * <p>
     * This implementation returns an empty context. Subclasses may override.
     * </p>
     *
     * @param context the operation context (never <code>null</code>)
     * @return the working copy context (not <code>null</code>)
     */
    protected IContext hWorkingCopyContext(IContext context)
    {
        return EMPTY_CONTEXT;
    }

    /**
     * Notifies about a working copy mode change: either the source file
     * became a working copy or reverted back from the working copy mode.
     * <p>
     * This implementation does nothing if no notification manager is
     * registered in the model context. Otherwise, it sends out a delta
     * notification indicating the nature of the working copy mode change.
     * </p>
     * <p>
     * Clients are not intended to invoke this method, but may override it.
     * </p>
     */
    protected void hWorkingCopyModeChanged()
    {
        INotificationManager notificationManager =
            hModel().getModelContext().get(INotificationManager.class);
        if (notificationManager == null)
            return;

        ElementDelta.Factory deltaFactory = hModel().getModelContext().get(
            ElementDelta.Factory.class);
        if (deltaFactory == null)
            deltaFactory = element -> new ElementDelta(element);
        ElementDelta rootDelta = deltaFactory.newDelta(hRoot());
        ElementDelta.Builder builder = new ElementDelta.Builder(rootDelta);
        if (hFileExists())
            builder.changed(this, F_WORKING_COPY);
        else if (hIsWorkingCopy())
            builder.added(this, F_WORKING_COPY);
        else
            builder.removed(this, F_WORKING_COPY);
        notificationManager.fireElementChangeEvent(new ElementChangeEvent(
            ElementChangeEvent.POST_CHANGE, builder.getDelta()));
    }

    @Override
    protected void hValidateExistence(IContext context) throws CoreException
    {
        if (!hIsWorkingCopy())
        {
            if (!hFileExists())
                throw hDoesNotExistException();
        }
    }

    @Override
    void hBuildStructure0(IContext context, IProgressMonitor monitor)
        throws CoreException
    {
        if (!context.containsKey(SOURCE_CONTENTS) && !context.containsKey(
            SOURCE_AST))
        {
            if (hIsWorkingCopy())
                throw new AssertionError();
            // NOTE: source files that are not working copies must reflect
            // the structure of the underlying file rather than the buffer
            NonExpiringSnapshot snapshot;
            try (ISnapshotProvider provider = hFileSnapshotProvider())
            {
                try
                {
                    snapshot = new NonExpiringSnapshot(provider);
                }
                catch (IllegalStateException e)
                {
                    Throwable cause = e.getCause();
                    if (cause instanceof CoreException)
                        throw (CoreException)cause;
                    throw new CoreException(Activator.createErrorStatus(
                        e.getMessage(), e));
                }
            }
            context = with(of(SOURCE_CONTENTS, snapshot.getContents()), of(
                SOURCE_SNAPSHOT, snapshot.getWrappedSnapshot()), context);
        }

        super.hBuildStructure0(context, monitor);

        Map<IElement, Object> newElements = context.get(NEW_ELEMENTS);
        Object body = newElements.get(this);
        if (body instanceof SourceElementBody)
        {
            SourceElementBody thisBody = (SourceElementBody)body;

            String source = context.get(SOURCE_CONTENTS);
            if (source != null)
                thisBody.setFullRange(new TextRange(0, source.length()));

            ISnapshot snapshot = context.get(SOURCE_SNAPSHOT);
            if (snapshot != null)
                setSnapshot(thisBody, snapshot, newElements);
        }
    }

    /**
     * Returns whether the underlying file exists.
     *
     * @return <code>true</code> if the underlying file exists,
     *  and <code>false</code> otherwise
     */
    protected abstract boolean hFileExists();

    /**
     * Returns a snapshot provider for the underlying file's stored contents.
     * <p>
     * The client takes (potentially shared) ownership of the returned provider
     * and is responsible for releasing it. The provider will be disposed
     * only after it is released by every owner. The provider must not
     * be accessed by clients that don't own it.
     * </p>
     *
     * @return a snapshot provider for the underlying file's stored contents
     *  (not <code>null</code>)
     * @see ISnapshotProvider
     */
    protected abstract ISnapshotProvider hFileSnapshotProvider();

    /**
     * Returns the buffer opened for the underlying file of this source file.
     * Note that buffers may be shared by multiple clients, so the returned buffer
     * may have unsaved changes if it has been modified by another client.
     * <p>
     * The client takes (potentially shared) ownership of the returned buffer
     * and is responsible for releasing it. The buffer will be disposed
     * only after it is released by every owner. The buffer must not
     * be accessed by clients that don't own it.
     * </p>
     * <p>
     * Implementations are encouraged to support the following standard options,
     * which may be specified in the given context:
     * </p>
     * <ul>
     * <li>
     * {@link org.eclipse.handly.model.Elements#CREATE_BUFFER CREATE_BUFFER} -
     * Indicates whether a new buffer should be created if none already exists.
     * </li>
     * </ul>
     *
     * @param context the operation context (never <code>null</code>)
     * @param monitor a progress monitor, or <code>null</code>
     *  if progress reporting is not desired
     * @return the buffer opened for the underlying file of this source file,
     *  or <code>null</code> if <code>CREATE_BUFFER == false</code> and
     *  there is currently no buffer opened for that file
     * @throws CoreException if the buffer could not be opened successfully
     * @throws OperationCanceledException if this method is canceled
     * @see IBuffer
     */
    protected abstract IBuffer hFileBuffer(IContext context,
        IProgressMonitor monitor) throws CoreException;

    /**
     * Creates and initializes bodies for this element and for each
     * of its descendant elements according to options specified in the
     * given context. Uses the {@link #NEW_ELEMENTS} map in the given context
     * to associate the created bodies with their respective elements.
     * <p>
     * The following context options influence how the structure is built and,
     * if simultaneously present, must be mutually consistent:
     * </p>
     * <ul>
     * <li>
     * {@link #SOURCE_AST} - Specifies the AST to use when building the structure.
     * The AST is safe to read in the dynamic context of this method call, but
     * must not be modified.
     * </li>
     * <li>
     * {@link #SOURCE_CONTENTS} - Specifies the source string to use when
     * building the structure.
     * </li>
     * </ul>
     * <p>
     * At least one of <code>SOURCE_AST</code> or <code>SOURCE_CONTENTS</code>
     * will have a non-null value in the given context.
     * </p>
     * <p>
     * The given context may provide additional data that this method can use,
     * including the following:
     * </p>
     * <ul>
     * <li>
     * {@link #SOURCE_SNAPSHOT} - Specifies the source snapshot from which
     * <code>SOURCE_AST</code> was created or <code>SOURCE_CONTENTS</code>
     * was obtained. The snapshot may expire.
     * </li>
     * </ul>
     *
     * @param context the operation context (never <code>null</code>)
     * @param monitor a progress monitor (never <code>null</code>)
     * @throws CoreException if this method fails
     * @throws OperationCanceledException if this method is canceled
     */
    @Override
    protected abstract void hBuildStructure(IContext context,
        IProgressMonitor monitor) throws CoreException;

    /**
     * Specifies the source AST.
     * @see #hBuildStructure(IContext, IProgressMonitor)
     */
    protected static final Property<Object> SOURCE_AST = Property.get(
        SourceFile.class.getName() + ".sourceAst", Object.class); //$NON-NLS-1$
    /**
     * Specifies the source string.
     * @see #hBuildStructure(IContext, IProgressMonitor)
     */
    protected static final Property<String> SOURCE_CONTENTS = Property.get(
        SourceFile.class.getName() + ".sourceContents", String.class); //$NON-NLS-1$
    /**
     * Specifies the source snapshot.
     * @see #hBuildStructure(IContext, IProgressMonitor)
     */
    protected static final Property<ISnapshot> SOURCE_SNAPSHOT = Property.get(
        SourceFile.class.getName() + ".sourceSnapshot", ISnapshot.class); //$NON-NLS-1$

    @Override
    protected void hGenerateAncestorBodies(IContext context,
        IProgressMonitor monitor) throws CoreException
    {
        if (hIsWorkingCopy())
            return; // don't open ancestors for a working copy
        super.hGenerateAncestorBodies(context, monitor);
    }

    @Override
    protected boolean hClose(boolean external)
    {
        if (hIsWorkingCopy())
            return false; // a working copy cannot be removed
        return super.hClose(external);
    }

    @Override
    protected void hToStringName(StringBuilder builder, IContext context)
    {
        if (hIsWorkingCopy())
            builder.append("[Working copy] "); //$NON-NLS-1$
        super.hToStringName(builder, context);
    }

    private static void setSnapshot(SourceElementBody body, ISnapshot snapshot,
        Map<IElement, Object> newElements)
    {
        body.setSnapshot(snapshot);
        for (IElement child : body.getChildren())
        {
            Object childBody = newElements.get(child);
            if (childBody instanceof SourceElementBody)
            {
                setSnapshot((SourceElementBody)childBody, snapshot,
                    newElements);
            }
        }
    }

    /**
     * Indicates whether the structure should be rebuilt when reconciling
     * is forced. Default value: <code>false</code>.
     * @see ReconcileOperation#reconcile(IContext, IProgressMonitor)
     */
    protected static final Property<Boolean> REBUILD_STRUCTURE_IF_FORCED =
        Property.get(SourceFile.class.getName() + ".rebuildStructureIfForced", //$NON-NLS-1$
            Boolean.class).withDefault(false);
    /**
     * Indicates whether reconciling was forced, i.e. the working copy buffer
     * has not been modified since the last time it was reconciled.
     * Default value: <code>false</code>.
     * @see ReconcileOperation#reconcile(IContext, IProgressMonitor)
     */
    static final Property<Boolean> RECONCILING_FORCED = Property.get(
        SourceFile.class.getName() + ".reconcilingForced", //$NON-NLS-1$
        Boolean.class).withDefault(false);

    private static final ThreadLocal<SourceFile> CURRENTLY_RECONCILED =
        new ThreadLocal<SourceFile>(); // the source file being reconciled

    /**
     * A reconcile operation for this source file.
     * <p>
     * Clients are not intended to use instances of this class or a subclass
     * of this class, but may extend it to augment the default behavior, e.g.
     * to send out a delta notification indicating the nature of the change
     * of the working copy since the last time it was reconciled. Clients that
     * extend this class or a subclass of this class should consider
     * overriding {@link SourceFile#hReconcileOperation()} method.
     * </p>
     *
     * @see NotifyingReconcileOperation
     */
    protected class ReconcileOperation
    {
        /**
         * Reconciles this working copy according to options specified
         * in the given context.
         * <p>
         * The following context options can influence whether the structure
         * of the working copy gets rebuilt:
         * </p>
         * <ul>
         * <li>
         * {@link #REBUILD_STRUCTURE_IF_FORCED} - Indicates whether the structure
         * should be rebuilt even if reconciling was forced, i.e. the working copy
         * buffer has not been modified since the last time it was reconciled.
         * </li>
         * </ul>
         * <p>
         * The following context options influence rebuilding of the structure
         * of the working copy and, if simultaneously present, must be mutually
         * consistent:
         * </p>
         * <ul>
         * <li>
         * {@link #SOURCE_AST} - Specifies the AST to use when building the
         * structure. The AST is safe to read in the dynamic context of this
         * method call, but must not be modified.
         * </li>
         * <li>
         * {@link #SOURCE_CONTENTS} - Specifies the source string to use when
         * building the structure.
         * </li>
         * </ul>
         * <p>
         * At least one of <code>SOURCE_AST</code> or <code>SOURCE_CONTENTS</code>
         * must have a non-null value in the given context.
         * </p>
         * <p>
         * The given context may provide additional data that this method can use,
         * including the following:
         * </p>
         * <ul>
         * <li>
         * {@link #SOURCE_SNAPSHOT} - Specifies the source snapshot from which
         * <code>SOURCE_AST</code> was created or <code>SOURCE_CONTENTS</code>
         * was obtained. The snapshot may expire.
         * </li>
         * </ul>
         * <p>
         * Subclasses may override this method, but must call the <b>super</b>
         * implementation.
         * </p>
         *
         * @param context the operation context (not <code>null</code>)
         * @param monitor a progress monitor, or <code>null</code>
         *  if progress reporting is not desired
         * @throws CoreException if the working copy cannot be reconciled
         * @throws OperationCanceledException if this method is canceled
         */
        protected void reconcile(IContext context, IProgressMonitor monitor)
            throws CoreException
        {
            if (context.get(SOURCE_AST) == null && context.get(
                SOURCE_CONTENTS) == null)
            {
                throw new IllegalArgumentException();
            }
            WorkingCopyInfo info = hElementManager().peekAtWorkingCopyInfo(
                SourceFile.this);
            boolean create = !info.created; // case of wc creation
            if (create || !context.getOrDefault(RECONCILING_FORCED)
                || context.getOrDefault(REBUILD_STRUCTURE_IF_FORCED))
            {
                if (CURRENTLY_RECONCILED.get() != null)
                    throw new AssertionError(); // should never happen
                CURRENTLY_RECONCILED.set(SourceFile.this);
                try
                {
                    hOpen(with(of(FORCE_OPEN, true), context), monitor);
                }
                finally
                {
                    CURRENTLY_RECONCILED.set(null);
                }
            }
            if (create)
            {
                if (!info.created)
                    throw new AssertionError(); // should never happen
                hWorkingCopyModeChanged(); // notify about wc creation
            }
        }
    }

    /**
     * Reconciles this working copy and sends out a delta notification
     * indicating the nature of the change of the working copy since
     * the last time it was reconciled. Uses the notification manager
     * registered in the model context.
     *
     * @see INotificationManager
     */
    protected class NotifyingReconcileOperation
        extends ReconcileOperation
    {
        @Override
        protected void reconcile(IContext context, IProgressMonitor monitor)
            throws CoreException
        {
            ElementDelta.Factory deltaFactory = hModel().getModelContext().get(
                ElementDelta.Factory.class);
            if (deltaFactory == null)
                deltaFactory = element -> new ElementDelta(element);
            ElementDelta rootDelta = deltaFactory.newDelta(SourceFile.this);
            ElementDifferencer differ = new ElementDifferencer(
                new ElementDelta.Builder(rootDelta));

            doReconcile(context, monitor);

            differ.buildDelta();
            if (!differ.isEmptyDelta())
            {
                hModel().getModelContext().get(
                    INotificationManager.class).fireElementChangeEvent(
                        new ElementChangeEvent(
                            ElementChangeEvent.POST_RECONCILE,
                            differ.getDelta()));
            }
        }

        /**
         * This implementation calls {@link ReconcileOperation#reconcile(
         * IContext, IProgressMonitor) super.reconcile(..)}.
         * <p>
         * Subclasses may override this method, but must call its <b>super</b>
         * implementation.
         * </p>
         *
         * @param context the operation context (not <code>null</code>)
         * @param monitor a progress monitor, or <code>null</code>
         *  if progress reporting is not desired
         * @throws CoreException if the working copy cannot be reconciled
         * @throws OperationCanceledException if this method is canceled
         */
        protected void doReconcile(IContext context, IProgressMonitor monitor)
            throws CoreException
        {
            super.reconcile(context, monitor);
        }
    }

    private abstract class WorkingCopyProvider
    {
        public WorkingCopyInfo acquireWorkingCopy()
        {
            for (;;)
            {
                if (isCanceled())
                    throw new OperationCanceledException();
                WorkingCopyInfo info = doAcquireWorkingCopy();
                if (info == null)
                    return null;
                boolean success = false;
                try
                {
                    success = waitForInit(info);
                }
                finally
                {
                    if (!success)
                        hReleaseWorkingCopy();
                }
                if (success)
                    return info;
            }
        }

        protected abstract WorkingCopyInfo doAcquireWorkingCopy();

        protected boolean isCanceled()
        {
            return false;
        }

        private boolean waitForInit(WorkingCopyInfo info)
        {
            for (int i = 0; i < 10; i++)
            {
                if (isCanceled())
                    throw new OperationCanceledException();
                try
                {
                    return info.initTask.wasSuccessful(10,
                        TimeUnit.MILLISECONDS);
                }
                catch (InterruptedException e)
                {
                }
                catch (TimeoutException e)
                {
                }
            }
            return false;
        }
    }
}
