/*******************************************************************************
 * Copyright (c) 2007, 2008, 2009 THALES GLOBAL SERVICES.
 * 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:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.query.legacy.business.internal.interpreter;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IVariableStatusListener;
import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
import org.eclipse.sirius.ext.base.collect.StackEx;
import org.eclipse.sirius.query.legacy.AcceleoInterpreterPlugin;
import org.eclipse.sirius.query.legacy.ecore.factories.FactoryException;
import org.eclipse.sirius.query.legacy.gen.template.Template;
import org.eclipse.sirius.query.legacy.gen.template.TemplateConstants;
import org.eclipse.sirius.query.legacy.gen.template.TemplateElement;
import org.eclipse.sirius.query.legacy.gen.template.eval.ENode;
import org.eclipse.sirius.query.legacy.gen.template.eval.ENodeCastException;
import org.eclipse.sirius.query.legacy.gen.template.eval.ENodeException;
import org.eclipse.sirius.query.legacy.gen.template.eval.ENodeIterator;
import org.eclipse.sirius.query.legacy.gen.template.eval.ENodeList;
import org.eclipse.sirius.query.legacy.gen.template.eval.LaunchManager;
import org.eclipse.sirius.query.legacy.gen.template.scripts.SpecificScript;
import org.eclipse.sirius.query.legacy.tools.classloaders.AcceleoClassLoader;

/**
 * This utility class ease the evaluation of Acceleo expressions. A singleton
 * instance is available for pure API comfort but it is advised for performances
 * issues to avoid changing metamodel on consecutive evaluations.
 * 
 * @author cbrun
 * 
 */
// CHECKSTYLE:OFF
public abstract class AcceleoInterpreter implements IInterpreter, IInterpreterProvider, IProposalProvider {
    // CHECKSTYLE:ON
    /**
     * Keyword used to identify a variable.
     */
    protected static final String VARIABLE_KEYWORD = "$";

    /**
     * Keyword used to identify the start of an expression.
     */
    protected static final String PREFIX_KEYWORD = "<%";

    /**
     * Keyword used to identify the end of an expression.
     */
    protected static final String SUFFIX_KEYWORD = "%>";

    /** This will allow us to store the parsed templates for each expressions. */
    protected final Map<SpecificScript, Map<String, Template>> templates = new HashMap<SpecificScript, Map<String, Template>>();

    /**
     * Script instance.
     */
    protected SpecificScript pvScript;

    /**
     * Table keeping track of the variables values.
     */
    protected final Map<String, StackEx<ENode>> variableTables = new HashMap<String, StackEx<ENode>>();

    /**
     * Map used to keep track of the Scripts instances from a metamodel URI.
     */
    protected Map<String, SpecificScript> mmToScript = new WeakHashMap<String, SpecificScript>();

    private final Collection<String> imports = new LinkedHashSet<String>();

    private final Set<IVariableStatusListener> variablesListeners = new HashSet<IVariableStatusListener>();

    /** The optional cache. */
    private Map<CacheKey, ENode> cache;

    private AcceleoTemplateWorkspaceListener templateListener;

    /**
     * Constructor.
     */
    public AcceleoInterpreter() {
        installWorkspaceListener();
    }

    /**
     * Return a script able to evaluate expression on the given EObject.
     * 
     * @param current
     *            current {@link EObject}.
     * @return a script able to evaluate expression on the given EObject.
     */
    protected final SpecificScript getScript(final EObject current) {
        /*
         * we keep one script per metamodel.
         */
        final String mmURI = computeMetamodelURI(current);
        final SpecificScript resultScript = mmToScript.get(mmURI);
        if (resultScript != null)
            return resultScript;
        final SpecificScript newScript = createNewScript(current, mmURI);
        mmToScript.put(mmURI, newScript);
        return newScript;
    }

    /**
     * 
     * {@inheritDoc}
     */
    protected abstract SpecificScript createNewScript(final EObject current, final String mmURI);

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluate(org.eclipse.emf.ecore.EObject,
     *      java.lang.String)
     */
    public Object evaluate(final EObject target, final String expression) throws EvaluationException {
        final ENode node = evaluateENode(target, expression);
        return getValue(node, expression);
    }

    /**
     * Evaluate the given expression and return the result.
     * 
     * @param eObj
     *            : the EObject on which we want to apply the evaluation.
     * @param expression
     *            : the Acceleo expression to evaluate, something like
     *            "<%eContainer()%>" but may also be "name : <%name%>".
     * @return : the {@link ENode} corresponding to this evaluation, and
     *         {@link ENode} wrap any possible type Acceleo may use.
     * @throws EvaluationException
     *             on evaluation errors.
     */
    public ENode evaluateENode(final EObject eObj, final String expression) throws EvaluationException {
        try {
            /*
             * We need to set the preferred loader here in order
             * to have Acceleo use the same class loader to create and evaluate
             * the script so as to avoid LinkageErrors. It will be reverted back
             * to null post-evaluation. IMPORTANT : the preferred class loader
             * MUST be set everywhere we instantiate or evaluate a
             * SpecificScript. See
             * AcceleoExtendedInterpreter#createNewScript(EObject, String) and
             * SiriusInformationAdapter#getAdapter(Object, Class).
             */
            AcceleoClassLoader.setPreferredClassLoader(eObj.getClass().getClassLoader());
            final SpecificScript script = getScript(eObj);
            Template template = null;
            if (expression != null && expression.trim().length() > 0) {
                Map<String, Template> scriptTemplates = templates.get(script);
                if (scriptTemplates != null && scriptTemplates.containsKey(expression)) {
                    template = scriptTemplates.get(expression);
                } else {
                    template = Template.from(expression, script, eObj);
                    if (scriptTemplates == null) {
                        scriptTemplates = new WeakHashMap<String, Template>();
                        templates.put(script, scriptTemplates);
                    }
                    scriptTemplates.put(expression, template);
                }
            }
            if (template != null)
                return template.evaluate(eObj, LaunchManager.create("run", false));
            AcceleoClassLoader.setPreferredClassLoader(null);
            return new ENode(null, (TemplateElement) null, true);
        } catch (final ENodeException e) {
            throw new EvaluationException(e);
        } catch (final FactoryException e) {
            throw new EvaluationException(e);
        }
    }

    /**
     * Evaluate an acceleo condition. The result is <code>true</code> if the
     * evaluation returns a <code>true</code> value or if the evaluation returns
     * a non null object. If the condition is null or empty or only composed
     * with white spaces, the result is <code>true</code>.
     * 
     * @param eObj
     *            the context object.
     * @param condition
     *            the condition to test.
     * @return <code>true</code> if the evaluation returns a <code>true</code>
     *         value or if the evaluation returns a non null object or if the
     *         condition is empty.
     * @throws EvaluationException
     *             if the interpreter encounter a problem while evaluting the
     *             condition.
     * @deprecated use {@link AcceleoInterpreter#evaluate(EObject, String)}
     *             instead
     */
    @Deprecated
    public boolean evaluateCondition(final EObject eObj, final String condition) throws EvaluationException {
        final boolean preconditionAccepted = true;
        return preconditionAccepted;
    }

    /**
     * return the header of the script containing the imports.
     * 
     * @param metamodelURI
     *            the metamodel uri.
     * @return the header of the script containing the imports.
     */
    protected String getScriptHeader(final String metamodelURI) {
        final String carriage = "\n";
        final StringBuffer header = new StringBuffer("");
        header.append(TemplateConstants.IMPORT_BEGIN).append(carriage);
        header.append(TemplateConstants.MODELTYPE_WORD).append(' ').append(metamodelURI).append(" \n");
        final Iterator<String> it = imports.iterator();
        while (it.hasNext()) {
            final String imp = it.next();
            if (!imp.contains("::")) {
                // Don't try to import Acceleo 3 modules.
                header.append(TemplateConstants.IMPORT_WORD).append(' ').append(imp).append(carriage);
            }
        }
        header.append(carriage).append(TemplateConstants.IMPORT_END);
        return header.toString();
    }

    /**
     * Gets the URI of the metamodel that defines the given object.
     * 
     * @param object
     *            is an object of the model
     * @return the URI of the metamodel
     */
    protected String computeMetamodelURI(final EObject object) {
        if (isDynamic(object)) {
            return computeEcoreFileURI(object);
        } else {
            return computeNsURI(object);
        }
    }

    private String computeEcoreFileURI(final EObject object) {
        final Resource eCoreRes = object.eClass().eResource();
        if (eCoreRes != null && eCoreRes.getURI() != null) {
            final URI ecoreURI = eCoreRes.getURI();
            if (ecoreURI.isPlatformResource()) {
                return ecoreURI.toPlatformString(true);
            }
        }
        return null;
    }

    private boolean isDynamic(final EObject object) {
        return object instanceof DynamicEObjectImpl;
    }

    private String computeNsURI(final EObject object) {
        EPackage p = object.eClass().getEPackage();
        String nsURI = p.getNsURI();
        p = p.getESuperPackage();
        while (p != null) {
            final String currentURI = p.getNsURI();
            if (currentURI != null && currentURI.length() > 0 && !currentURI.startsWith("unused://")) {
                nsURI = currentURI;
            }
            p = p.getESuperPackage();
        }
        return nsURI;
    }

    /**
     * Set a variable in the current interpreter. The user will be able to
     * access the variable value using the "$" prefix.
     * 
     * @param name
     *            the variable name.
     * @param value
     *            the variable value.
     */
    public void setVariable(final String name, final EObject value) {
        setVariable(name, new ENode(value, (TemplateElement) null, true));
    }

    /**
     * Set a variable in the current interpreter. The user will be able to
     * access the variable value using the "$" prefix.
     * 
     * @param name
     *            the variable name.
     * @param value
     *            the variable value.
     */
    public void setVariable(final String name, final Object value) {
        final ENode valueNode = ENode.createTry(value, new ENode(null, (TemplateElement) null, true));
        setVariable(name, valueNode);
    }

    /**
     * Set a variable in the current interpreter. The user will be able to
     * access the variable value using the "$" prefix.
     * 
     * @param name
     *            the variable name.
     * @param value
     *            the variable value.
     */
    public void setVariable(final String name, final ENode value) {
        StackEx<ENode> values = variableTables.get(name);
        if (values == null) {
            values = new StackEx<ENode>();
        }
        values.push(value);
        variableTables.put(name, values);
        notifyVariableListeners();
    }

    /**
     * Unset the variable.
     * 
     * @param name
     *            the variable name.
     */
    public void unSetVariable(final String name) {
        final StackEx<ENode> values = variableTables.get(name);
        if (values != null) {
            if (values.size() > 1) {
                /*
                 * There is another value in the stack, let's pop the old one.
                 */
                values.pop();
            } else {
                /*
                 * It was the last value in the stack, let's clear this variable
                 * entry.
                 */
                clearVariable(name);
            }
        }
        notifyVariableListeners();
    }

    /**
     * return the variable value.
     * 
     * @param name
     *            the variable name.
     * @return the variable value.
     */
    protected ENode getVariableValue(final String name) {
        final StackEx<ENode> values = variableTables.get(name);
        if (values != null)
            return values.peek();
        return null;
    }

    /**
     * Check if the variable is set.
     * 
     * @param name
     *            the variable name
     * @return <code>true</code> is the variable is set, <code>false</code>
     *         otherwise
     */
    protected boolean isVariableSet(final String name) {
        return variableTables.containsKey(name);
    }

    /**
     * Clear all the variables of the interpreter.
     */
    public void clearVariables() {
        variableTables.clear();
        notifyVariableListeners();
    }

    /**
     * Clear the variable with the given name.
     * 
     * @param name
     *            : name of the variable to clear.
     */
    public void clearVariable(final String name) {
        if (variableTables.containsKey(name)) {
            variableTables.remove(name);
            notifyVariableListeners();
        }
    }

    /**
     * Clear all the imports.
     */
    public void clearImports() {
        mmToScript.clear();
        templates.clear();
        imports.clear();
    }

    /**
     * Import a Java service or a template in the current Interpreter.
     * 
     * @param path
     *            the import id, for instance
     *            <tt>fr.obeo.my.package.java.StringServices</tt>
     */
    public void addImport(final String path) {
        if (path != null && path.contains(".") && !imports.contains(path)) {
            mmToScript.clear();
            templates.clear();
            imports.add(path);
        }
        templates.clear();
    }

    /**
     * Add a new listener to the current interpreter, the listener will be
     * notified on changes concerning variables.
     * 
     * @param newListener
     *            the new listener to add.
     */
    public void addVariableStatusListener(final IVariableStatusListener newListener) {
        variablesListeners.add(newListener);
    }

    /**
     * Remove the given {@link IVariableStatusListener}.
     * 
     * @param listener
     *            listener to remove.
     */
    public void removeVariableStatusListener(final IVariableStatusListener listener) {
        variablesListeners.remove(listener);
    }

    /**
     * Map with the variables.
     * 
     * @return a map containing the current variables.
     */
    public Map<String, ?> getVariables() {
        final Map<String, ENode> lightVariables = new HashMap<String, ENode>();
        final Iterator<String> it = variableTables.keySet().iterator();
        while (it.hasNext()) {
            final String variableName = it.next();
            lightVariables.put(variableName, getVariableValue(variableName));
        }
        return lightVariables;
    }

    private void notifyVariableListeners() {
        if (variablesListeners.size() > 0) {
            final Map<String, ?> lightVariables = getVariables();
            final Iterator<IVariableStatusListener> it = variablesListeners.iterator();
            while (it.hasNext()) {
                final IVariableStatusListener listener = it.next();
                listener.notifyChanged(lightVariables);
            }
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateBoolean(EObject,
     *      String)
     */
    @Deprecated
    public boolean getAsBoolean(final Object evaluate) {
        return internalGetAsBoolean(evaluate);
    }

    private boolean internalGetAsBoolean(final Object evaluate) {
        boolean result = false;
        if (evaluate instanceof ENode) {
            result = ENodeHelper.getAsBoolean((ENode) evaluate);
        } else if (evaluate instanceof Boolean) {
            result = ((Boolean) evaluate).booleanValue();
        } else if (evaluate instanceof String) {
            result = Boolean.parseBoolean((String) evaluate);
        } else if (evaluate instanceof IAdaptable) {
            final Boolean adaptedBoolean = (Boolean) ((IAdaptable) evaluate).getAdapter(Boolean.class);
            if (adaptedBoolean != null)
                result = adaptedBoolean.booleanValue();
        } else if (evaluate != null) {
            // in acceleo, if (something) returns true
            result = true;
        }
        return result;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateEObject(EObject,
     *      String)
     */
    @Deprecated
    public EObject getAsEObject(final Object result) {
        return internalGetAsEObject(result);
    }

    private EObject internalGetAsEObject(final Object result) {
        EObject eObject = null;
        if (result instanceof ENode) {
            eObject = ENodeHelper.getAsEObject((ENode) result);
        } else if (result instanceof EObject) {
            eObject = (EObject) result;
        } else if (result instanceof IAdaptable) {
            eObject = (EObject) ((IAdaptable) result).getAdapter(EObject.class);
        } else if (result instanceof ENodeList) {
            final ENodeList eNodeList = (ENodeList) result;
            if (eNodeList.size() > 0) {
                eObject = internalGetAsEObject(eNodeList.get(0));
            }
        } else if (result instanceof Collection) {
            final Collection<?> collection = (Collection<?>) result;
            if (!collection.isEmpty()) {
                final Object first = collection.iterator().next();
                eObject = internalGetAsEObject(first);
            }
        }
        return eObject;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateInteger(EObject,
     *      String)
     */
    @Deprecated
    public Integer getAsInteger(final Object result) {
        return internalGetAsInteger(result);
    }

    private Integer internalGetAsInteger(final Object result) {
        Integer integer = null;
        if (result instanceof ENode) {
            integer = ENodeHelper.getAsInteger((ENode) result);
        } else if (result instanceof Integer) {
            integer = (Integer) result;
        } else if (result instanceof IAdaptable) {
            integer = (Integer) ((IAdaptable) result).getAdapter(Integer.class);
        } else if (result instanceof String) {
            try {
                final int res = Integer.parseInt((String) result);
                integer = Integer.valueOf(res);
            } catch (final NumberFormatException e) {
                // silent
            }
        }
        return integer;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateBoolean(EObject,
     *      String)
     */
    @Deprecated
    public Collection<EObject> getAsListOfEObjects(final Object object) {
        return internalGetAsListOfEObjects(object);
    }

    private Collection<EObject> internalGetAsListOfEObjects(final Object object) {
        Collection<EObject> result = new LinkedList<EObject>();
        if (object instanceof Collection) {
            final Collection<?> tmp = (Collection<?>) object;
            for (final Object obj : tmp) {
                if (obj instanceof EObject) {
                    result.add((EObject) obj);
                }
            }
        } else if (object instanceof ENode) {
            result = ENodeHelper.getAsListOfEObjects((ENode) object);
        } else if (object instanceof EObject) {
            result.add((EObject) object);
        }
        return result;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateString(EObject,
     *      String)
     */
    @Deprecated
    public String getAsString(final Object result) {
        return internalGetAsString(result);
    }

    private String internalGetAsString(final Object result) {
        if (result instanceof ENode) {
            return ENodeHelper.getAsString((ENode) result);
        }
        return result != null ? result.toString() : null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getValue(java.lang.Object,
     *      java.lang.String)
     */
    public Object getValue(final Object object, final String s) {
        Object result = object;
        if (object instanceof ENode) {
            result = ENodeHelper.getValue((ENode) result, s);
        }
        return result;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#provides(java.lang.String)
     */
    public boolean provides(final String expression) {
        return expression != null && expression.indexOf(PREFIX_KEYWORD) >= 0;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateBoolean(org.eclipse.emf.ecore.EObject,
     *      java.lang.String)
     */
    public boolean evaluateBoolean(final EObject context, final String expression) throws EvaluationException {
        final Object evaluation = evaluate(context, expression);
        return internalGetAsBoolean(evaluation);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateCollection(org.eclipse.emf.ecore.EObject,
     *      java.lang.String)
     */
    public Collection<EObject> evaluateCollection(final EObject context, final String expression) throws EvaluationException {
        final Object evaluation = evaluate(context, expression);
        return internalGetAsListOfEObjects(evaluation);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateEObject(org.eclipse.emf.ecore.EObject,
     *      java.lang.String)
     */
    public EObject evaluateEObject(final EObject context, final String expression) throws EvaluationException {
        final Object evaluation = evaluate(context, expression);
        return internalGetAsEObject(evaluation);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateInteger(org.eclipse.emf.ecore.EObject,
     *      java.lang.String)
     */
    public Integer evaluateInteger(final EObject context, final String expression) throws EvaluationException {
        final Object evaluation = evaluate(context, expression);
        return internalGetAsInteger(evaluation);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#evaluateString(org.eclipse.emf.ecore.EObject,
     *      java.lang.String)
     */
    public String evaluateString(final EObject context, final String expression) throws EvaluationException {
        final Object evaluation = evaluate(context, expression);
        return internalGetAsString(evaluation);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getVariable(java.lang.String)
     */
    public Object getVariable(final String name) {
        final ENode node = getVariableValue(name);
        return getValue(node, "");
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#setProperty(java.lang.Object,
     *      java.lang.Object)
     */
    public void setProperty(final Object key, final Object value) {
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#dispose()
     */
    public void dispose() {
        for (final Map.Entry<SpecificScript, Map<String, Template>> child : templates.entrySet())
            child.getValue().clear();
        templates.clear();
        this.variableTables.clear();
        this.variablesListeners.clear();
        this.imports.clear();
        this.deactivateCache();
        uninstallWorkspaceListener();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#setModelAccessor(org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor)
     */
    public void setModelAccessor(final ModelAccessor modelAccessor) {
        // ignore.
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreterProvider#createInterpreter()
     */
    public abstract IInterpreter createInterpreter();

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider#getProposals(org.eclipse.sirius.common.tools.api.interpreter.IInterpreter,
     *      org.eclipse.sirius.common.tools.api.contentassist.ContentContext)
     */
    public List<ContentProposal> getProposals(IInterpreter interpreter, ContentContext context) {
        return getCompletionEntry().computeProposals(context);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getPrefix()
     */
    public String getPrefix() {
        return PREFIX_KEYWORD;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getNewEmtpyExpression()
     */
    public ContentProposal getNewEmtpyExpression() {
        return new ContentProposal(PREFIX_KEYWORD + SUFFIX_KEYWORD, PREFIX_KEYWORD + SUFFIX_KEYWORD, "New legacy query language expression.", 2);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getVariablePrefix()
     */
    public String getVariablePrefix() {
        return VARIABLE_KEYWORD;
    }

    /**
     * 
     * {@inheritDoc}
     */
    public void setCrossReferencer(final ECrossReferenceAdapter crossReferencer) {
        // no handling of cross referencer with specific script. (yet ;) )
    }

    /**
     * Returns the result of the evaluation from the cache.
     * 
     * @param context
     *            the context of the evaluation.
     * @param evaluation
     *            the evaluation.
     * @param args
     *            the arguments of the evaluation.
     * @return the result of the evaluation from the cache.
     */
    protected ENode getFromCache(final ENode context, final String evaluation, final ENode[] args) {
        if (cache != null) {
            return cache.get(new CacheKey(context, evaluation, args));
        }
        return null;
    }

    /**
     * Caches an evaluation.
     * 
     * @param context
     *            the context.
     * @param evaluation
     *            the evaluation.
     * @param args
     *            the arguments of the evaluation.
     * @param result
     *            the result of the evaluation.
     */
    protected void cache(final ENode context, final String evaluation, final ENode[] args, final ENode result) {
        if (cache != null)
            cache.put(new CacheKey(context, evaluation, args), result);
    }

    /**
     * Activates the cache.
     */
    public void activateCache() {
        if (this.cache == null)
            this.cache = new HashMap<CacheKey, ENode>();
    }
    
    /**
     * {@inheritDoc}
     *
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#activateMetamodels(java.util.Collection)
     */
    public void activateMetamodels(Collection<MetamodelDescriptor> metamodels) {
        // Nothing to do
    }

    /**
     * Deactivates the cache.
     */
    public void deactivateCache() {
        if (this.cache != null) {
            this.cache.clear();
            this.cache = null;
        }
    }

    /**
     * Inner Class CacheKey
     */
    private static class CacheKey {

        private ENode context;

        private String evaluation;

        private ENode[] args;

        public CacheKey(final ENode context, final String evaluation, final ENode[] args) {
            this.context = context;
            this.evaluation = evaluation;
            this.args = args;
        }

        /**
         * {@inheritDoc}
         * 
         * @see java.lang.Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + (evaluation == null ? 0 : evaluation.hashCode());
            result = prime * result + (context == null ? 0 : hashCode(context));
            for (ENode node : args) {
                result = prime * result + (node == null ? 0 : hashCode(node));
            }
            return result;
        }

        private int hashCode(final ENode node) {
            int value = 0;
            if (node.getValue() != null) {
                if (!node.isList()) {
                    return node.getValue().hashCode();
                } else {
                    try {
                        final ENodeIterator iterNodes = node.getList().iterator();
                        while (iterNodes.hasNext()) {
                            value += hashCode(iterNodes.next());
                        }
                    } catch (final ENodeCastException e) {
                        AcceleoInterpreterPlugin.getDefault().error(e.getMessage(), e);
                    }
                }
            }
            return value;
        }

        /**
         * {@inheritDoc}
         * 
         * @see java.lang.Object#equals(java.lang.Object)
         */
        @Override
        public boolean equals(final Object obj) {
            boolean result = false;
            if (obj instanceof CacheKey) {
                result = equals((CacheKey) obj);
            }
            return result;
        }

        private boolean equals(final CacheKey cacheKey) {
            final boolean node = (this.context == null && cacheKey.context == null) || (this.context != null && this.context.equals((Object) cacheKey.context));
            final boolean eval = node && ((this.evaluation == null && cacheKey.evaluation == null) || (this.evaluation != null && this.evaluation.equals(cacheKey.evaluation)));
            boolean result = eval && this.args.length == cacheKey.args.length;
            for (int i = 0; i < args.length && result; i++) {
                result = this.args[i].equals((Object) cacheKey.args[i]);
            }
            return result;
        }

    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider#getProposals(org.eclipse.sirius.common.tools.api.interpreter.IInterpreter,
     *      org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext)
     */
    public List<ContentProposal> getProposals(IInterpreter interpreter, ContentInstanceContext context) {
        final String textSoFar = context.getTextSoFar();
        String evaluationString = textSoFar.substring(0, context.getCursorPosition());

        if (evaluationString.toLowerCase().startsWith(PREFIX_KEYWORD)) {
            // Ask AcceleoCompletionEntry for proposals and process them
            List<ContentProposal> resultList = getCompletionEntry().computeProposals(context);
            if (resultList.size() > 0) {
                return resultList;
            }
        }

        return Collections.emptyList();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#getImports()
     */
    public Collection<String> getImports() {
        return Collections.<String> unmodifiableCollection(this.imports);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreter#removeImport(String)
     */
    public void removeImport(String dependency) {
        if (this.imports.contains(dependency)) {
            this.imports.remove(dependency);
            mmToScript.clear();
        }
        templates.clear();
    }

    protected AcceleoCompletionEntry getCompletionEntry() {
        return new AcceleoCompletionEntry();
    }

    /**
     * install workspace listener
     */
    private void installWorkspaceListener() {
        if (templateListener == null) {
            templateListener = new AcceleoTemplateWorkspaceListener(this);
            final IWorkspace workspace = ResourcesPlugin.getWorkspace();
            workspace.addResourceChangeListener(templateListener);
        }
    }

    /**
     * uninstall workspace listener.
     */
    private void uninstallWorkspaceListener() {
        if (templateListener != null) {
            final IWorkspace workspace = ResourcesPlugin.getWorkspace();
            workspace.removeResourceChangeListener(templateListener);
            templateListener = null;
        }
    }

    /**
     * Clear templates stored.
     */
    protected void reconsiderTemplateFiles() {
        for (final Map.Entry<SpecificScript, Map<String, Template>> child : templates.entrySet())
            child.getValue().clear();

        mmToScript.clear();
        templates.clear();
    }

}
