/*******************************************************************************
 * Copyright (c) 2004, 2017 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.core;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.internal.codeassist.InternalCompletionProposal;

/**
 * Completion proposal.
 * <p>
 * In typical usage, the user working in a code editor issues a code assist
 * command. This command results in a call to
 * <code>ICodeAssist.codeComplete(position, completionRequestor)</code> passing
 * the current position in the source code. The code assist engine analyzes the
 * code in the buffer, determines what kind of language construct is at that
 * position, and proposes ways to complete that construct. These proposals are
 * instances of the class <code>CompletionProposal</code>. These proposals,
 * perhaps after sorting and filtering, are presented to the user to make a
 * choice.
 * </p>
 * <p>
 * The proposal is as follows: insert the {@linkplain #getCompletion()
 * completion string} into the source file buffer, replacing the characters
 * between {@linkplain #getReplaceStart() the start} and
 * {@linkplain #getReplaceEnd() end}. The string can be arbitrary; for example,
 * it might include not only the name of a method but a set of parentheses.
 * Moreover, the source range may include source positions before or after the
 * source position where <code>ICodeAssist.codeComplete</code> was invoked. The
 * rest of the information associated with the proposal is to provide context
 * that may help a user to choose from among competing proposals.
 * </p>
 * <p>
 * The completion engine creates instances of this class; it is not intended to
 * be instantiated or subclassed by clients.
 * </p>
 *
 * @see ICodeAssist#codeComplete(int, CompletionRequestor)
 *
 */
public class CompletionProposal implements Cloneable {
	/**
	 * Completion is a reference to a field. This kind of completion might occur
	 * in a context like <code>"this.ref^ = 0;"</code> and complete it to
	 * <code>"this.refcount = 0;"</code>.
	 *
	 */
	public static final int FIELD_REF = 1;

	/**
	 * Completion is a keyword. This kind of completion might occur in a context
	 * like <code>"public cl^ Foo {}"</code> and complete it to
	 * <code>"public class Foo {}"</code>.
	 *
	 * @see #getKind()
	 */
	public static final int KEYWORD = 2;

	/**
	 * Completion is a reference to a label. This kind of completion might occur
	 * in a context like <code>"break lo^;"</code> and complete it to
	 * <code>"break loop;"</code>.
	 *
	 * @see #getKind()
	 */
	public static final int LABEL_REF = 3;

	/**
	 * Completion is a reference to a local variable. This kind of completion
	 * might occur in a context like <code>"ke^ = 4;"</code> and complete it to
	 * <code>"keys = 4;"</code>.
	 *
	 * @see #getKind()
	 */
	public static final int LOCAL_VARIABLE_REF = 4;

	/**
	 * Completion is a reference to a method. This kind of completion might
	 * occur in a context like <code>"System.out.pr^();"</code> and complete it
	 * to <code>""System.out.println();"</code>.
	 *
	 * @see #getKind()
	 */
	public static final int METHOD_REF = 5;

	/**
	 * Completion is a declaration of a method. This kind of completion might
	 * occur in a context like <code>"new List() {si^};"</code> and complete it
	 * to <code>"new List() {public int size() {} };"</code>.
	 *
	 * @see #getKind()
	 */
	public static final int METHOD_DECLARATION = 6;

	/**
	 * Completion is a reference to a type. Any kind of type is allowed,
	 * including primitive types, reference types, array types, parameterized
	 * types, and type variables. This kind of completion might occur in a
	 * context like <code>"public static Str^ key;"</code> and complete it to
	 * <code>"public static String key;"</code>.
	 *
	 * @see #getKind()
	 */
	public static final int TYPE_REF = 7;

	/**
	 * Completion is a declaration of a variable (locals, parameters, fields,
	 * etc.).
	 *
	 * @see #getKind()
	 */
	public static final int VARIABLE_DECLARATION = 8;

	/**
	 * Completion is a declaration of a new potential method. This kind of
	 * completion might occur in a context like <code>"new List() {si^};"</code>
	 * and complete it to <code>"new List() {public int si() {} };"</code>.
	 *
	 * @see #getKind()
	 *
	 */
	public static final int POTENTIAL_METHOD_DECLARATION = 9;

	/**
	 * Completion is a reference to a method name. This kind of completion might
	 * occur in a context like <code>"import p.X.fo^"</code> and complete it to
	 * <code>"import p.X.foo;"</code>.
	 *
	 * @see #getKind()
	 *
	 */
	public static final int METHOD_NAME_REFERENCE = 10;

	public static final int PACKAGE_REF = 11;

	public static final int USER = 15;

	/**
	 * First valid completion kind.
	 */
	protected static final int FIRST_KIND = FIELD_REF;

	/**
	 * Last valid completion kind.
	 */
	protected static final int LAST_KIND = 22;

	/**
	 * The key of the attribute for
	 * {@link CompletionProposal#setAttribute(String, Object)}, which can be
	 * used to specify the number of required parameters, treating all the
	 * remaining parameters as optional. By default all parameters are treated
	 * as required. This attribute allows completion framework to do it's best
	 * to represent the optional parameters with minimal efforts from the IDE
	 * developer. The value should be of the {@link Integer} type.
	 *
	 * @since 5.0
	 */
	public static final String ATTR_REQUIRED_PARAM_COUNT = DLTKCore.PLUGIN_ID
			+ ".MethodCompletionProposal#ParameterLimit";

	private boolean updateCompletion = false;

	/**
	 * Kind of completion request.
	 */
	private int completionKind;

	/**
	 * Offset in original buffer where ICodeAssist.codeComplete() was requested.
	 */
	private int completionLocation;

	/**
	 * Start position (inclusive) of source range in original buffer containing
	 * the relevant token defaults to empty subrange at [0,0).
	 */
	private int tokenStart = 0;

	/**
	 * End position (exclusive) of source range in original buffer containing
	 * the relevant token; defaults to empty subrange at [0,0).
	 */
	private int tokenEnd = 0;

	/**
	 * Completion string; defaults to empty string.
	 */
	private String completion = Util.EMPTY_STRING;

	/**
	 * Start position (inclusive) of source range in original buffer to be
	 * replaced by completion string; defaults to empty subrange at [0,0).
	 */
	private int replaceStart = 0;

	/**
	 * End position (exclusive) of source range in original buffer to be
	 * replaced by completion string; defaults to empty subrange at [0,0).
	 */
	private int replaceEnd = 0;

	/**
	 * Relevance rating; positive; higher means better; defaults to minimum
	 * rating.
	 */
	private int relevance = 1;

	/**
	 * Unique key of the relevant package or type declaration in the context, or
	 * <code>null</code> if none. Defaults to null.
	 */
	private String declarationKey = null;

	/**
	 * Simple name of the method, field, member, or variable relevant in the
	 * context, or <code>null</code> if none. Defaults to null.
	 */
	private String name = null;

	/**
	 * Unique of the method, field type, member type, relevant in the context,
	 * or <code>null</code> if none. Defaults to null.
	 */
	private String key = null;

	/**
	 * Modifier flags relevant in the context, or <code>Flags.AccDefault</code>
	 * if none. Defaults to <code>Flags.AccDefault</code>.
	 */
	private int flags = 0;

	/**
	 * Parameter names (for method completions), or <code>null</code> if none.
	 * Lazily computed. Defaults to <code>null</code>.
	 */
	private String[] parameterNames = null;

	private IModelElement modelElement;
	private Map<Object, Object> attributes;
	private Object extraInfo;

	private int accessibility = IAccessRule.K_ACCESSIBLE;

	private boolean isConstructor = false;

	/**
	 * Creates a basic completion proposal. All instance field have plausible
	 * default values unless otherwise noted.
	 * <p>
	 * Note that the constructors for this class are internal to the model
	 * implementation. Clients cannot directly create CompletionProposal
	 * objects.
	 * </p>
	 *
	 * @param kind
	 *            one of the kind constants declared on this class
	 * @param completionOffset
	 *            original offset of code completion request
	 * @return a new completion proposal
	 */
	public static CompletionProposal create(int kind, int completionOffset) {
		return new InternalCompletionProposal(kind, completionOffset);
	}

	/**
	 * Creates a basic completion proposal. All instance field have plausible
	 * default values unless otherwise noted.
	 * <p>
	 * Note that the constructors for this class are internal to the model
	 * implementation. Clients cannot directly create CompletionProposal
	 * objects.
	 * </p>
	 *
	 * @param kind
	 *            one of the kind constants declared on this class
	 * @param completionLocation
	 *            original offset of code completion request
	 */
	protected CompletionProposal(int kind, int completionLocation) {
		if ((kind < CompletionProposal.FIRST_KIND)
				|| (kind > CompletionProposal.LAST_KIND)) {
			throw new IllegalArgumentException();
		}

		if (this.completion == null || completionLocation < 0) {
			// Work around for bug 132558
			// (https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558).
			// completionLocation can be -1 if the completion occur at the start
			// of a file or
			// the start of a code snippet but this API isn't design to support
			// negative position.
			if (this.completion == null || completionLocation != -1) {
				throw new IllegalArgumentException();
			}
			completionLocation = 0;
		}

		this.completionKind = kind;
		this.completionLocation = completionLocation;
	}

	/**
	 * Returns the kind of completion being proposed.
	 * <p>
	 * The set of different kinds of completion proposals is expected to change
	 * over time. It is strongly recommended that clients do <b>not</b> assume
	 * that the kind is one of the ones they know about, and code defensively
	 * for the possibility of unexpected future growth.
	 * </p>
	 *
	 * @return the kind; one of the kind constants declared on this class, or
	 *         possibly a kind unknown to the caller
	 */
	public int getKind() {
		return this.completionKind;
	}

	/**
	 * Returns the character index in the source file buffer where source
	 * completion was requested (the <code>offset</code> parameter to
	 * <code>ICodeAssist.codeComplete</code>).
	 *
	 * @return character index in source file buffer
	 * @see ICodeAssist#codeComplete(int,CompletionRequestor)
	 */
	public int getCompletionLocation() {
		return this.completionLocation;
	}

	/**
	 * Returns the character index of the start of the subrange in the source
	 * file buffer containing the relevant token being completed. This token is
	 * either the identifier or language keyword under, or immediately
	 * preceding, the original request offset. If the original request offset is
	 * not within or immediately after an identifier or keyword, then the
	 * position returned is original request offset and the token range is
	 * empty.
	 *
	 * @return character index of token start position (inclusive)
	 */
	public int getTokenStart() {
		return this.tokenStart;
	}

	/**
	 * Returns the character index of the end (exclusive) of the subrange in the
	 * source file buffer containing the relevant token. When there is no
	 * relevant token, the range is empty (
	 * <code>getEndToken() == getStartToken()</code>).
	 *
	 * @return character index of token end position (exclusive)
	 */
	public int getTokenEnd() {
		return this.tokenEnd;
	}

	/**
	 * Sets the character indices of the subrange in the source file buffer
	 * containing the relevant token being completed. This token is either the
	 * identifier or language keyword under, or immediately preceding, the
	 * original request offset. If the original request offset is not within or
	 * immediately after an identifier or keyword, then the source range begins
	 * at original request offset and is empty.
	 * <p>
	 * If not set, defaults to empty subrange at [0,0).
	 * </p>
	 *
	 * @param startIndex
	 *            character index of token start position (inclusive)
	 * @param endIndex
	 *            character index of token end position (exclusive)
	 */
	public void setTokenRange(int startIndex, int endIndex) {
		if (startIndex < 0 || endIndex < startIndex) {
			throw new IllegalArgumentException();
		}

		this.tokenStart = startIndex;
		this.tokenEnd = endIndex;
	}

	/**
	 * Returns the proposed sequence of characters to insert into the source
	 * file buffer, replacing the characters at the specified source range. The
	 * string can be arbitrary; for example, it might include not only the name
	 * of a method but a set of parentheses.
	 * <p>
	 * The client must not modify the array returned.
	 * </p>
	 *
	 * @return the completion string
	 */
	public String getCompletion() {
		if (this.completionKind == METHOD_DECLARATION) {
			this.findParameterNames(null);
			if (this.updateCompletion) {
				this.updateCompletion = false;

				if (this.parameterNames != null) {
					int length = this.parameterNames.length;
					StringBuffer completionBuffer = new StringBuffer(
							this.completion.length());

					int start = 0;
					int end = this.completion.indexOf('%');

					completionBuffer.append(this.completion, start,
							end - start);

					for (int i = 0; i < length; i++) {
						completionBuffer.append(this.parameterNames[i]);
						start = end + 1;
						end = this.completion.indexOf('%', start);
						if (end > -1) {
							completionBuffer.append(this.completion, start,
									end - start);
						} else {
							completionBuffer.append(this.completion, start,
									this.completion.length() - start);
						}
					}
					this.completion = completionBuffer.toString();
				}
			}
		} else if (this.completionKind == METHOD_REF) {
			this.findParameterNames(null);
			if (this.updateCompletion) {
				this.updateCompletion = false;

				if (this.parameterNames != null) {
					int length = this.parameterNames.length;
					StringBuffer completionBuffer = new StringBuffer(
							this.completion.length());

					int start = 0;
					int end = this.completion.indexOf('%');

					completionBuffer.append(this.completion, start,
							end - start);

					for (int i = 0; i < length; i++) {
						completionBuffer.append(this.parameterNames[i]);
						start = end + 1;
						end = this.completion.indexOf('%', start);
						if (end > -1) {
							completionBuffer.append(this.completion, start,
									end - start);
						} else {
							completionBuffer.append(this.completion, start,
									this.completion.length() - start);
						}
					}
					this.completion = completionBuffer.toString();
				}
			}
		}
		return this.completion;
	}

	/**
	 * Sets the proposed sequence of characters to insert into the source file
	 * buffer, replacing the characters at the specified source range. The
	 * string can be arbitrary; for example, it might include not only the name
	 * of a method but a set of parentheses.
	 * <p>
	 * If not set, defaults to an empty character array.
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param completion
	 *            the completion string
	 */
	public void setCompletion(String completion) {
		this.completion = completion;
	}

	/**
	 * Returns the character index of the start of the subrange in the source
	 * file buffer to be replaced by the completion string. If the subrange is
	 * empty (<code>getReplaceEnd() == getReplaceStart()</code>), the completion
	 * string is to be inserted at this index.
	 * <p>
	 * Note that while the token subrange is precisely specified, the
	 * replacement range is loosely constrained and may not bear any direct
	 * relation to the original request offset. For example, it would be
	 * possible for a type completion to propose inserting an import declaration
	 * at the top of the compilation unit; or the completion might include
	 * trailing parentheses and punctuation for a method completion.
	 * </p>
	 *
	 * @return replacement start position (inclusive)
	 */
	public int getReplaceStart() {
		return this.replaceStart;
	}

	/**
	 * Returns the character index of the end of the subrange in the source file
	 * buffer to be replaced by the completion string. If the subrange is empty
	 * (<code>getReplaceEnd() == getReplaceStart()</code>), the completion
	 * string is to be inserted at this index.
	 *
	 * @return replacement end position (exclusive)
	 */
	public int getReplaceEnd() {
		return this.replaceEnd;
	}

	/**
	 * Sets the character indices of the subrange in the source file buffer to
	 * be replaced by the completion string. If the subrange is empty (
	 * <code>startIndex == endIndex</code>), the completion string is to be
	 * inserted at this index.
	 * <p>
	 * If not set, defaults to empty subrange at [0,0).
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param startIndex
	 *            character index of replacement start position (inclusive)
	 * @param endIndex
	 *            character index of replacement end position (exclusive)
	 */
	public void setReplaceRange(int startIndex, int endIndex) {
		if (startIndex < 0 || endIndex < startIndex) {
			throw new IllegalArgumentException();
		}

		this.replaceStart = startIndex;
		this.replaceEnd = endIndex;
	}

	/**
	 * Returns the relative relevance rating of this proposal.
	 *
	 * @return relevance rating of this proposal; ratings are positive; higher
	 *         means better
	 */
	public int getRelevance() {
		return this.relevance;
	}

	/**
	 * Sets the relative relevance rating of this proposal.
	 * <p>
	 * If not set, defaults to the lowest possible rating (1).
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param rating
	 *            relevance rating of this proposal; ratings are positive;
	 *            higher means better
	 */
	public void setRelevance(int rating) {
		if (rating <= 0) {
			throw new IllegalArgumentException();
		}

		this.relevance = rating;
	}

	/**
	 * Returns the key of the relevant declaration in the context, or
	 * <code>null</code> if none.
	 * <p>
	 * This field is available for the following kinds of completion proposals:
	 * <ul>
	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - key of the type that is
	 * being subclassed or implemented</li>
	 * <li><code>METHOD_DECLARATION</code> - key of the type that declares the
	 * method that is being implemented or overridden</li>
	 * </ul>
	 * For kinds of completion proposals, this method returns <code>null</code>.
	 * Clients must not modify the array returned.
	 * </p>
	 *
	 * @return a key, or <code>null</code> if none
	 *
	 */
	public String getDeclarationKey() {
		return this.declarationKey;
	}

	/**
	 * Sets the type or package key of the relevant declaration in the context,
	 * or <code>null</code> if none.
	 * <p>
	 * If not set, defaults to none.
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param key
	 *            the type or package key, or <code>null</code> if none
	 *
	 */
	public void setDeclarationKey(String key) {
		this.declarationKey = key;
	}

	/**
	 * Returns the simple name of the method, field, member, or variable
	 * relevant in the context, or <code>null</code> if none.
	 * <p>
	 * This field is available for the following kinds of completion proposals:
	 * <ul>
	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - the name of the attribute</li>
	 * <li><code>FIELD_REF</code> - the name of the field</li>
	 * <li><code>KEYWORD</code> - the keyword</li>
	 * <li><code>LABEL_REF</code> - the name of the label</li>
	 * <li><code>LOCAL_VARIABLE_REF</code> - the name of the local variable</li>
	 * <li><code>METHOD_REF</code> - the name of the method (the type simple
	 * name for constructor)</li>
	 * <li><code>METHOD_DECLARATION</code> - the name of the method (the type
	 * simple name for constructor)</li>
	 * <li><code>VARIABLE_DECLARATION</code> - the name of the variable</li>
	 * <li><code>POTENTIAL_METHOD_DECLARATION</code> - the name of the
	 * method</li>
	 * </ul>
	 * For kinds of completion proposals, this method returns <code>null</code>.
	 * Clients must not modify the array returned.
	 * </p>
	 *
	 * @return the keyword, field, method, local variable, or member name, or
	 *         <code>null</code> if none
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * Sets the simple name of the method (type simple name for constructor),
	 * field, member, or variable relevant in the context, or <code>null</code>
	 * if none.
	 * <p>
	 * If not set, defaults to none.
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param name
	 *            the keyword, field, method, local variable, or member name, or
	 *            <code>null</code> if none
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Returns the key relevant in the context, or <code>null</code> if none.
	 * <p>
	 * This field is available for the following kinds of completion proposals:
	 * <ul>
	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method key of the
	 * constructor that is being invoked, or <code>null</code> if the declaring
	 * type is an interface</li>
	 * <li><code>METHOD_DECLARATION</code> - method key of the method that is
	 * being implemented or overridden</li>
	 * </ul>
	 * For kinds of completion proposals, this method returns <code>null</code>.
	 * Clients must not modify the array returned.
	 * </p>
	 *
	 * @return the key, or <code>null</code> if none
	 *
	 */
	public String getKey() {
		return this.key;
	}

	/**
	 * Sets the key of the method, field type, member type, relevant in the
	 * context, or <code>null</code> if none.
	 * <p>
	 * If not set, defaults to none.
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param key
	 *            the key, or <code>null</code> if none
	 *
	 */
	public void setKey(String key) {
		this.key = key;
	}

	/**
	 * Returns the modifier flags relevant in the context, or
	 * <code>Flags.AccDefault</code> if none.
	 * <p>
	 * This field is available for the following kinds of completion proposals:
	 * <ul>
	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - modifier flags of the
	 * attribute that is referenced;
	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - modifier flags of the
	 * constructor that is referenced</li>
	 * <li><code>FIELD_REF</code> - modifier flags of the field that is
	 * referenced; <code>Flags.AccEnum</code> can be used to recognize
	 * references to enum constants</li>
	 * <li><code>KEYWORD</code> - modifier flag corrresponding to the modifier
	 * keyword</li>
	 * <li><code>LOCAL_VARIABLE_REF</code> - modifier flags of the local
	 * variable that is referenced</li>
	 * <li><code>METHOD_REF</code> - modifier flags of the method that is
	 * referenced; <code>Flags.AccAnnotation</code> can be used to recognize
	 * references to annotation type members</li>
	 * <li><code>METHOD_DECLARATION</code> - modifier flags for the method that
	 * is being implemented or overridden</li>
	 * <li><code>TYPE_REF</code> - modifier flags of the type that is
	 * referenced; <code>Flags.AccInterface</code> can be used to recognize
	 * references to interfaces, <code>Flags.AccEnum</code> enum types, and
	 * <code>Flags.AccAnnotation</code> annotation types</li>
	 * <li><code>VARIABLE_DECLARATION</code> - modifier flags for the variable
	 * being declared</li>
	 * <li><code>POTENTIAL_METHOD_DECLARATION</code> - modifier flags for the
	 * method that is being created</li>
	 * </ul>
	 * For other kinds of completion proposals, this method returns
	 * <code>Flags.AccDefault</code>.
	 * </p>
	 *
	 * @return the modifier flags, or <code>Flags.AccDefault</code> if none
	 * @see Flags
	 */
	public int getFlags() {
		return this.flags;
	}

	/**
	 * Sets the modifier flags relevant in the context.
	 * <p>
	 * If not set, defaults to none.
	 * </p>
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param flags
	 *            the modifier flags, or <code>Flags.AccDefault</code> if none
	 */
	public void setFlags(int flags) {
		this.flags = flags;
	}

	/**
	 * Finds the method parameter names. This information is relevant to method
	 * reference (and method declaration proposals). Returns <code>null</code>
	 * if not available or not relevant.
	 * <p>
	 * The client must not modify the array returned.
	 * </p>
	 * <p>
	 * <b>Note that this is an expensive thing to compute, which may require
	 * parsing source files, etc. Use sparingly.</b>
	 * </p>
	 *
	 * @param monitor
	 *            the progress monitor, or <code>null</code> if none
	 * @return the parameter names, or <code>null</code> if none or not
	 *         available or not relevant
	 */
	public String[] findParameterNames(IProgressMonitor monitor) {
		return this.parameterNames;
	}

	/**
	 * Returns the method parameter names. This information is relevant to
	 * method reference (and method declaration proposals). Returns
	 * <code>null</code> if not available or not relevant.
	 * <p>
	 * The client must not modify the array returned.
	 * </p>
	 *
	 * @return the parameter names, or <code>null</code> if none or not
	 *         available or not relevant
	 */
	public String[] getParameterNames() {
		return this.parameterNames;
	}

	/**
	 * Sets the method parameter names. This information is relevant to method
	 * reference (and method declaration proposals).
	 * <p>
	 * The completion engine creates instances of this class and sets its
	 * properties; this method is not intended to be used by other clients.
	 * </p>
	 *
	 * @param parameterNames
	 *            the parameter names, or <code>null</code> if none
	 */
	public void setParameterNames(String[] parameterNames) {
		this.parameterNames = parameterNames;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append('[');
		switch (this.completionKind) {
		case CompletionProposal.FIELD_REF:
			buffer.append("FIELD_REF"); //$NON-NLS-1$
			break;
		case CompletionProposal.KEYWORD:
			buffer.append("KEYWORD"); //$NON-NLS-1$
			break;
		case CompletionProposal.LABEL_REF:
			buffer.append("LABEL_REF"); //$NON-NLS-1$
			break;
		case CompletionProposal.LOCAL_VARIABLE_REF:
			buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$
			break;
		case CompletionProposal.METHOD_DECLARATION:
			buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$
			if (this.isConstructor()) {
				buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
			}
			break;
		case CompletionProposal.METHOD_REF:
			buffer.append("METHOD_REF"); //$NON-NLS-1$
			if (this.isConstructor()) {
				buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
			}
			break;
		case CompletionProposal.TYPE_REF:
			buffer.append("TYPE_REF"); //$NON-NLS-1$
			break;
		case CompletionProposal.VARIABLE_DECLARATION:
			buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$
			break;
		case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
			buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
			break;
		case CompletionProposal.METHOD_NAME_REFERENCE:
			buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
			break;
		default:
			buffer.append("PROPOSAL"); //$NON-NLS-1$
			break;

		}
		buffer.append("]{completion:"); //$NON-NLS-1$
		if (this.completion != null)
			buffer.append(this.completion);
		buffer.append(", declSign:"); //$NON-NLS-1$
		buffer.append(", declKey:"); //$NON-NLS-1$
		if (this.declarationKey != null)
			buffer.append(this.declarationKey);
		buffer.append(", key:"); //$NON-NLS-1$
		if (this.key != null)
			buffer.append(key);
		buffer.append(", name:"); //$NON-NLS-1$
		if (this.name != null)
			buffer.append(this.name);
		buffer.append(", ["); //$NON-NLS-1$
		buffer.append(this.replaceStart);
		buffer.append(',');
		buffer.append(this.replaceEnd);
		buffer.append("], relevance="); //$NON-NLS-1$
		buffer.append(this.relevance);
		buffer.append('}');
		return buffer.toString();
	}

	public IModelElement getModelElement() {
		return modelElement;
	}

	public void setModelElement(IModelElement modelElement) {
		this.modelElement = modelElement;
	}

	private static final String FOREIGN = CompletionProposal.class.getName()
			+ ".FOREIGN";

	public void setForeign(Object f) {
		setAttribute(FOREIGN, f);
	}

	public Object getForeign() {
		return getAttribute(FOREIGN);
	}

	public Object getExtraInfo() {
		return extraInfo;
	}

	public void setExtraInfo(Object extraInfo) {
		this.extraInfo = extraInfo;
	}

	public void setAttribute(String key, Object value) {
		internalSetAttribute(key, value);
	}

	private void internalSetAttribute(Object key, Object value) {
		if (value != null) {
			if (attributes == null) {
				attributes = new HashMap<>(4);
			}
			attributes.put(key, value);
		} else if (attributes != null) {
			attributes.remove(key);
		}
	}

	public Object getAttribute(String key) {
		return attributes != null ? attributes.get(key) : null;
	}

	/**
	 * Sets the specified flag.
	 */
	public void setFlag(CompletionProposalFlag flag) {
		internalSetAttribute(flag, Boolean.TRUE);
	}

	/**
	 * Clears the specified flag.
	 */
	public void clearFlag(CompletionProposalFlag flag) {
		internalSetAttribute(flag, null);
	}

	/**
	 * Tests if the specified flag is set.
	 */
	public boolean hasFlag(CompletionProposalFlag flag) {
		return attributes != null && attributes.containsKey(flag);
	}

	/**
	 * Returns the accessibility of the proposal.
	 * <p>
	 * This field is available for the following kinds of completion proposals:
	 * <ul>
	 * <li><code>TYPE_REF</code> - accessibility of the type</li>
	 * </ul>
	 * For these kinds of completion proposals, this method returns
	 * {@link IAccessRule#K_ACCESSIBLE} or {@link IAccessRule#K_DISCOURAGED} or
	 * {@link IAccessRule#K_NON_ACCESSIBLE}. By default this method return
	 * {@link IAccessRule#K_ACCESSIBLE}.
	 * </p>
	 *
	 * @see IAccessRule
	 *
	 * @return the accessibility of the proposal
	 *
	 */
	public int getAccessibility() {
		return this.accessibility;
	}

	public void setAccessibility(int accessiblility) {
		this.accessibility = accessiblility;
	}

	/**
	 * Returns whether this proposal is a constructor.
	 * <p>
	 * This field is available for the following kinds of completion proposals:
	 * <ul>
	 * <li><code>METHOD_REF</code> - return <code>true</code> if the referenced
	 * method is a constructor</li>
	 * <li><code>METHOD_DECLARATION</code> - return <code>true</code> if the
	 * declared method is a constructor</li>
	 * </ul>
	 * For kinds of completion proposals, this method returns <code>false</code>
	 * .
	 * </p>
	 *
	 * @return <code>true</code> if the proposal is a constructor.
	 *
	 */
	public boolean isConstructor() {
		return this.isConstructor;
	}

	public void setIsConstructor(boolean isConstructor) {
		this.isConstructor = isConstructor;
	}

	public void setCompletionLocation(int i) {
		this.completionLocation = i;
	}

	@Override
	public CompletionProposal clone() {
		try {
			final CompletionProposal copy = (CompletionProposal) super.clone();
			// parameterNames array is shared, don't want to copy it.
			if (attributes != null) {
				copy.attributes = new HashMap<>(attributes);
			}
			return copy;
		} catch (CloneNotSupportedException e) {
			throw new AssertionError(e);
		}
	}
}
