/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 
 *******************************************************************************/
package org.eclipse.dltk.core;

import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;

/**
 * A script project represents a view of a project resource in terms of DLTK
 * elements such as script folders, types, methods and fields. A project may
 * contain several project fragments, which contain script folders. A project
 * fragment corresponds to an underlying folder or an archive (like JAR).
 * <p>
 * Each script project has a buildpath, defining which folders contain source
 * code and where required libraries are located. <s>Each script project also
 * has an output location, defining where the builder writes output files.</s> A
 * project that references folders in another project can access the folders by
 * including the required project in a buildpath entry. The DLTK model will
 * present the source elements in the required project; <s>when building, the
 * compiler will use the corresponding generated class files from the required
 * project's output location(s))</s>. The buildpath format is a sequence of
 * buildpath entries describing the location and contents of project fragments .
 * </p>
 * Script project elements need to be opened before they can be navigated or
 * manipulated. The children of a script project are the project fragments that
 * are defined by the buildpath and contained in this project (in other words,
 * it does not include project fragments for other projects).
 * 
 * The children (i.e. the project fragments) appear in the order they are
 * defined by the buildpath. </p>
 * <p>
 * An instance of one of these handles can be created via
 * <code>DLTKCore.create(project)</code>.
 * </p>
 * 
 * @see DLTKCore#create(org.eclipse.core.resources.IProject)
 * @see IBuildpathEntry
 * @noimplement This interface is not intended to be implemented by clients.
 */
public interface IScriptProject extends IModelElement, IOpenable, IParent {

	/**
	 * Returns the <code>IProject</code> on which this
	 * <code>IScriptProject</code> was created. This is handle-only method.
	 * 
	 * @return the <code>IProject</code> on which this
	 *         <code>IScriptProject</code> was created
	 */
	IProject getProject();

	/**
	 * Returns all of the project fragments contained in this project,
	 * identified on this project's resolved buildpath. The result does not
	 * include project fragments in other projects referenced on this project's
	 * buildpath.
	 * 
	 * <p>
	 * NOTE: This is equivalent to <code>getChildren()</code>.
	 * 
	 * @return all of the project fragments contained in this project,
	 *         identified on this project's resolved buildpath
	 * @exception ModelException
	 *                if this element does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 */
	IProjectFragment[] getProjectFragments() throws ModelException;

	/**
	 * Helper method for returning one option value only. Equivalent to
	 * <code>(String)this.getOptions(inheritDLTKCoreOptions).get(optionName)</code>
	 * Note that it may answer <code>null</code> if this option does not exist,
	 * or if there is no custom value for it.
	 * <p>
	 * For a complete description of the configurable options, see
	 * <code>DLTKCore#getDefaultOptions</code>.
	 * </p>
	 * 
	 * @param optionName
	 *            the name of an option
	 * @param inheritDLTKCoreOptions
	 *            - boolean indicating whether DLTKCore options should be
	 *            inherited as well
	 * @return the String value of a given option
	 * @see DLTKCore#getDefaultOptions()
	 */
	String getOption(String optionName, boolean inheritDLTKCoreOptions);

	/**
	 * Returns the table of the current custom options for this project.
	 * Projects remember their custom options, in other words, only the options
	 * different from the the DLTKCore global options for the workspace. A
	 * boolean argument allows to directly merge the project options with global
	 * ones from <code>DLTKCore</code>.
	 * <p>
	 * For a complete description of the configurable options, see
	 * <code>DLTKCore#getDefaultOptions</code>.
	 * </p>
	 * 
	 * @param inheritDLTKCoreOptions
	 *            - boolean indicating whether DLTKCore options should be
	 *            inherited as well
	 * @return table of current settings of all options (key type:
	 *         <code>String</code>; value type: <code>String</code>)
	 * @see DLTKCore#getDefaultOptions()
	 * 
	 */
	Map<String, String> getOptions(boolean inheritDLTKCoreOptions);

	/**
	 * Helper method for setting one option value only. Equivalent to
	 * 
	 * <code>Map options = this.getOptions(false); map.put(optionName, optionValue); this.setOptions(map)</code>
	 * <p>
	 * For a complete description of the configurable options, see
	 * <code>DLTKCore#getDefaultOptions</code>.
	 * </p>
	 * 
	 * @param optionName
	 *            the name of an option
	 * @param optionValue
	 *            the value of the option to set
	 * @see DLTKCore#getDefaultOptions()
	 * 
	 */
	void setOption(String optionName, String optionValue);

	/**
	 * Sets the project custom options. All and only the options explicitly
	 * included in the given table are remembered; all previous option settings
	 * are forgotten, including ones not explicitly mentioned.
	 * <p>
	 * For a complete description of the configurable options, see
	 * <code>DLTKCore#getDefaultOptions</code>.
	 * </p>
	 * 
	 * @param newOptions
	 *            the new options (key type: <code>String</code>; value type:
	 *            <code>String</code>), or <code>null</code> to flush all custom
	 *            options (clients will automatically get the global DLTKCore
	 *            options).
	 * @see DLTKCore#getDefaultOptions()
	 * 
	 */
	void setOptions(Map newOptions);

	/**
	 * Returns a project fragment for the given resource, which must either be a
	 * folder representing the root of source folders, or <code>.zip</code>
	 * file. This is a handle-only method. The underlying resource may or may
	 * not exist.
	 * 
	 * @param resource
	 *            the given resource
	 * @return a project fragment for the given resource, which must either be a
	 *         folder representing the top of source folders, or a
	 *         <code>.zip</code> file
	 */
	IProjectFragment getProjectFragment(IResource resource);

	/**
	 * Returns a package fragment root for the ZIP at the specified file system
	 * path. This is a handle-only method. The underlying
	 * <code>java.io.File</code> may or may not exist. No resource is associated
	 * with this local ZIP package fragment root.
	 * 
	 * @param zipPath
	 *            the jars's file system path
	 * @return a package fragment root for the JAR at the specified file system
	 *         path
	 */
	IProjectFragment getProjectFragment(String zipPath);

	/**
	 * Returns a project fragment for an external library or a source folder at
	 * the specified file system path. This is a handle-only method. The
	 * underlying <code>java.io.File</code> may or may not exist. No resource is
	 * associated with this local library package fragment root.
	 * 
	 * @param path
	 *            the library's file system path
	 * @return a package fragment root for the external library at the specified
	 *         file system path
	 * @since 3.0
	 */
	IProjectFragment getProjectFragment(IPath path);

	/**
	 * Sets the buildpath of this project using a list of buildpath entries.
	 * 
	 * Setting the buildpath to <code>null</code> specifies a default buildpath
	 * (the project root). Setting the buildpath to an empty array specifies an
	 * empty buildpath.
	 * <p>
	 * If a cycle is detected while setting this buildpath, an error marker will
	 * be added to the project closing the cycle. To avoid this problem, use
	 * <code>hasBuildpathCycle(IBuildpathEntry[] entries)</code> before setting
	 * the buildpath.
	 * <p>
	 * This operation acquires a lock on the workspace's root.
	 * 
	 * @param entries
	 *            a list of buildpath entries
	 * @param monitor
	 *            the given progress monitor
	 * @exception ModelException
	 *                if the buildpath could not be set. Reasons include:
	 *                <ul>
	 *                <li> This model element does not exist
	 *                (ELEMENT_DOES_NOT_EXIST)</li> <li> The buildpath is being
	 *                modified during resource change event notification
	 *                (CORE_EXCEPTION) <li> The buildpath failed the validation
	 *                check
	 *                </ul>
	 * @see IBuildpathEntry
	 */
	void setRawBuildpath(IBuildpathEntry[] entries, IProgressMonitor monitor)
			throws ModelException;

	/**
	 * Returns true if this is valid DLTK Project.
	 * 
	 */
	public boolean isValid();

	/**
	 * Decodes the buildpath entry that has been encoded in the given string in
	 * the context of this project. Returns null if the encoded entry is
	 * malformed.
	 * 
	 * @param encodedEntry
	 *            the encoded buildpath entry
	 * @return the decoded buildpath entry, or <code>null</code> if unable to
	 *         decode it
	 * 
	 */
	IBuildpathEntry decodeBuildpathEntry(String encodedEntry);

	/**
	 * Encodes the given buildpath entry into a string in the context of this
	 * project.
	 * 
	 * @param buildpathEntry
	 *            the buildpath entry to encode
	 * @return the encoded buildpath entry
	 * 
	 */
	public String encodeBuildpathEntry(IBuildpathEntry buildpathEntry);

	IBuildpathEntry[] getRawBuildpath() throws ModelException;

	/**
	 * This is a helper method returning the resolved buildpath for the project
	 * as a list of simple (non-variable, non-container) buildpath entries. All
	 * buildpath variable and buildpath container entries in the project's raw
	 * buildpath will be replaced by the simple buildpath entries they resolve
	 * to.
	 * <p>
	 * The resulting resolved buildpath is accurate for the given point in time.
	 * If the project's raw buildpath is later modified, or if buildpath
	 * variables are changed, the resolved buildpath can become out of date.
	 * Because of this, hanging on resolved buildpath is not recommended.
	 * </p>
	 * 
	 * @param ignoreUnresolvedEntry
	 *            indicates how to handle unresolvable variables and containers;
	 *            <code>true</code> indicates that missing variables and
	 *            unresolvable buildpath containers should be silently ignored,
	 *            and that the resulting list should consist only of the entries
	 *            that could be successfully resolved; <code>false</code>
	 *            indicates that a <code>ModelException</code> should be thrown
	 *            for the first unresolved variable or container
	 * @return the resolved buildpath for the project as a list of simple
	 *         buildpath entries, where all buildpath variable and container
	 *         entries have been resolved and substituted with their final
	 *         target entries
	 * @exception ModelException
	 *                in one of the corresponding situation:
	 *                <ul>
	 *                <li>this element does not exist</li>
	 *                <li>an exception occurs while accessing its corresponding
	 *                resource</li>
	 *                <li>a buildpath variable or buildpath container was not
	 *                resolvable and <code>ignoreUnresolvedEntry</code> is
	 *                <code>false</code>.</li>
	 *                </ul>
	 * @see IBuildpathEntry
	 */
	IBuildpathEntry[] getResolvedBuildpath(boolean ignoreUnresolvedEntry)
			throws ModelException;

	/**
	 * Returns the <code>IModelElement</code> corresponding to the given
	 * buildpath-relative path, or <code>null</code> if no such
	 * <code>IModelElement</code> is found. The result is one of an
	 * <code>ISourceModule</code>, <code>IClassFile</code>, or
	 * <code>IScriptFolder</code>.
	 * <p>
	 * When looking for a package fragment, there might be several potential
	 * matches; only one of them is returned.
	 * 
	 * <p>
	 * For example, the path "java/lang/Object.java", would result in the
	 * <code>ISourceModule</code> corresponding to "java.lang.Object". The path
	 * "java/lang" would result in the <code>IScriptFolder</code> for
	 * "java.lang".
	 * 
	 * @param path
	 *            the given buildpath-relative path
	 * @exception ModelException
	 *                if the given path is <code>null</code> or absolute
	 * @return the <code>IModelElement</code> corresponding to the given
	 *         buildpath-relative path, or <code>null</code> if no such
	 *         <code>IModelElement</code> is found
	 */
	IModelElement findElement(IPath path) throws ModelException;

	/**
	 * Returns the <code>IModelElement</code> corresponding to the given
	 * buildpath-relative path, or <code>null</code> if no such
	 * <code>IModelElement</code> is found. The result is one of an
	 * <code>ISourceModule</code>, <code>IClassFile</code>, or
	 * <code>IScriptFolder</code>. If it is an <code>ISourceModule</code>, its
	 * owner is the given owner.
	 * <p>
	 * When looking for a package fragment, there might be several potential
	 * matches; only one of them is returned.
	 * 
	 * <p>
	 * For example, the path "java/lang/Object.java", would result in the
	 * <code>ISourceModule</code> corresponding to "java.lang.Object". The path
	 * "java/lang" would result in the <code>IScriptFolder</code> for
	 * "java.lang".
	 * 
	 * @param path
	 *            the given buildpath-relative path
	 * @param owner
	 *            the owner of the returned compilation unit, ignored if it is
	 *            not a compilation unit.
	 * @exception ModelException
	 *                if the given path is <code>null</code> or absolute
	 * @return the <code>IModelElement</code> corresponding to the given
	 *         buildpath-relative path, or <code>null</code> if no such
	 *         <code>IModelElement</code> is found
	 * 
	 */
	IModelElement findElement(IPath path, WorkingCopyOwner owner)
			throws ModelException;

	/**
	 * Returns the first existing package fragment on this project's buildpath
	 * whose path matches the given (absolute) path, or <code>null</code> if
	 * none exist. The path can be: - internal to the workbench: "/Project/src"
	 * - external to the workbench: "c:/jdk/classes.zip/java/lang"
	 * 
	 * @param path
	 *            the given absolute path
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first existing package fragment on this project's buildpath
	 *         whose path matches the given (absolute) path, or
	 *         <code>null</code> if none exist
	 */
	IScriptFolder findScriptFolder(IPath path) throws ModelException;

	/**
	 * Returns the existing package fragment root on this project's buildpath
	 * whose path matches the given (absolute) path, or <code>null</code> if one
	 * does not exist. The path can be: - internal to the workbench:
	 * "/Compiler/src" - external to the workbench: "c:/jdk/classes.zip"
	 * 
	 * @param path
	 *            the given absolute path
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the existing package fragment root on this project's buildpath
	 *         whose path matches the given (absolute) path, or
	 *         <code>null</code> if one does not exist
	 */
	IProjectFragment findProjectFragment(IPath path) throws ModelException;

	/**
	 * Returns the existing package fragment roots identified by the given
	 * entry. Note that a buildpath entry that refers to another project may
	 * have more than one root (if that project has more than on root containing
	 * source), and buildpath entries within the current project identify a
	 * single root.
	 * <p>
	 * If the buildpath entry denotes a variable, it will be resolved and return
	 * the roots of the target entry (empty if not resolvable).
	 * <p>
	 * If the buildpath entry denotes a container, it will be resolved and
	 * return the roots corresponding to the set of container entries (empty if
	 * not resolvable).
	 * 
	 * @param entry
	 *            the given entry
	 * @return the existing package fragment roots identified by the given entry
	 * @see IBuildpathContainer
	 * 
	 */
	IProjectFragment[] findProjectFragments(IBuildpathEntry entry);

	/**
	 * Returns the first type found following this project's buildpath with the
	 * given fully qualified name or <code>null</code> if none is found. The
	 * fully qualified name is a dot-separated name. For example, a class B
	 * defined as a member type of a class A in package x.y should have a the
	 * fully qualified name "x.y.A.B".
	 * 
	 * Note that in order to be found, a type name (or its toplevel enclosing
	 * type name) must match its corresponding compilation unit name. As a
	 * consequence, secondary types cannot be found using this functionality. To
	 * find secondary types use {@link #findType(String, IProgressMonitor)}
	 * instead.
	 * 
	 * @param fullyQualifiedName
	 *            the given fully qualified name
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given fully qualified name or <code>null</code> if none is found
	 * @see IType#getFullyQualifiedName(char)
	 * 
	 */
	IType findType(String fullyQualifiedName) throws ModelException;

	/**
	 * Same functionality as {@link #findType(String)} but also look for
	 * secondary types if given name does not match a compilation unit name.
	 * 
	 * @param fullyQualifiedName
	 *            the given fully qualified name
	 * @param progressMonitor
	 *            the progress monitor to report progress to, or
	 *            <code>null</code> if no progress monitor is provided
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given fully qualified name or <code>null</code> if none is found
	 * @see IType#getFullyQualifiedName(char)
	 * 
	 */
	IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor)
			throws ModelException;

	/**
	 * Returns the first type found following this project's buildpath with the
	 * given fully qualified name or <code>null</code> if none is found. The
	 * fully qualified name is a dot-separated name. For example, a class B
	 * defined as a member type of a class A in package x.y should have a the
	 * fully qualified name "x.y.A.B". If the returned type is part of a
	 * compilation unit, its owner is the given owner.
	 * 
	 * Note that in order to be found, a type name (or its toplevel enclosing
	 * type name) must match its corresponding compilation unit name. As a
	 * consequence, secondary types cannot be found using this functionality. To
	 * find secondary types use
	 * {@link #findType(String, WorkingCopyOwner, IProgressMonitor)} instead.
	 * 
	 * @param fullyQualifiedName
	 *            the given fully qualified name
	 * @param owner
	 *            the owner of the returned type's compilation unit
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given fully qualified name or <code>null</code> if none is found
	 * @see IType#getFullyQualifiedName(char)
	 * 
	 */
	IType findType(String fullyQualifiedName, WorkingCopyOwner owner)
			throws ModelException;

	/**
	 * Same functionality as {@link #findType(String, WorkingCopyOwner)} but
	 * also look for secondary types if given name does not match a compilation
	 * unit name.
	 * 
	 * @param fullyQualifiedName
	 *            the given fully qualified name
	 * @param owner
	 *            the owner of the returned type's compilation unit
	 * @param progressMonitor
	 *            the progress monitor to report progress to, or
	 *            <code>null</code> if no progress monitor is provided
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given fully qualified name or <code>null</code> if none is found
	 * @see IType#getFullyQualifiedName(char)
	 * 
	 */
	IType findType(String fullyQualifiedName, WorkingCopyOwner owner,
			IProgressMonitor progressMonitor) throws ModelException;

	/**
	 * Returns the first type found following this project's buildpath with the
	 * given package name and type qualified name or <code>null</code> if none
	 * is found. The package name is a dot-separated name. The type qualified
	 * name is also a dot-separated name. For example, a class B defined as a
	 * member type of a class A should have the type qualified name "A.B".
	 * 
	 * Note that in order to be found, a type name (or its toplevel enclosing
	 * type name) must match its corresponding compilation unit name. As a
	 * consequence, secondary types cannot be found using this functionality. To
	 * find secondary types use
	 * {@link #findType(String, String, IProgressMonitor)} instead.
	 * 
	 * @param packageName
	 *            the given package name
	 * @param typeQualifiedName
	 *            the given type qualified name
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given package name and type qualified name or <code>null</code>
	 *         if none is found
	 * @see IType#getTypeQualifiedName(char)
	 * 
	 */
	IType findType(String packageName, String typeQualifiedName)
			throws ModelException;

	/**
	 * Same functionality as {@link #findType(String, String)} but also look for
	 * secondary types if given name does not match a compilation unit name.
	 * 
	 * @param packageName
	 *            the given package name
	 * @param typeQualifiedName
	 *            the given type qualified name
	 * @param progressMonitor
	 *            the progress monitor to report progress to, or
	 *            <code>null</code> if no progress monitor is provided
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given fully qualified name or <code>null</code> if none is found
	 * @see IType#getFullyQualifiedName(char)
	 * 
	 */
	IType findType(String packageName, String typeQualifiedName,
			IProgressMonitor progressMonitor) throws ModelException;

	/**
	 * Returns the first type found following this project's buildpath with the
	 * given package name and type qualified name or <code>null</code> if none
	 * is found. The package name is a dot-separated name. The type qualified
	 * name is also a dot-separated name. For example, a class B defined as a
	 * member type of a class A should have the type qualified name "A.B". If
	 * the returned type is part of a compilation unit, its owner is the given
	 * owner.
	 * 
	 * Note that in order to be found, a type name (or its toplevel enclosing
	 * type name) must match its corresponding compilation unit name. As a
	 * consequence, secondary types cannot be found using this functionality. To
	 * find secondary types use
	 * {@link #findType(String, String, WorkingCopyOwner, IProgressMonitor)}
	 * instead.
	 * 
	 * @param packageName
	 *            the given package name
	 * @param typeQualifiedName
	 *            the given type qualified name
	 * @param owner
	 *            the owner of the returned type's compilation unit
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given package name and type qualified name or <code>null</code>
	 *         if none is found
	 * @see IType#getTypeQualifiedName(char)
	 * 
	 */
	IType findType(String packageName, String typeQualifiedName,
			WorkingCopyOwner owner) throws ModelException;

	/**
	 * Same functionality as {@link #findType(String, String, WorkingCopyOwner)}
	 * but also look for secondary types if given name does not match a
	 * compilation unit name.
	 * 
	 * @param packageName
	 *            the given package name
	 * @param typeQualifiedName
	 *            the given type qualified name
	 * @param owner
	 *            the owner of the returned type's compilation unit
	 * @param progressMonitor
	 *            the progress monitor to report progress to, or
	 *            <code>null</code> if no progress monitor is provided
	 * @exception ModelException
	 *                if this project does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @return the first type found following this project's buildpath with the
	 *         given fully qualified name or <code>null</code> if none is found
	 * @see IType#getFullyQualifiedName(char)
	 * 
	 */
	IType findType(String packageName, String typeQualifiedName,
			WorkingCopyOwner owner, IProgressMonitor progressMonitor)
			throws ModelException;

	/**
	 * Returns the raw buildpath for the project as defined by its
	 * <code>.buildpath</code> file from disk, or <code>null</code> if unable to
	 * read the file.
	 * <p>
	 * This buildpath may differ from the in-memory buildpath returned by
	 * <code>getRawBuildpath</code>, in case the automatic reconciliation
	 * mechanism has not been performed yet. Usually, any change to the
	 * <code>.buildpath</code> file is automatically noticed and reconciled at
	 * the next resource change notification event. However, if the file is
	 * modified within an operation, where this change needs to be taken into
	 * account before the operation ends, then the buildpath from disk can be
	 * read using this method, and further assigned to the project using
	 * <code>setRawBuildpath(...)</code>.
	 * </p>
	 * <p>
	 * Buildpath variable and buildpath container entries can be resolved using
	 * the helper method <code>getResolvedBuildpath</code>; buildpath variable
	 * entries also can be resolved individually using
	 * <code>DLTKCore#getBuildpathVariable</code>).
	 * </p>
	 * <p>
	 * Note that no check is performed whether the project has the script nature
	 * set, allowing an existing <code>.buildpath</code> file to be considered
	 * independantly (unlike <code>getRawBuildpath</code> which requires the
	 * script nature to be associated with the project).
	 * </p>
	 * <p>
	 * In order to manually force a project buildpath refresh, one can simply
	 * assign the project buildpath using the result of this method, as follows:
	 * 
	 * <code>proj.setRawBuildpath(proj.readRawBuildpath(), proj.readOutputLocation(), monitor)</code>
	 * (note that the <code>readRawBuildpath/readOutputLocation</code> methods
	 * could return <code>null</code>).
	 * </p>
	 * 
	 * @return the raw buildpath from disk for the project, as a list of
	 *         buildpath entries
	 * @see #getRawBuildpath()
	 * @see IBuildpathEntry
	 * 
	 */
	IBuildpathEntry[] readRawBuildpath();

	/**
	 * Returns all of the existing project fragments that exist on the
	 * buildpath, in the order they are defined by the buildpath.
	 * 
	 * @return all of the existing project fragments that exist on the buildpath
	 * @exception ModelException
	 *                if this element does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 */
	IProjectFragment[] getAllProjectFragments() throws ModelException;

	public Object[] getForeignResources() throws ModelException;

	/**
	 * Returns whether the given element is on the buildpath of this project,
	 * that is, referenced from a buildpath entry and not explicitly excluded
	 * using an exclusion pattern.
	 * 
	 * @param element
	 *            the given element
	 * @return <code>true</code> if the given element is on the buildpath of
	 *         this project, <code>false</code> otherwise
	 * @see IBuildpathEntry#getInclusionPatterns()
	 * @see IBuildpathEntry#getExclusionPatterns()
	 * 
	 */
	boolean isOnBuildpath(IModelElement element);

	/**
	 * Returns whether the given resource is on the buildpath of this project,
	 * that is, referenced from a buildpath entry and not explicitly excluded
	 * using an exclusion pattern.
	 * 
	 * @param resource
	 *            the given resource
	 * @return <code>true</code> if the given resource is on the buildpath of
	 *         this project, <code>false</code> otherwise
	 * @see IBuildpathEntry#getInclusionPatterns()
	 * @see IBuildpathEntry#getExclusionPatterns()
	 * 
	 */
	boolean isOnBuildpath(IResource resource);

	/**
	 * Creates and returns a type hierarchy for all types in the given region,
	 * considering subtypes within that region.
	 * 
	 * @param monitor
	 *            the given progress monitor
	 * @param region
	 *            the given region
	 * @exception JavaModelException
	 *                if this element does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @exception IllegalArgumentException
	 *                if region is <code>null</code>
	 * @return a type hierarchy for all types in the given region, considering
	 *         subtypes within that region
	 */
	ITypeHierarchy newTypeHierarchy(IRegion region, IProgressMonitor monitor)
			throws ModelException;

	/**
	 * Creates and returns a type hierarchy for all types in the given region,
	 * considering subtypes within that region and considering types in the
	 * working copies with the given owner. In other words, the owner's working
	 * copies will take precedence over their original compilation units in the
	 * workspace.
	 * <p>
	 * Note that if a working copy is empty, it will be as if the original
	 * compilation unit had been deleted.
	 * <p>
	 * 
	 * @param monitor
	 *            the given progress monitor
	 * @param region
	 *            the given region
	 * @param owner
	 *            the owner of working copies that take precedence over their
	 *            original compilation units
	 * @exception JavaModelException
	 *                if this element does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * @exception IllegalArgumentException
	 *                if region is <code>null</code>
	 * @return a type hierarchy for all types in the given region, considering
	 *         subtypes within that region
	 * @since 3.0
	 */
	ITypeHierarchy newTypeHierarchy(IRegion region, WorkingCopyOwner owner,
			IProgressMonitor monitor) throws ModelException;

	/**
	 * Creates and returns a type hierarchy for the given type considering
	 * subtypes in the specified region.
	 * 
	 * @param type
	 *            the given type
	 * @param region
	 *            the given region
	 * @param monitor
	 *            the given monitor
	 * 
	 * @exception JavaModelException
	 *                if this element does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * 
	 * @exception IllegalArgumentException
	 *                if type or region is <code>null</code>
	 * @return a type hierarchy for the given type considering subtypes in the
	 *         specified region
	 */
	ITypeHierarchy newTypeHierarchy(IType type, IRegion region,
			IProgressMonitor monitor) throws ModelException;

	/**
	 * Creates and returns a type hierarchy for the given type considering
	 * subtypes in the specified region and considering types in the working
	 * copies with the given owner. In other words, the owner's working copies
	 * will take precedence over their original compilation units in the
	 * workspace.
	 * <p>
	 * Note that if a working copy is empty, it will be as if the original
	 * compilation unit had been deleted.
	 * <p>
	 * 
	 * @param type
	 *            the given type
	 * @param region
	 *            the given region
	 * @param monitor
	 *            the given monitor
	 * @param owner
	 *            the owner of working copies that take precedence over their
	 *            original compilation units
	 * 
	 * @exception JavaModelException
	 *                if this element does not exist or if an exception occurs
	 *                while accessing its corresponding resource
	 * 
	 * @exception IllegalArgumentException
	 *                if type or region is <code>null</code>
	 * @return a type hierarchy for the given type considering subtypes in the
	 *         specified region
	 * @since 3.0
	 */
	ITypeHierarchy newTypeHierarchy(IType type, IRegion region,
			WorkingCopyOwner owner, IProgressMonitor monitor)
			throws ModelException;

	public IScriptFolder[] getScriptFolders() throws ModelException;

	public IDLTKLanguageToolkit getLanguageToolkit();
}
