/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *
 ********************************************************************************/

package org.eclipse.jst.jsf.designtime.internal.jsp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.resource.EventResult;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.ReasonType;
import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.IMetaDataDomainContext;
import org.eclipse.jst.jsf.common.metadata.internal.TraitValueHelper;
import org.eclipse.jst.jsf.common.metadata.query.internal.MetaDataQueryContextFactory;
import org.eclipse.jst.jsf.common.metadata.query.internal.MetaDataQueryFactory;
import org.eclipse.jst.jsf.common.metadata.query.internal.taglib.ITaglibDomainMetaDataQuery;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.context.symbol.IComponentSymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.context.symbol.source.AbstractContextSymbolFactory;
import org.eclipse.jst.jsf.context.symbol.source.ISymbolConstants;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.DesignTimeApplicationManager;
import org.eclipse.jst.jsf.designtime.context.DTFacesContext;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Processes a JSP model to determine information of interest about it such
 * as what tags are currently in use.  Listens to the model and updates it's
 * information when the model changes.
 *
 * @author cbateman
 *
 */
public class JSPModelProcessor
{
    /**
     * Pass to force refresh arguments
     */
    public final static boolean FORCE_REFRESH = true;

    /**
     * Pass to runAfter argument of refresh to indicate there is nothing
     * to run when the refresh job completes.
     */
    public final static Runnable NO_RUN_AFTER = null;

    /**
     * Pass to runAfter argument of refresh to indicate that the caller
     * should be blocked until the job completes.
     */
    public final static Runnable RUN_ON_CURRENT_THREAD = new Runnable()
    {
        public void run()
        {
            // do nothing
        }
    };

    /**
     * An init-time setting that is used to stop the model processor from
     * automatically refreshing when the file it is tracking changes. The can
     * only be set once at init is permanent for the static life timpe of
     * JSPModelProcessor.
     *
     * Note that it does not turn off listening for file delete events because
     * the singleton management still needs to know if it can dispose of an
     * instance.
     */
    private final static boolean                         DISABLE_WKSPACE_CHANGE_REFRESH = System
                                                                                                .getProperty("org.eclipse.jst.jsf.jspmodelprocessor.disable.wkspace.change.refresh") != null; //$NON-NLS-1$
    private final static Map<IFile, JSPModelProcessor>  RESOURCE_MAP =
        new HashMap<IFile, JSPModelProcessor>();
    private final static java.util.concurrent.locks.Lock CRITICAL_SECTION =
        new  ReentrantLock();
    private static LifecycleListener  LIFECYCLE_LISTENER;

    /**
     * @param file The file to get the model processor for
     * @return the processor for a particular model, creating it if it does not
     *         already exist
     * @throws CoreException if an attempt to get the model associated with file
     *         fails due to reasons other than I/O problems
     */
    public static JSPModelProcessor get(final IFile file) throws CoreException
    {
        CRITICAL_SECTION.lock();
        try
        {
            if (!file.isAccessible())
            {
                throw new CoreException(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, "File must be accessible")); //$NON-NLS-1$
            }

            JSPModelProcessor processor = RESOURCE_MAP.get(file);

            if (processor == null)
            {
                if (LIFECYCLE_LISTENER == null)
                {
                    LIFECYCLE_LISTENER = new LifecycleListener(file, ResourcesPlugin.getWorkspace());
                }
                else
                {
                    LIFECYCLE_LISTENER.addResource(file);
                }

                processor = new JSPModelProcessor(file,LIFECYCLE_LISTENER);
                RESOURCE_MAP.put(file, processor);
            }

            return processor;
        }
        finally
        {
            CRITICAL_SECTION.unlock();
        }
    }

    /**
     * Disposes of the JSPModelProcessor associated with model
     * @param file the model processor to be disposed
     */
    private static void dispose(final IFile file)
    {
        CRITICAL_SECTION.lock();
        try
        {
            final JSPModelProcessor processor = RESOURCE_MAP.get(file);

            if (processor != null)
            {
                RESOURCE_MAP.remove(file);

                if (!processor.isDisposed())
                {
                    processor.dispose();
                    LIFECYCLE_LISTENER.removeResource(file);
                }

            }

            if (RESOURCE_MAP.isEmpty())
            {
                // if we no longer have any resources being tracked,
                // then dispose the lifecycle listener
                LIFECYCLE_LISTENER.dispose();
                LIFECYCLE_LISTENER = null;
            }
        }
        finally
        {
            CRITICAL_SECTION.unlock();
        }
    }

    private final IFile             _file;
    private LifecycleListener       _lifecycleListener;
    private IResourceLifecycleListener  _resListener;
    private volatile boolean                 _isDisposed;
    private Map<Object, ISymbol>    _requestMap;
    private Map<Object, ISymbol>    _sessionMap;
    private Map<Object, ISymbol>    _applicationMap;
    private Map<Object, ISymbol>    _noneMap;
    private Map<Object, ISymbol>    _viewMap;
    private Map<Object, ISymbol>    _flashMap;

    // used to avoid infinite recursion in refresh.  Must never be null
    private final CountingMutex     _lastModificationStampMonitor = new CountingMutex();

    /**
     * Construct a new JSPModelProcessor for model
     *
     * @param model
     */
    private JSPModelProcessor(final IFile  file, final LifecycleListener lifecycleListener)
    {
        _file = file;
        _lifecycleListener = lifecycleListener;
        _resListener = new IResourceLifecycleListener()
        {
            public EventResult acceptEvent(final ResourceLifecycleEvent event)
            {
                final EventResult result = EventResult.getDefaultEventResult();

                // not interested
                if (!_file.equals(event.getAffectedResource()))
                {
                    return result;
                }

                if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE)
                {
                    dispose(_file);
                }
                else if (event.getEventType() == EventType.RESOURCE_CHANGED)
                {
                    // if the file has changed contents on disk, then
                    // invoke an unforced refresh of the JSP file
                    if (event.getReasonType() == ReasonType.RESOURCE_CHANGED_CONTENTS
                            && !DISABLE_WKSPACE_CHANGE_REFRESH)
                    {
                        refresh(! FORCE_REFRESH, NO_RUN_AFTER);
                    }
                }

                return result;
            }
        };

        lifecycleListener.addListener(_resListener);
    }

    private IDOMModel getModelForFile(final IFile file)
            throws CoreException, IOException
    {
        final IModelManager modelManager =
            StructuredModelManager.getModelManager();

        final IStructuredModel model = modelManager.getModelForRead(file);

        if (model instanceof IDOMModel)
        {
            return (IDOMModel) model;
        }
        else if (model != null)
        {
            // only release from read if we don't find a DOMModelForJSP
            // if the model is correct, it will be released in dispose
            model.releaseFromRead();
        }
        
        JSFCorePlugin.log("Couldn't get valid model for file: "+file.toString(), new Exception()); //$NON-NLS-1$
        return null;
    }

    private void dispose()
    {
        if (!_isDisposed)
        {
            // ensure the resource listener is disposed
            _lifecycleListener.removeListener(_resListener);
            _resListener = null;
            _lifecycleListener = null;

            if (_requestMap != null)
            {
                _requestMap.clear();
                _requestMap = null;
            }

            if (_sessionMap != null)
            {
                _sessionMap.clear();
                _sessionMap = null;
            }

            if (_applicationMap != null)
            {
                _applicationMap.clear();
                _applicationMap = null;
            }

            if (_noneMap != null)
            {
                _noneMap.clear();
                _noneMap = null;
            }

            // mark as disposed
            _isDisposed = true;
        }
    }

    /**
     * @return true if this model processor has been disposed.  Disposed
     * processors should not be used.
     */
    public boolean isDisposed()
    {
        return _isDisposed;
    }

    /**
     * If isModelDirty() returns true, then it means that a call
     * to refresh(false) will trigger a reprocess of the underlying document.
     *
     * @return true if the underlying JSP model is considered to be dirty
     */
    public boolean isModelDirty()
    {
        final long currentModificationStamp = _file.getModificationStamp();
        return _lastModificationStampMonitor.hasChanged(currentModificationStamp);
    }



    /**
     * Refreshes the processor's cache of information from its associated
     * JSP file.
     *
     * @param forceRefresh
     * @param runAfter
     */
    public void refresh(final boolean forceRefresh, final Runnable runAfter)
    {
        if (isDisposed())
        {
            throw new IllegalStateException(
                    "Processor is disposed for file: " + _file.toString()); //$NON-NLS-1$
        }

        if (runAfter == RUN_ON_CURRENT_THREAD)
        {
            try
            {
                runOnCurrentThread(forceRefresh);
            } 
            catch (final CoreException e)
            {
                JSFCorePlugin.log(e, "Running JSP model processor"); //$NON-NLS-1$
            } 
            catch (final OperationCanceledException e)
            {
                // ignore
            } 
        } 
        else
        {
            runOnWorkspaceJob(forceRefresh, runAfter);
        }

    }
    private void runOnWorkspaceJob(final boolean forceRefresh, final Runnable runAfter)
    {
    	WorkspaceJob refreshJob = new WorkspaceJob(NLS.bind(Messages
                .getString("JSPModelProcessor.0"), _file)) { //$NON-NLS-1$
            @Override
            public IStatus runInWorkspace(IProgressMonitor monitor)
                    throws CoreException
            {
                RefreshRunnable runnable = new RefreshRunnable(forceRefresh);
                runnable.run(monitor);
                return Status.OK_STATUS;
            }
        };
        refreshJob.setSystem(true);
        refreshJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
        if (runAfter != null)
        {
            refreshJob.addJobChangeListener(new JobChangeAdapter()
            {
                @Override
                public void done(final IJobChangeEvent event)
                {
                    runAfter.run();
                }
            });
        }
        refreshJob.schedule();
    }

    private void runOnCurrentThread(final boolean forceRefresh) throws CoreException, OperationCanceledException
    {
        ResourcesPlugin.getWorkspace().run(new RefreshRunnable(forceRefresh), _file, 0, null);
    }
    
    private final class RefreshRunnable implements IWorkspaceRunnable
    {
        private final boolean _forceRefresh;

        public RefreshRunnable(final boolean forceRefresh)
        {
            _forceRefresh = forceRefresh;
        }

        public void run(final IProgressMonitor monitor)
                throws CoreException
        {
            synchronized (_lastModificationStampMonitor)
            {
                if (!_lastModificationStampMonitor.compareAndSetSignalled(false, true))
                {
                    // if this calls succeeds, then this thread has obtained the
                    // lock already and has called through here before.
                    // return immediately to ensure that we don't recurse
                    // infinitely
                    return;
                }
                IDOMModel model = null;
                try
                {
                    // only refresh if forced or if the underlying file has
                    // changed
                    // since the last run
                    if (_forceRefresh || isModelDirty())
                    {
                        model = getModelForFile(_file);
                        if (model != null)
                        {
                            refreshInternal(model);
                        }
                        _lastModificationStampMonitor.setModificationStamp(_file.getModificationStamp());
                    }
                }
                catch (final IOException e)
                {
                    IStatus status = new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID,"Error refreshing internal model", e); //$NON-NLS-1$
                    final CoreException e2 = new CoreException(status);
                    throw e2;
                }
                // make sure that we unsignal the monitor before releasing the
                // mutex
                finally
                {
                    _lastModificationStampMonitor.setSignalled(false);
                    if (model != null)
                    {
                        model.releaseFromRead();
                    }
                }
            }
        }
    }



    private void refreshInternal(final IDOMModel model)
    {
        final IStructuredDocumentContext context =
            IStructuredDocumentContextFactory.INSTANCE.getContext(model.getStructuredDocument(), -1);
        final ITaglibContextResolver taglibResolver =
            IStructuredDocumentContextResolverFactory.INSTANCE.getTaglibContextResolver(context);
        final IDOMDocument document = model.getDocument();
        getApplicationMap().clear();
        getRequestMap().clear();
        getSessionMap().clear();

        if (taglibResolver == null) {
            // unusual, but protect against possible NPE
            JSFCorePlugin.log(IStatus.ERROR, "Program Error: taglib resolver is null."); //$NON-NLS-1$
            return;
        }

        //long curTime = System.currentTimeMillis();
        recurseChildNodes(model, document.getChildNodes(), taglibResolver);
        //long netTime = System.currentTimeMillis() - curTime;
        //System.out.println("Net time to recurse document: "+netTime);
    }

    private void recurseChildNodes(final IDOMModel model,
                                   final NodeList nodes,
                                    final ITaglibContextResolver taglibResolver)
    {
        for (int i = 0; i < nodes.getLength(); i++)
        {
            final Node child = nodes.item(i);

            // process attributes at this node before recursing
            processAttributes(model, child, taglibResolver);
            recurseChildNodes(model, child.getChildNodes(), taglibResolver);
        }
    }

    private void processAttributes(final IDOMModel model, final Node node,
                                    final ITaglibContextResolver taglibResolver)
    {
        if (taglibResolver.hasTag(node))
        {
            final String uri =
                taglibResolver.getTagURIForNodeName(node);
            final String elementName = node.getLocalName();

            for (int i = 0; i < node.getAttributes().getLength(); i++)
            {
                final Node attribute = node.getAttributes().item(i);

                processSymbolContrib(model, uri, elementName, attribute);
                processSetsLocale(uri, elementName, attribute);
            }
        }
    }

    private void processSymbolContrib(final IDOMModel model, final String uri, final String elementName, final Node attribute)
    {
        final SymbolContribAggregator  aggregator =
            SymbolContribAggregator.
               create(_file, uri, elementName, attribute.getLocalName());

        if (aggregator != null)
        {
            final AbstractContextSymbolFactory factory = aggregator.getFactory();
            final String symbolName = attribute.getNodeValue();

            if (factory != null)
            {
//                long curTime = System.currentTimeMillis();
                final IStructuredDocumentContext context =
                    IStructuredDocumentContextFactory.INSTANCE.
                        getContext(model.getStructuredDocument(),
                           attribute);

                if (factory.supports(context))
                {
                    final List problems = new ArrayList();
                    final ISymbol symbol =
                        factory.create(symbolName,
                                      ISymbolConstants.SYMBOL_SCOPE_REQUEST, //TODO:
                                      context,
                                      problems,
                                      // TODO: add meta-data for signature
                                      new AdditionalContextSymbolInfo(aggregator.getStaticType(), aggregator.getValueExpressionAttr()));

    //                long netTime = System.currentTimeMillis() - curTime;
    //                System.out.println("Time to process loadBundle: "+netTime);

                    if (symbol != null)
                    {
                        updateMap(symbol, aggregator.getScope());
                    }
                }
            }
            else
            {
                final IComponentSymbol componentSymbol =
                    SymbolFactory.eINSTANCE.createIComponentSymbol();
                componentSymbol.setName(symbolName);

                updateMap(componentSymbol, aggregator.getScope());
            }
        }
    }
    
    @SuppressWarnings("deprecation")
    private void processSetsLocale(final String uri, final String elementName, Node attribute)
    {
        LocaleSetAggregator  aggregator = LocaleSetAggregator.create(_file, uri, elementName, attribute.getLocalName());

        if (aggregator != null)
        {
            DesignTimeApplicationManager  dtAppMgr =
                DesignTimeApplicationManager.getInstance(_file.getProject());

            if (dtAppMgr != null)
            {
                DTFacesContext facesContext = dtAppMgr.getFacesContext(_file);
                
                if (facesContext != null)
                {
                    facesContext.setLocaleString(attribute.getNodeValue());
                }
            }
        }
    }

   /**
     * @param scopeName - one of "request", "session" or "application" or "view" if JSF2.x
     * @return an unmodifable map containing all known symbols for
     * that scope.  If scopeName is not found, returns the empty map.
     */
    public Map<Object, ISymbol> getMapForScope(final String scopeName)
    {
        final Map<Object, ISymbol> map = getMapForScopeInternal(scopeName);

        if (map != null)
        {
            return Collections.unmodifiableMap(map);
        }

        return Collections.EMPTY_MAP;
    }

    private void updateMap(final ISymbol symbol, final String  scopeName)
    {
        final Map<Object, ISymbol> map = getMapForScopeInternal(scopeName);

        if (map != null)
        {
            map.put(symbol.getName(), symbol);
        }
        else
        {
            Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Throwable())); //$NON-NLS-1$
        }
    }

    private Map<Object, ISymbol> getMapForScopeInternal(final String scopeName)
    {
        if (ISymbolConstants.SYMBOL_SCOPE_REQUEST_STRING.equals(scopeName))
        {
            return getRequestMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_SESSION_STRING.equals(scopeName))
        {
            return getSessionMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_APPLICATION_STRING.equals(scopeName))
        {
            return getApplicationMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_NONE_STRING.equals(scopeName))
        {
            return getNoneMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_VIEW_STRING.equals(scopeName))
        {
            return getViewMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_FLASH_STRING.equals(scopeName))
        {
            return getFlashMap();
        }

        Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Throwable())); //$NON-NLS-1$
        return null;

    }

    private Map getRequestMap()
    {
        if (_requestMap == null)
        {
            _requestMap = new HashMap<Object, ISymbol>();
        }

        return _requestMap;
    }

    private Map<Object, ISymbol> getSessionMap()
    {
        if (_sessionMap == null)
        {
            _sessionMap = new HashMap<Object, ISymbol>();
        }

        return _sessionMap;
    }

    private Map<Object, ISymbol> getApplicationMap()
    {
        if (_applicationMap == null)
        {
            _applicationMap = new HashMap<Object, ISymbol>();
        }

        return _applicationMap;
    }

    private Map<Object, ISymbol> getNoneMap()
    {
        if (_noneMap == null)
        {
            _noneMap = new HashMap<Object, ISymbol>();
        }

        return _noneMap;
    }
    
    private Map<Object, ISymbol> getViewMap()
    {
        if (_viewMap == null)
        {
        	_viewMap = new HashMap<Object, ISymbol>();
        }

        return _viewMap;
    }
    
    private Map<Object, ISymbol> getFlashMap()
    {
        if (_flashMap == null)
        {
        	_flashMap = new HashMap<Object, ISymbol>();
        }

        return _flashMap;
    }

    /**
     * Aggregates the sets-locale meta-data
     *
     * @author cbateman
     */
    private static class LocaleSetAggregator
    {
        private final static String SETS_LOCALE = "sets-locale"; //$NON-NLS-1$

        private static LocaleSetAggregator create(final IFile file,
                                              final String uri,
                                              final String elementName, final String attributeName)
        {
    		final IMetaDataDomainContext context = MetaDataQueryContextFactory.getInstance().createTaglibDomainModelContext(file);
    		final ITaglibDomainMetaDataQuery query = MetaDataQueryFactory.getInstance().createQuery(context);
    		final Trait trait = query.getQueryHelper().getTrait(uri, elementName+"/"+attributeName, SETS_LOCALE); //$NON-NLS-1$
//            final ITaglibDomainMetaDataModelContext mdContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, uri);
//            final Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, elementName+"/"+attributeName, SETS_LOCALE); //$NON-NLS-1$

            if (TraitValueHelper.getValueAsBoolean(trait))
            {
                return new LocaleSetAggregator();
            }

            return null;
        }
    }

    /**
     * Aggregates all the symbol contributor meta-data into a single object
     *
     * @author cbateman
     *
     */
    private static class SymbolContribAggregator
    {
        private final static String CONTRIBUTES_VALUE_BINDING =
            "contributes-value-binding"; //$NON-NLS-1$
        private final static String VALUE_BINDING_SCOPE = "value-binding-scope"; //$NON-NLS-1$
        private final static String VALUE_BINDING_SYMBOL_FACTORY =
            "value-binding-symbol-factory"; //$NON-NLS-1$
        private final static String STATIC_TYPE_KEY = "optional-value-binding-static-type"; //$NON-NLS-1$
        private final static String VALUEEXPRESSION_ATTR_NAME_KEY = "optional-value-binding-valueexpr-attr"; //$NON-NLS-1$

        /**
         * @param attributeName
         * @return a new instance only if attributeName is a symbol contributor
         */
        private static SymbolContribAggregator create(final IFile file,
                                              final String uri,
                                              final String elementName,
                                              final String attributeName)
        {
            final String entityKey = elementName+"/"+attributeName; //$NON-NLS-1$
    		final IMetaDataDomainContext context = MetaDataQueryContextFactory.getInstance().createTaglibDomainModelContext(file);
    		final ITaglibDomainMetaDataQuery query = MetaDataQueryFactory.getInstance().createQuery(context);
    		final Entity entity = query.getQueryHelper().getEntity(uri, entityKey);
    		Trait trait = query.getQueryHelper().getTrait(entity, CONTRIBUTES_VALUE_BINDING);
//            final ITaglibDomainMetaDataModelContext mdContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, uri);
//            Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, CONTRIBUTES_VALUE_BINDING);

            final boolean contribsValueBindings = TraitValueHelper.getValueAsBoolean(trait);

            if (contribsValueBindings)
            {
                String scope = null;
                String symbolFactory = null;

                trait = query.getQueryHelper().getTrait(entity, VALUE_BINDING_SCOPE);
                scope = TraitValueHelper.getValueAsString(trait);

                if (scope != null && !scope.equals("")) //$NON-NLS-1$
                {
                    trait = query.getQueryHelper().getTrait(entity, VALUE_BINDING_SYMBOL_FACTORY);
                    symbolFactory = TraitValueHelper.getValueAsString(trait);
                }

                trait = query.getQueryHelper().getTrait(entity, STATIC_TYPE_KEY);

                String staticType = null;

                if (trait != null)
                {
                    staticType = TraitValueHelper.getValueAsString(trait);
                }

                trait = query.getQueryHelper().getTrait(entity, VALUEEXPRESSION_ATTR_NAME_KEY);

                String valueExprAttr = null;
                if (trait != null)
                {
                    valueExprAttr = TraitValueHelper.getValueAsString(trait);
                }

                return new SymbolContribAggregator(scope, symbolFactory, staticType, valueExprAttr);
            }

            return null;
        }

        private final Map<String, String>   _metadata = new HashMap<String, String>(4);

        SymbolContribAggregator(final String scope, final String factory, final String staticType, final String valueExprAttr)
        {
            _metadata.put("scope", scope); //$NON-NLS-1$
            _metadata.put("factory", factory); //$NON-NLS-1$
            _metadata.put("staticType", staticType); //$NON-NLS-1$
            _metadata.put("valueExprAttr", valueExprAttr); //$NON-NLS-1$
        }

        /**
         * @return the scope
         */
        public String getScope()
        {
            return _metadata.get("scope"); //$NON-NLS-1$
        }

        /**
         * @return the factory
         */
        public AbstractContextSymbolFactory getFactory()
        {
            return JSFCommonPlugin.getSymbolFactories().get(_metadata.get("factory")); //$NON-NLS-1$
        }

        public String getStaticType()
        {
            return _metadata.get("staticType"); //$NON-NLS-1$
        }

        public String getValueExpressionAttr()
        {
            return _metadata.get("valueExprAttr"); //$NON-NLS-1$
        }
    }

    private final static class CountingMutex extends Object
    {
        private long                    _lastModificationStamp = -1;
        private boolean _signalled = false;
        private final ILock _lock = Job.getJobManager().newLock();

        /**
         * Similar to AtomicBoolean.compareAndSet.  If the signalled flag
         * is the same as expect then update is written to the flag.  Otherwise,
         * nothing happens.
         * @param expect the value of _signalled where update occurs
         * @param update the value written to _signalled if _signalled == expect
         * 
         * @return true if the signalled flag was set to update
         */
        public boolean compareAndSetSignalled(final boolean expect, final boolean update) {
            final boolean[] value = new boolean[1];
            safeRun(new Runnable() {
            public void run()
            {
                if (_signalled == expect)
                {
                    _signalled = update;
                    value[0] = true;
                }
                else
                {
                    value[0] = false;
                }
            }});      
            return value[0];
        }

        public boolean hasChanged(final long currentModificationStamp)
        {
            final boolean[] value = new boolean[1];
            safeRun(new Runnable() {
            public void run()
            {
                value[0] = (_lastModificationStamp != currentModificationStamp);
            }});                
            return value[0];
        }

        /**
         * @param signalled
         */
        public void setSignalled(final boolean signalled) {
            safeRun(new Runnable() {
                public void run()
                {
                    _signalled = signalled;
                }});
        }

        public void setModificationStamp(final long newValue)
        {
            safeRun(new Runnable() {
                public void run()
                {
                    _lastModificationStamp = newValue;
                }});
        }
        
        private void safeRun(final Runnable runnable)
        {
            _lock.acquire();
            try
            {
                runnable.run();
            }
            finally
            {
                _lock.release();
            }
        }
    }
}
