/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.royale.compiler.internal.definitions;

import static org.apache.royale.compiler.common.ISourceLocation.UNKNOWN;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.royale.abc.ABCConstants;
import org.apache.royale.abc.semantics.Name;
import org.apache.royale.abc.semantics.Namespace;
import org.apache.royale.abc.semantics.Nsset;
import org.apache.royale.compiler.asdoc.IASDocComment;
import org.apache.royale.compiler.common.ASModifier;
import org.apache.royale.compiler.common.DependencyType;
import org.apache.royale.compiler.common.ModifiersSet;
import org.apache.royale.compiler.common.NodeReference;
import org.apache.royale.compiler.config.CompilerDiagnosticsConstants;
import org.apache.royale.compiler.constants.IASLanguageConstants;
import org.apache.royale.compiler.constants.IMetaAttributeConstants;
import org.apache.royale.compiler.constants.INamespaceConstants;
import org.apache.royale.compiler.definitions.IAccessorDefinition;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.IDocumentableDefinition;
import org.apache.royale.compiler.definitions.INamespaceDefinition;
import org.apache.royale.compiler.definitions.IPackageDefinition;
import org.apache.royale.compiler.definitions.IScopedDefinition;
import org.apache.royale.compiler.definitions.metadata.IDeprecationInfo;
import org.apache.royale.compiler.definitions.metadata.IMetaTag;
import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
import org.apache.royale.compiler.definitions.references.INamespaceReference;
import org.apache.royale.compiler.definitions.references.INamespaceResolvedReference;
import org.apache.royale.compiler.definitions.references.IReference;
import org.apache.royale.compiler.filespecs.IFileSpecification;
import org.apache.royale.compiler.internal.common.Counter;
import org.apache.royale.compiler.internal.definitions.metadata.DeprecationInfo;
import org.apache.royale.compiler.internal.definitions.metadata.MetaTag;
import org.apache.royale.compiler.internal.parsing.as.OffsetLookup;
import org.apache.royale.compiler.internal.projects.CompilerProject;
import org.apache.royale.compiler.internal.projects.RoyaleProject;
import org.apache.royale.compiler.internal.scopes.ASFileScope;
import org.apache.royale.compiler.internal.scopes.ASProjectScope;
import org.apache.royale.compiler.internal.scopes.ASScope;
import org.apache.royale.compiler.internal.scopes.ASScopeBase;
import org.apache.royale.compiler.internal.scopes.SWCFileScopeProvider.SWCFileScope;
import org.apache.royale.compiler.mxml.IMXMLTagData;
import org.apache.royale.compiler.projects.ICompilerProject;
import org.apache.royale.compiler.scopes.IASScope;
import org.apache.royale.compiler.scopes.IDefinitionSet;
import org.apache.royale.compiler.tree.as.IASNode;
import org.apache.royale.compiler.tree.as.IDefinitionNode;
import org.apache.royale.compiler.tree.as.IDocumentableDefinitionNode;
import org.apache.royale.compiler.tree.as.IExpressionNode;
import org.apache.royale.compiler.units.ICompilationUnit;

/**
 * This class is the abstract base class for all ActionScript definitions in the
 * symbol table.
 * <p>
 * After definitions are added to the symbol table, they should always be
 * accessed through the read-only definition interfaces (which are
 * <code>IDefinition</code> and its subinterfaces) rather than through these
 * implementation classes.
 * <p>
 * Note that this class also implements {@link IDefinitionSet} so that a
 * scope's map can point to a single definition acting as it own
 * definition-set-of-size-1.
 */
public abstract class DefinitionBase implements IDocumentableDefinition, IDefinitionSet
{
    // Mask constants for bitflags in the 'flags' field,
    // a short value that we use in place of multiple boolean fields.
    protected static final short FLAG_CAST_FUNCTION = 1 << 0;
    protected static final short FLAG_CONSTRUCTOR = 1 << 1;
    protected static final short FLAG_DYNAMIC = 1 << 2;
    protected static final short FLAG_FINAL = 1 << 3;
    protected static final short FLAG_IMPLICIT = 1 << 4;
    protected static final short FLAG_NATIVE = 1 << 5;
    protected static final short FLAG_OVERRIDE = 1 << 6;
    protected static final short FLAG_REST = 1 << 7;
    protected static final short FLAG_STATIC = 1 << 8;
    protected static final short FLAG_DEFAULT = 1 << 9;
    protected static final short FLAG_CONTINGENT = 1 << 10;
    protected static final short FLAG_GENERATED_EMBED_CLASS = 1 << 11;
    protected static final short FLAG_HAS_INIT = 1 << 12;
    protected static final short FLAG_DEPRECATED = 1 << 13;
    protected static final short FLAG_DECLARED_IN_CONTROL_FLOW = 1 << 14;

    /**
     * Constructor.
     * 
     * @param name The "constructor name" of the definition.
     * This is currently in an inconsistent form; for example,
     * for the <code>flash.display.Sprite</code> class definition
     * constructed from source code it is <code>"Sprite"</code>
     * but for the same definition constructed from ABC it is
     * <code>"flash.display.Sprite"</code>.
     * The "constructor name" will be converted to a "storage name"
     * and stored in the <code>storageName</code> field.
     */
    // TODO Fix construction of definitions so that
    // the storage name is always passed in.
    public DefinitionBase(String name)
    {
        assert name != null;
        this.storageName = toStorageName(name);
        
        if (Counter.COUNT_DEFINITIONS)
            countDefinitions();
    }

    // The scope that contains this definition.
    // This field is set when the addDefinition() method of ASScope
    // calls the package-private setContainingScope() method of this class.
    private IASScope containingScope;

    // Bit flags for this definition, such as whether it is implicit.
    protected short flags;

    // The namespace reference for this definition.
    // For most definitions this will be non-null, even if no namespace was specified
    // in the source code. For example, if the namespace is omitted on a member of a class,
    // "internal" is implied; therefore this field will be a reference to the internal
    // namespace for the package containing the class. However, some types of definitions,
    // such as a for a function parameter, do have a null namespace reference.
    private INamespaceResolvedReference namespaceReference;

    // The name stored for this definition. See getStorageName() for details.
    private final String storageName;

    // The type reference for this definition. See getTypeReference() for details.
    // Note that this is an IReference, which is basically a reference-by-name
    // to a definition, which can resolve to different definitions in different projects.
    private IReference typeReference;

    // metaTags is never null. As an optimization, it re-uses a singleton empty array when
    // it has nothing in it
    private IMetaTag[] metaTags = singletonEmptyMetaTags;

    protected static final IMetaTag[] singletonEmptyMetaTags = new IMetaTag[0];

    // Hold a reference to the node this definition came from
    // (NodeReference only holds onto the node weakly, so we don't have to worry about leaks).
    protected NodeReference nodeRef = NodeReference.noReference;

    private int absoluteNameStart = 0;
    private int absoluteNameEnd = 0;
    
    private IDefinition parentDef = null;

    /**
     * Called by {@code MXMLScopeBuilder} when building definitions from
     * {@code MXMLData}. Creates a nodeless {@code NodeReference} for this
     * definition that keeps track of the file and offset for the MXML tag that
     * produced this definition. Later, after the MXML tree is produced, this
     * {@code NodeReference} can be used to locate the appropriate tree node.
     * 
     * @param tag The {@code MXMLTagData} that is producing this definition.
     */
    public void setLocation(IMXMLTagData tag)
    {
        nodeRef = new NodeReference(tag.getSource(), tag.getAbsoluteStart());
    }

    /**
     * Attaches a weak reference to the source node that produced this
     * definition, and copies over enough source-location information to
     * re-associate the node if it is garbage-collected.
     * 
     * @param node The {@link IDefinitionNode} that is producing
     * this definition.
     */
    public void setNode(IDefinitionNode node)
    {
        if (node == null)
        {
            nodeRef = NodeReference.noReference;

            absoluteNameStart = UNKNOWN;
            absoluteNameEnd = UNKNOWN;
        }
        else
        {
            nodeRef = new NodeReference(node);

            IExpressionNode nameNode = node.getNameExpressionNode();
            if (nameNode != null)
            {
                absoluteNameStart = nameNode.getAbsoluteStart();
                absoluteNameEnd = nameNode.getAbsoluteEnd();
            }
            else
            {
                absoluteNameStart = UNKNOWN;
                absoluteNameEnd = UNKNOWN;
            }
        }
    }

    /**
     * This method is used to set the name location when there is no name node
     * from which it can be determined.
     */
    public void setNameLocation(int absoluteNameStart, int absoluteNameEnd)
    {
        this.absoluteNameStart = absoluteNameStart;
        this.absoluteNameEnd = absoluteNameEnd;
    }

    @Override
    public IASScope getContainingScope()
    {
        return containingScope;
    }

    public void setContainingScope(IASScope scope)
    {
        containingScope = scope;
    }

    @Override
    public IDefinition getParent()
    {
    	if (parentDef != null)
    		return parentDef;
    	
        IASScope scope = getContainingScope();

        // Walk up the scope chain until we find a scope that has
        // a containing definition.  The following types of scope do
        // not have an immediate containing definition:
        // CatchScope's
        // WithScope's
        // FunctionScope's for MXML event handler's.
        while ((scope != null) && (scope.getDefinition() == null))
            scope = scope.getContainingScope();

        parentDef = scope != null ? scope.getDefinition() : null;
        return parentDef;
    }

    @Override
    public IDefinition getAncestorOfType(Class<? extends IDefinition> ancestorType)
    {
        IDefinition definition = getParent();
        while (definition != null && !(ancestorType.isInstance(definition)))
            definition = definition.getParent();
        return definition;
    }
    
    // TODO Eliminate this method and its overrides
    // by constructing the definition with its storage name.
    protected String toStorageName(String name)
    {
        // Most constructors pass in either a base name or a qname,
        // which we convert to a base name.
        // However, this method is overridin in DefinitionPromise,
        // PackageDefinition, and AppliedVectorDefinition to NOT
        // reduce the constructor name to a base name.
        int i = name.lastIndexOf('.');
        return i == -1 ? name : name.substring(i + 1);
    }
    
    /**
     *  Gets the name that is actually stored for this definition.
     *  <p>
     *  This is not a public API, and is not in the {@link IDefinition}
     *  interface, because different types of definitions store different
     *  types of names. However, the storage name of a definition does
     *  not depend on whether it came from source code or from ABC.
     *  <p>
     *  For class, interface, function, variable, constant, and namespace
     *  definitions -- whose base name and the qualified name can differ
     *  when the definition is at package scope -- the storage name is the
     *  base name (e.g., <code>"Sprite"</code>,
     *  not <code>"flash.display.Sprite"</code>).
     *  <p>
     *  In the case of vector types, the storage name is a base name
     *  like <code>"Vector.&lt;Sprite&gt;"</code>
     *  (not <code>"Vector.&lt;flash.display.Sprite&gt;"</code>),
     *  which is considered a base name despite technically having a dot.
     *  <p>
     *  For parameter definitions -- which cannot be at package scope -
     *  and for event, style, and effect definitions -- which as metadata
     *  don't live in any scope -- there is no distinction between the base
     *  name and the qualified name; the storage name is the same as both
     *  of these. E.g., <code>i</code> for a parameter definition or
     *  <code>"click"</code> for an event definition.
     *  <p>
     *  For package definitions, the storage name is the package name
     *  (e.g., <code>"flash.display"</code>), which is considered
     *  both the base name and the qualified name of a package definition.
     *  <p>
     *  Finally, for definition promises, the storage name is a dotted,
     *  fully-qualified name (e.g., <code>"flash.display.Sprite"</code>,
     *  not <code>"Sprite"</code>).
     */
    protected final String getStorageName()
    {
        return storageName;
    }

    /**
     */
    public IFileSpecification getFileSpecification()
    {
        return nodeRef.getFileSpecification();
    }

    @Override
    public String getSourcePath()
    {
        IFileSpecification fileSpec = getFileSpecification();
        return fileSpec != null ? fileSpec.getPath() : null;
    }

    private OffsetLookup getOffsetLookup()
    {
        final ASFileScope fileScope = getFileScope();
        if (fileScope == null)
            return null;

        return fileScope.getOffsetLookup();
    }

    @Override
    public int getStart()
    {
        // Because the starting offset is what is used
        // connect a node to a definition,
        // we can't just call getStart() on getNode();
        // because this leads to deadlock.
        // Instead, we have to use the starting offset
        // stored in the NodeReference.

        if (nodeRef == null)
            return UNKNOWN;

        final int absoluteStart = nodeRef.getAbsoluteStart();
        if (absoluteStart == UNKNOWN)
            return UNKNOWN;

        final OffsetLookup offsetLookup = getOffsetLookup();
        if (offsetLookup == null)
            return absoluteStart;

        return offsetLookup.getLocalOffset(absoluteStart);
    }

    @Override
    public int getEnd()
    {
        final IDefinitionNode node = getNode();
        if (node == null)
            return UNKNOWN;

        return node.getEnd();
    }

    @Override
    public int getLine()
    {
        final IDefinitionNode node = getNode();
        if (node == null)
            return UNKNOWN;

        return node.getLine();
    }

    @Override
    public int getColumn()
    {
        final IDefinitionNode node = getNode();
        if (node == null)
            return UNKNOWN;

        return node.getColumn();
    }

    @Override
    public int getAbsoluteStart()
    {
        // Because the starting offset is what is used
        // connect a node to a definition,
        // we can't just call getAbsoluteStart() on getNode();
        // because this leads to deadlock.
        // Instead, we have to use the starting offset
        // stored in the NodeReference.

        if (nodeRef == null)
            return UNKNOWN;

        return nodeRef.getAbsoluteStart();
    }

    @Override
    public int getAbsoluteEnd()
    {
        final IDefinitionNode node = getNode();
        if (node == null)
            return UNKNOWN;

        return node.getAbsoluteEnd();
    }

    private IExpressionNode getNameNode()
    {
        IDefinitionNode node = getNode();
        if (node == null)
            return null;

        return node.getNameExpressionNode();
    }

    @Override
    public int getNameStart()
    {
        if (absoluteNameStart == UNKNOWN)
            return UNKNOWN;

        OffsetLookup offsetLookup = getOffsetLookup();
        if (offsetLookup == null)
            return absoluteNameStart;

        return offsetLookup.getLocalOffset(absoluteNameStart);
    }

    @Override
    public int getNameEnd()
    {
        if (absoluteNameEnd == UNKNOWN)
            return UNKNOWN;

        OffsetLookup offsetLookup = getOffsetLookup();
        if (offsetLookup == null)
            return absoluteNameEnd;

        return offsetLookup.getLocalOffset(absoluteNameEnd);
    }

    /**
     * Get line number for the name of this definition, if it can be determined.
     * 
     * @return the line number, or -1 if we couldn't figure it out
     */
    @Override
    public int getNameLine()
    {
        final IExpressionNode nameNode = getNameNode();
        if (nameNode == null)
            return UNKNOWN;

        return nameNode.getLine();
    }

    /**
     * Get column number for the name of this definition, if it can be
     * determined.
     * 
     * @return the column number, or -1 if we couldn't figure it out
     */
    @Override
    public int getNameColumn()
    {
        final IExpressionNode nameNode = getNameNode();
        if (nameNode == null)
            return UNKNOWN;

        return nameNode.getColumn();
    }

    @Override
    public String getContainingFilePath()
    {
        ASFileScope fileScope = getFileScope();
        if (fileScope == null)
            return null;
        return fileScope.getContainingPath();
    }

    @Override
    public String getContainingSourceFilePath(final ICompilerProject project)
    {
        // If node reference is set, find the source file name from
        // offset lookup
        if (nodeRef != NodeReference.noReference)
        {
            final ASFileScope fileScope = getFileScope();
            if (fileScope != null && fileScope.getOffsetLookup() != null)
            {
                return fileScope.getOffsetLookup().getFilename(getAbsoluteStart());
            }
        }

        ASScope containingScope = (ASScope)getContainingScope();
        if (containingScope != null)
            return containingScope.getContainingSourcePath(getQualifiedName(), project);
        return null;
    }

    private static String namespaceReferenceToPackageName(INamespaceReference nsRef)
    {
        if (nsRef instanceof NamespaceDefinition.INamespaceWithPackageName)
            return ((NamespaceDefinition.INamespaceWithPackageName)nsRef).getNamespacePackageName();
        return null;
    }

    /**
     * 
     * @param definition is the definition whose containing top level definition we want
     * @return the top level deinition, or null if none exists.
     */
    private static DefinitionBase getContainingToplevelDefinition(DefinitionBase definition)
    {
        ASScope currentContainingScope = definition.getContainingASScope();
        DefinitionBase currentDefinition = definition;

        IScopedDefinition containingDefinition = currentContainingScope.getContainingDefinition();
        while (containingDefinition != null)
        {
            currentDefinition = (DefinitionBase)containingDefinition;
            currentContainingScope = currentDefinition.getContainingASScope();
            
            // With some synthetic definitions you can't find a containint top level definition.
            // This happens with Vector<T>, for example. In this case, return null
            if (currentContainingScope == null)
                return null;                    
            
            containingDefinition = currentContainingScope.getContainingDefinition();
        }
        assert currentDefinition != null;
        return currentDefinition;
    }

    @Override
    public String getPackageName()
    {
        // Ugghhh!!  This method is supposed to return the fully qualified name
        // of the package that contains this definition.  The method works even
        // if this definition is not a top level definition.

        // Sub-classes that will never have a containing scope ( like DefinitionPromise's )
        // should overload this method.
        assert getContainingScope() != null : "This method should not be called until we have a containing scope.!";

        // If we get here, we have a containing scope, so we can just walk the scope
        // chain until we get to a definition that is a direct child of a package or file
        // scope.

        DefinitionBase containingToplevelDefinition = getContainingToplevelDefinition(this);
        if (containingToplevelDefinition == null)
        {
            // If there is no containing top level definition they return the top level package.
            // In the case of member functions of the Vector<T> class, this will be correct
            return "";
        }

        assert (!(containingToplevelDefinition instanceof FunctionDefinition)) || (!((FunctionDefinition)containingToplevelDefinition).isConstructor()) : "Constructors should always be contained by class definitions!";

        INamespaceReference toplevelDefinitionNSRef =
                containingToplevelDefinition.getNamespaceReference();

        assert toplevelDefinitionNSRef != null;
        String packageNameFromNSRef = namespaceReferenceToPackageName(toplevelDefinitionNSRef);
        if (packageNameFromNSRef != null)
            return packageNameFromNSRef;

        assert getBaseName().indexOf('.') == -1;
        return "";
    }

    @Override
    public String getBaseName()
    {
        // Most definitions store their base name, so this base method
        // simply returns it. However, a few subclasses override this.
        return storageName;
    }

    @Override
    public String getQualifiedName()
    {
        // For top-level definitions, report the package name concatenated
        // with the base name. If it's not in a package (e.g. a file private
        // definition), then the package name will be "".
        if (isTopLevelDefinition())
        {
            String packageName = getPackageName();
            if (packageName != null && !packageName.isEmpty())
                return packageName + "." + storageName;
        }
        
        return storageName;
    }

    /**
     * Is this definition a toplevel definition
     * 
     * @return true if this definition is declared at file scope, or package
     * scope.
     */
    public boolean isTopLevelDefinition()
    {
        return getParent() instanceof IPackageDefinition || getParent() == null;
    }

    @Override
    public boolean isDynamic()
    {
        return (flags & FLAG_DYNAMIC) != 0;
    }

    public void setDynamic()
    {
        flags |= FLAG_DYNAMIC;
    }

    @Override
    public boolean isFinal()
    {
        return (flags & FLAG_FINAL) != 0;
    }

    public void setFinal()
    {
        flags |= FLAG_FINAL;
    }

    @Override
    public boolean isNative()
    {
        return (flags & FLAG_NATIVE) != 0;
    }

    public void setNative()
    {
        flags |= FLAG_NATIVE;
    }

    @Override
    public boolean isOverride()
    {
        return (flags & FLAG_OVERRIDE) != 0;
    }

    public void setOverride()
    {
        flags |= FLAG_OVERRIDE;
    }

    public void unsetOverride()
    {
        if (isOverride())
            flags -= FLAG_OVERRIDE;
    }

    @Override
    public boolean isStatic()
    {
        return (flags & FLAG_STATIC) != 0;
    }

    public void setStatic()
    {
        flags |= FLAG_STATIC;
    }

    @Override
    public boolean hasModifier(ASModifier modifier)
    {
        // Note: These get checked in decreasing order of frequency of use.

        if (modifier == ASModifier.OVERRIDE)
        {
            return (flags & FLAG_OVERRIDE) != 0;
        }
        else if (modifier == ASModifier.STATIC)
        {
            return (flags & FLAG_STATIC) != 0;
        }
        else if (modifier == ASModifier.FINAL)
        {
            return (flags & FLAG_FINAL) != 0;
        }
        else if (modifier == ASModifier.DYNAMIC)
        {
            return (flags & FLAG_DYNAMIC) != 0;
        }
        else if (modifier == ASModifier.NATIVE)
        {
            return (flags & FLAG_NATIVE) != 0;
        }
        else if (modifier == ASModifier.VIRTUAL)
        {
            // Ignore "virtual" modifier.
            return false;
        }
        else
        {
            assert false : "Unknown modifier: " + modifier;
            return false;
        }
    }

    @Override
    public ModifiersSet getModifiers()
    {
        ModifiersSet result = new ModifiersSet();
        if ((flags & FLAG_OVERRIDE) != 0)
            result.addModifier(ASModifier.OVERRIDE);
        if ((flags & FLAG_STATIC) != 0)
            result.addModifier(ASModifier.STATIC);
        if ((flags & FLAG_FINAL) != 0)
            result.addModifier(ASModifier.FINAL);
        if ((flags & FLAG_DYNAMIC) != 0)
            result.addModifier(ASModifier.DYNAMIC);
        if ((flags & FLAG_NATIVE) != 0)
            result.addModifier(ASModifier.NATIVE);
        return result;
    }

    public void setModifier(ASModifier modifier)
    {
        // Note: These get checked in decreasing order of frequency of use.

        if (modifier == ASModifier.OVERRIDE)
            flags |= FLAG_OVERRIDE;

        else if (modifier == ASModifier.STATIC)
            flags |= FLAG_STATIC;

        else if (modifier == ASModifier.FINAL)
            flags |= FLAG_FINAL;

        else if (modifier == ASModifier.DYNAMIC)
            flags |= FLAG_DYNAMIC;

        else if (modifier == ASModifier.NATIVE)
            flags |= FLAG_NATIVE;

        else
            assert false;
    }

    @Override
    public boolean isPublic()
    {
        return namespaceReference instanceof INamespaceDefinition.IPublicNamespaceDefinition;
    }

    @Override
    public boolean isPrivate()
    {
        return namespaceReference instanceof INamespaceDefinition.IPrivateNamespaceDefinition;
    }

    @Override
    public boolean isProtected()
    {
        return namespaceReference instanceof INamespaceDefinition.IProtectedNamespaceDefinition;
    }

    @Override
    public boolean isInternal()
    {
        return namespaceReference instanceof INamespaceDefinition.IInternalNamespaceDefinition;
    }

    @Override
    public boolean hasNamespace(INamespaceReference namespace, ICompilerProject project)
    {
        // If the namespaces being compared are language namespaces
        // (which have singleton NamespaceReferences)
        // then we can just compare the NamespaceReferences.
        if (namespace.isLanguageNamespace() &&
            this.namespaceReference.isLanguageNamespace())
        {
            return namespace == this.namespaceReference;
        }

        // Otherwise, the namespaces are equivalent if they resolve to
        // equivalent namespaceReference definitions (i.e., two with the same URI).
        INamespaceDefinition ns1 = namespace.resolveNamespaceReference(project);
        INamespaceDefinition ns2 = this.namespaceReference.resolveNamespaceReference(project);
        return ((ns1 != null && ns2 != null) ? ns1.equals(ns2) : false);
    }

    @Override
    public INamespaceReference getNamespaceReference()
    {
        return namespaceReference;
    }

    public void setNamespaceReference(INamespaceReference value)
    {
        namespaceReference = (INamespaceResolvedReference)value;

        NamespaceDefinition.setContainingDefinitionOfReference(value, this);
    }

    public void setPublic()
    {
        setNamespaceReference(NamespaceDefinition.getPublicNamespaceDefinition());
    }

    /**
     * Utility to mark a definition as bindable. This method should only ever be
     * called during construction or initialization of a definition.
     */
    public void setBindable()
    {
        MetaTag bindableMetaTag = new MetaTag(this, IMetaAttributeConstants.ATTRIBUTE_BINDABLE, new IMetaTagAttribute[0]);
        addMetaTag(bindableMetaTag);
    }

    @Override
    public INamespaceDefinition resolveNamespace(ICompilerProject project)
    {
        return namespaceReference != null ? namespaceReference.resolveNamespaceReference(project) : null;
    }

    @Override
    public String getTypeAsDisplayString()
    {
        return typeReference != null ? typeReference.getDisplayString() : "";
    }

    @Override
    public IReference getTypeReference()
    {
        return typeReference;
    }

    /**
     * Sets the type reference for this definition.
     * 
     * @param typeReference An [@Link IReference} to a class or interface.
     */
    public void setTypeReference(IReference typeReference)
    {
        this.typeReference = typeReference;
    }

    /**
     * Gets the {@link DependencyType} that should be used when resolving the
     * type of this definition.
     * <p>
     * This method is intended to be overridden by sub-classes.
     * 
     * @return The {@link DependencyType} that should be used when resolving the
     * type of this variable definition
     */
    protected DependencyType getTypeDependencyType()
    {
        return DependencyType.SIGNATURE;
    }

    @Override
    public TypeDefinitionBase resolveType(ICompilerProject project)
    {
        DependencyType dt = getTypeDependencyType();
        return resolveType(typeReference, project, dt);
    }

    @Override
    public boolean isImplicit()
    {
        return (flags & FLAG_IMPLICIT) != 0;
    }

    public void setImplicit()
    {
        flags |= FLAG_IMPLICIT;
    }

    @Override
    public IMetaTag[] getAllMetaTags()
    {
        return metaTags;
    }

    protected void addMetaTag(IMetaTag metaTag)
    {
        IMetaTag[] newMetaTags = new IMetaTag[metaTags.length + 1];
        System.arraycopy(metaTags, 0, newMetaTags, 0, metaTags.length);
        newMetaTags[metaTags.length] = metaTag;
        setMetaTags(newMetaTags);
    }

    public void setMetaTags(IMetaTag[] newMetaTags)
    {
        if (newMetaTags == null)
        {
            metaTags = singletonEmptyMetaTags;
        }
        else
        {
            this.metaTags = newMetaTags;
            
            // Use a flag bit to keep track of whether there is a [Deprecated] tag.
            for (IMetaTag metaTag : metaTags)
            {
                String tagName = metaTag.getTagName();
                if (tagName.equals(IMetaAttributeConstants.ATTRIBUTE_DEPRECATED))
                    setDeprecated();
            }
        }
    }

    @Override
    public IMetaTag[] getMetaTagsByName(String name)
    {
        // We should never return null from this function - callers do not expect it.
        // So allocate an empty array here, even if metaTags is null
        List<IMetaTag> list = new ArrayList<IMetaTag>();

        for (IMetaTag tag : metaTags)
        {
            if (tag.getTagName().equals(name))
                list.add(tag);
        }

        return list.toArray(new IMetaTag[0]);
    }

    @Override
    public boolean hasMetaTagByName(String name)
    {
        return getMetaTagByName(name) != null;
    }

    @Override
    public IMetaTag getMetaTagByName(String name)
    {
        for (IMetaTag tag : metaTags)
        {
            if (tag.getTagName().equals(name))
                return tag;
        }
        return null;
    }

    @Override
    public IASDocComment getExplicitSourceComment()
    {
        IDefinitionNode node = getNode();
        if (node instanceof IDocumentableDefinitionNode)
            return ((IDocumentableDefinitionNode)node).getASDocComment();
        return null;
    }

    @Override
    public boolean hasExplicitComment()
    {
        IDefinitionNode node = getNode();

        if (node instanceof IDocumentableDefinitionNode)
            return ((IDocumentableDefinitionNode)node).hasExplicitComment();

        return false;
    }

    public ASFileScope getFileScope()
    {
        ASScope s = getContainingASScope();
        if (s == null)
            return null;
        return s.getFileScope();
    }

    @Override
    public IDefinitionNode getNode()
    {
        // If this definition didn't come from source, return null.
        if (nodeRef == NodeReference.noReference)
            return null;

        ASScope containingScope = getContainingASScope();
        if (containingScope == null)
            return null;

        ASFileScope fileScope = containingScope.getFileScope();
        if (fileScope == null)
            return null;

        IASNode node = nodeRef.getNode(fileScope.getWorkspace(), getContainingASScope());
        if (!(node instanceof IDefinitionNode))
            return null;

        return (IDefinitionNode)node;
    }

    /**
     * Static version of {@code resolveType()} to help sub-classes implement
     * their overrides of {@link #resolveType(String, ICompilerProject, DependencyType)}.
     * 
     * @param context {@link DefinitionBase} relative to which the resolve should
     * be done.
     */
    protected static TypeDefinitionBase resolveType(DefinitionBase context, String typeName, ICompilerProject project, DependencyType dt)
    {
        // TODO - should probably return the Definition for "*" once we have an easy way to get that
        // TODO - definition - this works for now to prevent NPEs
        if (typeName == null)
            return null;

        CompilerProject compilerProject = (CompilerProject)project;
        ASScope containingScope = (ASScope)(context.containingScope);
        // TODO at some point this method should take some sort of name object.
        if (containingScope != null)
        {
            int lastIndexOfDot = typeName.lastIndexOf('.');
            IDefinition foundDefinition = null;
            if (lastIndexOfDot != -1)
            {
                String unqualifiedName = typeName.substring(lastIndexOfDot + 1);
                String packageName = typeName.substring(0, lastIndexOfDot);
                INamespaceDefinition packageNS = ((CompilerProject)project).getWorkspace().getPackageNamespaceDefinitionCache().get(packageName, false);
                foundDefinition = containingScope.findPropertyQualified(compilerProject, packageNS, unqualifiedName, dt, true);
            }
            else
            {
                foundDefinition = containingScope.findProperty(compilerProject, typeName, dt, true);
            }

            assert (foundDefinition == null) || foundDefinition.isInProject(project);
            if (foundDefinition instanceof TypeDefinitionBase)
                return (TypeDefinitionBase)foundDefinition;
        }

        return null;
    }

    protected static TypeDefinitionBase resolveType(DefinitionBase context, IReference typeRef, ICompilerProject project, DependencyType dt)
    {
        // No type means '*'
        if (typeRef == null)
            return (TypeDefinitionBase)project.getBuiltinType(IASLanguageConstants.BuiltinType.ANY_TYPE);

        IDefinition foundDefinition = typeRef.resolve(project, (ASScope)context.containingScope, dt, true);
        assert (foundDefinition == null) || foundDefinition.isInProject(project);
        return foundDefinition instanceof TypeDefinitionBase ? (TypeDefinitionBase)foundDefinition : null;
    }

    /**
     * This helper method resolves type references in definitions (i.e., Strings
     * such as "int", "Sprite", or "flash.events.IEventDispatcher" that are
     * stored as references to a class or interface) to the definition of the
     * specified type.
     * <p>
     * It is called by
     * <ul>
     * <li><code>resolveType()</code> in DefinitionBase to resolve a type
     * annotation such as the "int" on a declaration like
     * <code>public var foo:int</code>;</li>
     * <li><code>resolveReturnType()</code> in FunctionDefinition to resolve the
     * return type of a function declaration;</li>
     * <li><code>resolveBaseClass()</code> in ClassDefinition to resolve
     * <code>extends</code> clause of a class declaration;</li>
     * <li><code>resolveImplementedInterfaces()</code> in ClassDefinition to
     * resolve the <code>implements</code> clause of a class declaration;</li>
     * <li><code>resolveTypeParameters()</code> in ParameterizedClassDefinition
     * to resolve the type of a Vector;</li>
     * <li><code>resolveExtendedInterfaces()</code> in InterfaceDefinition to
     * resolve the <code>extends</code> clause of an interface declaration.</li>
     * </ul>
     * 
     * @param typeName The name of the type to resolve.
     * @param project The compiler project.
     * @param dt The type of dependency to be created.
     * @return The definition of the resolved type.
     */
    protected TypeDefinitionBase resolveType(String typeName, ICompilerProject project, DependencyType dt)
    {
        return resolveType(this, typeName, project, dt);
    }

    public TypeDefinitionBase resolveType(IReference typeRef, ICompilerProject project, DependencyType dt)
    {
        return resolveType(this, typeRef, project, dt);
    }

    protected String getLocationString()
    {
        StringBuilder sb = new StringBuilder();

        int start = getStart();
        int end = getEnd();
        if (start != -1 && end != -1)
        {
            sb.append(start);
            sb.append('-');
            sb.append(end);
        }

        sb.append(' ');

        String path = getContainingFilePath();
        if (path != null)
            sb.append(path);

        return sb.toString();
    }

    /**
     * Generate an AET Name object for this definition, and log any Problems
     * encountered while constructing the Name, to the list of problems passed
     * in.
     * 
     * @param project the Project to use when resolving the Definitions
     * Namespace
     * @return An AET Name object that represents the qualified name of this
     * definition. Will return null if errors are encountered while constructing
     * the name (such as, the Namespace of the Definition is unresolved).
     */
    public Name getMName(ICompilerProject project)
    {
        Name name = null;

        Namespace qual = null;
        if (namespaceReference != null)
        {
            qual = namespaceReference.resolveAETNamespace(project);
        }
        else
        {
            assert false : "All definitions should have a namespaceReference qualifier.";
            ASScope scope = getContainingASScope();
            if (scope != null)
                qual = ((NamespaceDefinition)NamespaceDefinition.getDefaultNamespaceDefinition(scope)).getAETNamespace();
        }

        // if we can't figure out the namespaceReference, we can't generate a valid name
        if (qual != null)
            name = new Name(ABCConstants.CONSTANT_Qname, new Nsset(qual), getBaseName());
        return name;
    }

    protected final ASScope getContainingASScope()
    {
        IASScope s = getContainingScope();
        ASScope scope = s instanceof ASScope ? (ASScope)s : null;
        return scope;
    }

    protected String getNamespaceReferenceAsString()
    {
        INamespaceReference namespaceReference = getNamespaceReference();
        return namespaceReference != null ?
                namespaceReference.toString() :
                INamespaceConstants.internal_;
    }

    /**
     * 
     * @return false if and only if we can reject the match due to one or the other or both
     * being vectors.
     */
    private boolean checkVectorMatch(DefinitionBase node)
    {
        
        
        IASScope thisScope = getContainingScope();
        IASScope nodeScope = node.getContainingScope();
        if (thisScope != null && nodeScope != null)
            
        {
            IScopedDefinition thisDef = thisScope.getDefinition();
            IScopedDefinition nodeDef = nodeScope.getDefinition();
            
            if (thisDef instanceof AppliedVectorDefinition && nodeDef instanceof AppliedVectorDefinition)
            {
                String thisElementQName = ((AppliedVectorDefinition)thisDef).getQualifiedName();
                String nodeElementQName = ((AppliedVectorDefinition)nodeDef).getQualifiedName();
                if (thisElementQName==null && nodeElementQName==null)
                    return true;            // I don't know if this can happen, but it does then they "match"
            
                if (thisElementQName == null)
                    return false;           

                return thisElementQName.equals(nodeElementQName);
            }
        }
        
        return true;        // we could not reject this match due to vector specific issues
    }
    public boolean matches(DefinitionBase node)
    {
        if (node == null)
            return false;

        if (node.getClass() != getClass())
            return false;

        if (node == this)
            return true;

        INamespaceReference namespace = getNamespaceReference();
        if (namespace == null && node.getNamespaceReference() != null)
            return false;
        if (namespace != null && namespace.getBaseName().compareTo(node.getNamespaceReference().getBaseName()) != 0)
        {
            return false;
        }

        if (node.getBaseName().compareTo(getBaseName()) != 0)
            return false;
        
        if (!checkVectorMatch(node))
            return false;
        String packageName = node.getPackageName();
        String packageName2 = getPackageName();
        if (packageName == null && packageName2 != null)
            return false;

        if (packageName != null && packageName2 != null && packageName.compareTo(packageName2) != 0)
            return false;

        ASScope leftScope = node.getContainingASScope();
        if (leftScope != null)
        {
            leftScope = leftScope.getFileScope();
        }
        ASScope rightScope = getContainingASScope();
        if (rightScope != null)
        {
            rightScope = rightScope.getFileScope();
        }

        if (leftScope instanceof SWCFileScope || rightScope instanceof SWCFileScope)
        {
            return true; //we can't verify path because we might be a definition from a library
        }
        else if (leftScope instanceof ASFileScope && rightScope instanceof ASFileScope)
        {
            if (((ASFileScope)leftScope).getContainingPath().compareTo(((ASFileScope)rightScope).getContainingPath()) != 0)
            {
                return false;
            }
        }
        else
        {
            //For normal case, just compare the full containing file path
            //Note that for some synthetic definitions (like Vector), this path will be null
            String nodePath = node.getContainingFilePath();
            String thisPath = this.getContainingFilePath();
            
            if (nodePath == null)
            {
                if (thisPath != null) return false;
            }
            else
                if (nodePath.compareTo(thisPath) != 0)
                    return false;
        }
        if (node.getTypeAsDisplayString().compareTo(getTypeAsDisplayString()) != 0)
            return false;

        return true;
    }

    /**
     * Whether this definition was specified as "Bindable" in its metadata
     */
    private boolean isBindableLocally()
    {
        return getMetaTagByName(IMetaAttributeConstants.ATTRIBUTE_BINDABLE) != null;
    }

    /**
     * Whether this definition was specified as "Bindable" in its metadata, or
     * inherits bindability from the containing class
     * 
     * @return true if this definition is Bindable.
     */
    @Override
    public boolean isBindable()
    {
        // A variable is considered bindable if it is marked bindable,
        // or if it is a public var in a class marked bindable
        boolean bindable = isBindableLocally();
        if (!bindable)
        {
            IDefinition containing = getParent();
            if (containing instanceof IClassDefinition
                    && this.getNamespaceReference() == NamespaceDefinition.getPublicNamespaceDefinition())
            {
                DefinitionBase containingBase = (DefinitionBase)containing;
                bindable = containingBase.isBindableLocally();
            }
        }
        return bindable;
    }

    /**
     * @return a collection of Bindable event names, if any were specified in
     * the metadata, as well as any inherited from the class
     */
    @Override
    public List<String> getBindableEventNames()
    {
        // First get any from this definition
        // Use a Set<> temporarily, so we can do an easy union
        Set<String> eventNames = new HashSet<String>(getBindableEventNamesLocally());

        // Now "or" in any from the containing class
        IDefinition containing = getParent();
        if (containing instanceof IClassDefinition
                && this.getNamespaceReference() == NamespaceDefinition.getPublicNamespaceDefinition())
        {
            DefinitionBase containingBase = (DefinitionBase)containing;
            eventNames.addAll(containingBase.getBindableEventNamesLocally());
        }

        // Convert to list, as per the return type in IDefinition
        return new ArrayList<String>(eventNames);
    }

    /**
     * @return a collection of Bindable event names, if any were specified in
     * the metadata
     */
    private List<String> getBindableEventNamesLocally()
    {
        IMetaTag[] bindableTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_BINDABLE);

        if (bindableTags != null)
        {
            List<String> events = new ArrayList<String>();
            for (IMetaTag bindableTag : bindableTags)
            {
                String eventName = bindableTag.getAttributeValue(IMetaAttributeConstants.NAME_BINDABLE_EVENT);
                if (eventName == null && bindableTag.getAllAttributes().length == 1)
                {
                    Boolean isStyle = false;
                    
                    eventName = bindableTag.getAllAttributes()[0].getKey();
                    if (eventName != null && eventName.equals("style"))
                        isStyle = true;
                    eventName = bindableTag.getAllAttributes()[0].getValue();
                    if (isStyle && eventName.equals("true"))
                        eventName = "isStyle"; // hack: fake event name "isStyle"
                }
                if (eventName != null)
                    events.add(eventName);
            }
            return events;
        }
        return Collections.emptyList();
    }

    /**
     * @return a collection of Bindable event names, if any were specified in
     * the metadata
     */
    @Override
    public boolean isBindableStyle()
    {
        IMetaTag[] bindableTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_BINDABLE);

        if (bindableTags != null)
        {
            for (IMetaTag bindableTag : bindableTags)
            {
                String style = bindableTag.getAttributeValue(IMetaAttributeConstants.NAME_BINDABLE_STYLE);
                if (style != null && IASLanguageConstants.TRUE.equals(style))
                    return true;
            }
        }
        return false;
    }

    @Override
    public boolean isContingent()
    {
        return (flags & FLAG_CONTINGENT) != 0;
    }

    /**
     * Marks the definition as contingent. Meaning that it's added to the symbol
     * table as a placeholder, but codegen will decide whether or not it needs
     * to actually be created.
     */
    protected void setContingent()
    {
        flags |= FLAG_CONTINGENT;
    }

    @Override
    public boolean isGeneratedEmbedClass()
    {
        return (flags & FLAG_GENERATED_EMBED_CLASS) != 0;
    }

    /**
     * Marks a class definition as being auto-generated for an embedded asset
     * (i.e., one created for a <code>var</code> with <code>[Embed(...)]</code>
     * metadata).
     * <p>
     * Adding such a class to the project scope in the middle of a compilation
     * will not cause the <code>validImports</code> set to be rebuilt.
     */
    public void setGeneratedEmbedClass()
    {
        flags |= FLAG_GENERATED_EMBED_CLASS;
    }

    @Override
    public boolean isContingentNeeded(ICompilerProject project)
    {
        return ((ASScopeBase)getContainingScope()).isContingentDefinitionNeeded(project, this);
    }

    protected IMetaTag getSkinPart()
    {
        return getMetaTagByName(IMetaAttributeConstants.ATTRIBUTE_SKIN_PART);
    }

    protected boolean isRequiredSkinPart(IMetaTag skinPart)
    {
        // if the required value is not set, it's not required, as skin parts are
        // optional by default.
        String isRequired = skinPart.getAttributeValue(IMetaAttributeConstants.NAME_SKIN_PART_REQUIRED);
        if (isRequired == null)
            return false;

        if (!isRequired.equals(IMetaAttributeConstants.VALUE_SKIN_PART_REQUIRED_TRUE))
            return false;

        return true;
    }

    /**
     * Returns the type specified by <code>[ArrayElementType("...")]</code>
     * metadata on a variable/getter/setter of type Array. </p> This method is
     * in DefinitionBase because it is common to VariableDefinition,
     * GetterDefinition, and SetterDefinition.
     */
    public String getArrayElementType(ICompilerProject project)
    {
        if (getTypeAsDisplayString().equals(IASLanguageConstants.Array))
        {
            return getPropertyMetaTagValue(
                    (RoyaleProject)project, IMetaAttributeConstants.ATTRIBUTE_ARRAYELEMENTTYPE);
        }

        return null;
    }

    /**
     * Returns the type specified by <code>[InstanceType("...")]</code> metadata
     * on a variable/getter/setter of type mx.core.IDeferredInstance.
     * <p>
     * This method is in DefinitionBase because it is common to
     * VariableDefinition, GetterDefinition, and SetterDefinition.
     */
    public String getInstanceType(ICompilerProject project)
    {
        if (getTypeAsDisplayString().equals(((RoyaleProject)project).getDeferredInstanceInterface()))
        {
            return getPropertyMetaTagValue(
                    (RoyaleProject)project, IMetaAttributeConstants.ATTRIBUTE_INSTANCETYPE);
        }

        return null;
    }

    /**
     * Returns the property name specified by <code>[PercentProxy("...")]</code>
     * metadata on a variable/getter/setter. </p> This method is in
     * DefinitionBase because it is common to VariableDefinition,
     * GetterDefinition, and SetterDefinition.
     */
    public String getPercentProxy(ICompilerProject project)
    {
        IMetaTag metaTag = getPropertyMetaTag(
                (RoyaleProject)project, IMetaAttributeConstants.ATTRIBUTE_PERCENT_PROXY);

        return metaTag != null ? metaTag.getValue() : null;
    }

    /**
     * Returns <code>true</code> if there is <code>[RichTextContent]</code>
     * metadata on a variable/getter/setter.
     * <p>
     * This method is in DefinitionBase because it is common to
     * VariableDefinition, GetterDefinition, and SetterDefinition.
     */
    public boolean hasRichTextContent(ICompilerProject project)
    {
        IMetaTag metaTag = getPropertyMetaTag(
                (RoyaleProject)project, IMetaAttributeConstants.ATTRIBUTE_RICHTEXTCONTENT);

        return metaTag != null;
    }

    /**
     * Returns <code>true</code> if there is <code>[CollapseWhiteSpace]</code>
     * metadata on a variable/getter/setter.
     * <p>
     * This method is in DefinitionBase because it is common to
     * VariableDefinition, GetterDefinition, and SetterDefinition.
     */
    public boolean hasCollapseWhiteSpace(ICompilerProject project)
    {
        IMetaTag metaTag = getPropertyMetaTag(
                (RoyaleProject)project, IMetaAttributeConstants.ATTRIBUTE_COLLAPSEWHITESPACE);

        return metaTag != null;
    }

    /**
     * Returns <code>true</code> if there is <code>[Inspectable(...)]</code>
     * metadata on a vairable/getter/setter that specifies
     * <code>format="Color"</code>.
     * <p>
     * This method is in DefinitionBase because it is common to
     * VariableDefinition, GetterDefinition, and SetterDefinition.
     */
    public boolean isColor(ICompilerProject project)
    {
        IMetaTag metaTag = getPropertyMetaTag(
                (RoyaleProject)project, IMetaAttributeConstants.ATTRIBUTE_INSPECTABLE);

        if (metaTag == null)
            return false;

        String format = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_INSPECTABLE_FORMAT);
        return format.equals(IMetaAttributeConstants.VALUE_INSPECTABLE_FORMAT_COLOR);
    }

    private IMetaTag getPropertyMetaTag(RoyaleProject project, String metadataName)
    {
        // Look for metadata with the specified name.
        IMetaTag metaTag = getMetaTagByName(metadataName);

        // If we don't find it, and we're a getter or setter,
        // look on the corresponding setter or getter.
        if (metaTag == null && this instanceof IAccessorDefinition)
        {
            IAccessorDefinition correspondingAccessor =
                    ((IAccessorDefinition)this).resolveCorrespondingAccessor(project);
            if (correspondingAccessor != null)
                metaTag = correspondingAccessor.getMetaTagByName(metadataName);
        }

        return metaTag;
    }

    /**
     * This helper method is called by {@code getArrayElementType()} and
     * {@code getInstanceType()}.
     */
    private String getPropertyMetaTagValue(RoyaleProject project, String metadataName)
    {
        // Look for metadata with the specified name.
        IMetaTag metaTag = getPropertyMetaTag(project, metadataName);

        // If we found the metadata, return the type that it specifies.
        // There should be one keyless attribute, and we want its value.
        return metaTag != null ? metaTag.getValue() : null;
    }

    /**
     * Determines if this definition is in a package namespaceReference. This is here, so
     * that the various sub-classes can call it from get*Classification()
     * methods.
     * 
     * @return true, if the namespaceReference for this definition is some kind of
     * package namespaceReference.
     */
    protected boolean inPackageNamespace()
    {
        INamespaceReference nsRef = getNamespaceReference();
        assert nsRef != null : "All definitions should have a namespaceReference reference!";
        if (nsRef.isPublicOrInternalNamespace())
            return true;
        return false;
    }
    
    @Override
    public boolean isDeprecated()
    {
        return (flags & FLAG_DEPRECATED) != 0;
    }
    
    /**
     * Sets a bitflag to indicate that this definition has [Deprecated] metadata.
     * Checking this flag is faster than walking through the metadata multiple times.
     */
    private void setDeprecated()
    {
        flags |= FLAG_DEPRECATED;
    }

    @Override
    public IDeprecationInfo getDeprecationInfo()
    {
        for (IMetaTag metaTag : metaTags)
        {
            if (metaTag.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_DEPRECATED))
            {
                String replacement = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_DEPRECATED_REPLACEMENT);
                String since = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_DEPRECATED_SINCE);
                String message = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_DEPRECATED_MESSAGE);
                return new DeprecationInfo(replacement, since, message);
            }
        }

        return null;
    }

    /**
     * Used only in asserts.
     */
    public boolean verify()
    {
        // Verify the name.
        assert getBaseName() != null : "Definition has null name";

        // TODO: Verify the source location eventually.
        //      assert getSourcePath() != null : "Definition has null source path";
        //      assert getStart() != UNKNOWN : "Definition has unknown start";
        //      assert getEnd() != UNKNOWN : "Definition has unknown end";
        //      assert getLine() != UNKNOWN : "Definition has unknown line";
        //      assert getColumn() != UNKNOWN : "Definition has unknown column";

        return true;
    }

    /**
     * Used only for debugging.
     */
    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        buildString(sb, false);
        return sb.toString();
    }

    /**
     * Used only for debugging, as part of {@link #toString()}.
     */
    public void buildString(StringBuilder sb, boolean withLocation)
    {
        buildInnerString(sb);

        if (withLocation)
        {
            sb.append(' ');
            sb.append(getLocationString());
        }
    }

    /**
     * Used only for debugging, as part of {@link #toString()}.
     */
    protected void buildInnerString(StringBuilder sb)
    {
    }
    
    /**
     * Counts various types of definitions that are created,
     * as well as the total number of definitions.
     */
    private void countDefinitions()
    {
    	if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.COUNTER) == CompilerDiagnosticsConstants.COUNTER)
    		System.out.println("DefinitionBase incrementing Counter for " + getClass().getSimpleName());
        Counter counter = Counter.getInstance();
        counter.incrementCount(getClass().getSimpleName());
        counter.incrementCount("definitions");
    	if ((CompilerDiagnosticsConstants.diagnostics & CompilerDiagnosticsConstants.COUNTER) == CompilerDiagnosticsConstants.COUNTER)
    		System.out.println("DefinitionBase done incrementing Counter for " + getClass().getSimpleName());
    }
    
    //
    // IDefinitionSet methods
    //
    
    @Override
    public boolean isEmpty()
    {
        return false;
    }

    @Override
    public int getSize()
    {
        return 1;
    }

    @Override
    public int getMaxSize()
    {
        return 1;
    }

    @Override
    public IDefinition getDefinition(int i)
    {
        assert i == 0;
        return this;
    }

    @Override
    public boolean isInProject(ICompilerProject project)
    {
        final ICompilationUnit compilationUnit = ((ASProjectScope)project.getScope()).getCompilationUnitForDefinition(this);
        if (compilationUnit != null)
        {
            if (compilationUnit.getProject() == project)
                return true;
            else
                return false;
        }
        if (AppliedVectorDefinition.isVectorScope(getContainingASScope()))
        {
            IDefinition parentDef = getParent();
            return parentDef.isInProject(project);
        }
        return false;
    }
}
