/*******************************************************************************
 * Copyright (c) 2005, 2018 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.ui.text.java;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.StyledString;

import org.eclipse.jdt.core.CompletionContext;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.Signature;

import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.template.java.SignatureUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.corext.util.Strings;

import org.eclipse.jdt.ui.JavaElementImageDescriptor;
import org.eclipse.jdt.ui.JavaElementLabels;

import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;


/**
 * Provides labels for java content assist proposals. The functionality is
 * similar to the one provided by {@link org.eclipse.jdt.ui.JavaElementLabels},
 * but based on signatures and {@link CompletionProposal}s.
 *
 * @see Signature
 * @since 3.1
 */
public class CompletionProposalLabelProvider {

	private static final String QUALIFIER_SEPARATOR= JavaElementLabels.CONCAT_STRING;
	private static final String RETURN_TYPE_SEPARATOR= JavaElementLabels.DECL_STRING;
	private static final String VAR_TYPE_SEPARATOR= JavaElementLabels.DECL_STRING;


	/**
	 * The completion context.
	 *
	 * @since 3.2
	 */
	private CompletionContext fContext;

	/**
	 * Creates a new label provider.
	 */
	public CompletionProposalLabelProvider() {
	}

	/**
	 * Creates and returns a parameter list of the given method or type proposal suitable for
	 * display. The list does not include parentheses. The lower bound of parameter types is
	 * returned.
	 * <p>
	 * Examples:
	 * 
	 * <pre>
	 *   &quot;void method(int i, String s)&quot; -&gt; &quot;int i, String s&quot;
	 *   &quot;? extends Number method(java.lang.String s, ? super Number n)&quot; -&gt; &quot;String s, Number n&quot;
	 * </pre>
	 * 
	 * </p>
	 * 
	 * @param proposal the proposal to create the parameter list for
	 * @return the list of comma-separated parameters suitable for display
	 */
	public String createParameterList(CompletionProposal proposal) {
		String paramList;
		int kind= proposal.getKind();
		switch (kind) {
			case CompletionProposal.METHOD_REF:
			case CompletionProposal.CONSTRUCTOR_INVOCATION:
				paramList= appendUnboundedParameterList(new StyledString(), proposal).getString();
				return org.eclipse.jdt.internal.core.manipulation.util.Strings.markJavaElementLabelLTR(paramList);
			case CompletionProposal.TYPE_REF:
			case CompletionProposal.JAVADOC_TYPE_REF:
				paramList= appendTypeParameterList(new StyledString(), proposal).getString();
				return org.eclipse.jdt.internal.core.manipulation.util.Strings.markJavaElementLabelLTR(paramList);
			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
				paramList= appendUnboundedParameterList(new StyledString(), proposal).getString();
				return org.eclipse.jdt.internal.core.manipulation.util.Strings.markJavaElementLabelLTR(paramList);
			default:
				Assert.isLegal(false);
				return null; // dummy
		}
	}

	/**
	 * Appends the parameter list to <code>buffer</code>.
	 *
	 * @param buffer the buffer to append to
	 * @param methodProposal the method proposal
	 * @return the modified <code>buffer</code>
	 */
	private StyledString appendUnboundedParameterList(StyledString buffer, CompletionProposal methodProposal) {
		// TODO remove once https://bugs.eclipse.org/bugs/show_bug.cgi?id=85293
		// gets fixed.
		char[] signature= SignatureUtil.fix83600(methodProposal.getSignature());
		char[][] parameterNames= methodProposal.findParameterNames(null);
		char[][] parameterTypes= Signature.getParameterTypes(signature);

		for (int i= 0; i < parameterTypes.length; i++)
			parameterTypes[i]= createTypeDisplayName(SignatureUtil.getLowerBound(parameterTypes[i]));

		if (Flags.isVarargs(methodProposal.getFlags())) {
			int index= parameterTypes.length - 1;
			parameterTypes[index]= convertToVararg(parameterTypes[index]);
		}
		return appendParameterSignature(buffer, parameterTypes, parameterNames);
	}

	/**
	 * Appends the type parameter list to <code>buffer</code>.
	 *
	 * @param buffer the buffer to append to
	 * @param typeProposal the type proposal
	 * @return the modified <code>buffer</code>
	 * @since 3.2
	 */
	private StyledString appendTypeParameterList(StyledString buffer, CompletionProposal typeProposal) {
		// TODO remove once https://bugs.eclipse.org/bugs/show_bug.cgi?id=85293
		// gets fixed.
		char[] signature= SignatureUtil.fix83600(typeProposal.getSignature());
		char[][] typeParameters= Signature.getTypeArguments(signature);
		for (int i= 0; i < typeParameters.length; i++) {
			char[] param= typeParameters[i];
			typeParameters[i]= Signature.toCharArray(param);
		}
		return appendParameterSignature(buffer, typeParameters, null);
	}

	/**
	 * Converts the display name for an array type into a variable arity display name.
	 * <p>
	 * Examples:
	 * <ul>
	 * <li> "int[]" -> "int..."</li>
	 * <li> "Object[][]" -> "Object[]..."</li>
	 * <li> "String" -> "String"</li>
	 * </ul>
	 * </p>
	 * <p>
	 * If <code>typeName</code> does not include the substring "[]", it is returned unchanged.
	 * </p>
	 *
	 * @param typeName the type name to convert
	 * @return the converted type name
	 * @since 3.2
	 */
    private char[] convertToVararg(char[] typeName) {
    	if (typeName == null)
    		return typeName;
    	final int len= typeName.length;
		if (len < 2)
    		return typeName;

    	if (typeName[len - 1] != ']')
    		return typeName;
    	if (typeName[len - 2] != '[')
    		return typeName;

		char[] vararg= new char[len + 1];
		System.arraycopy(typeName, 0, vararg, 0, len - 2);
		vararg[len - 2]= '.';
		vararg[len - 1]= '.';
		vararg[len]= '.';
	    return vararg;
    }

	/**
	 * Returns the display string for a java type signature.
	 *
	 * @param typeSignature the type signature to create a display name for
	 * @return the display name for <code>typeSignature</code>
	 * @throws IllegalArgumentException if <code>typeSignature</code> is not a
	 *         valid signature
	 * @see Signature#toCharArray(char[])
	 * @see Signature#getSimpleName(char[])
	 */
	private char[] createTypeDisplayName(char[] typeSignature) throws IllegalArgumentException {
		char[] displayName= Signature.getSimpleName(Signature.toCharArray(typeSignature));

		// XXX see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84675
		boolean useShortGenerics= false;
		if (useShortGenerics) {
			StringBuffer buf= new StringBuffer();
			buf.append(displayName);
			int pos;
			do {
				pos= buf.indexOf("? extends "); //$NON-NLS-1$
				if (pos >= 0) {
					buf.replace(pos, pos + 10, "+"); //$NON-NLS-1$
				} else {
					pos= buf.indexOf("? super "); //$NON-NLS-1$
					if (pos >= 0)
						buf.replace(pos, pos + 8, "-"); //$NON-NLS-1$
				}
			} while (pos >= 0);
			return buf.toString().toCharArray();
		}
		return displayName;
	}

	/**
	 * Creates a display string of a parameter list (without the parentheses)
	 * for the given parameter types and names.
	 *
	 * @param buffer the string buffer
	 * @param parameterTypes the parameter types
	 * @param parameterNames the parameter names
	 * @return the display string of the parameter list defined by the passed arguments
	 */
	private final StyledString appendParameterSignature(StyledString buffer, char[][] parameterTypes, char[][] parameterNames) {
		if (parameterTypes != null) {
			for (int i = 0; i < parameterTypes.length; i++) {
				if (i > 0) {
					buffer.append(',');
					buffer.append(' ');
				}
				buffer.append(parameterTypes[i]);
				if (parameterNames != null && parameterNames[i] != null) {
					buffer.append(' ');
					buffer.append(parameterNames[i]);
				}
			}
		}
		return buffer;
	}

	/**
	 * Creates a display label for the given method proposal. The display label
	 * consists of:
	 * <ul>
	 *   <li>the method name</li>
	 *   <li>the parameter list (see {@link #createParameterList(CompletionProposal)})</li>
	 *   <li>the upper bound of the return type (see {@link SignatureUtil#getUpperBound(String)})</li>
	 *   <li>the raw simple name of the declaring type</li>
	 * </ul>
	 * <p>
	 * Examples:
	 * For the <code>get(int)</code> method of a variable of type <code>List<? extends Number></code>, the following
	 * display name is returned: <code>get(int index)  Number - List</code>.<br>
	 * For the <code>add(E)</code> method of a variable of type <code>List<? super Number></code>, the following
	 * display name is returned: <code>add(Number o)  void - List</code>.<br>
	 * </p>
	 *
	 * @param methodProposal the method proposal to display
	 * @return the display label for the given method proposal
	 */
	StyledString createMethodProposalLabel(CompletionProposal methodProposal) {
		StyledString nameBuffer= new StyledString();

		// method name
		nameBuffer.append(methodProposal.getName());

		// parameters
		nameBuffer.append('(');
		appendUnboundedParameterList(nameBuffer, methodProposal);
		nameBuffer.append(')');

		// return type
		if (!methodProposal.isConstructor()) {
			// TODO remove SignatureUtil.fix83600 call when bugs are fixed
			char[] returnType= createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(methodProposal.getSignature()))));
			nameBuffer.append(RETURN_TYPE_SEPARATOR);
			nameBuffer.append(returnType);
		}

		// declaring type
		nameBuffer.append(QUALIFIER_SEPARATOR, StyledString.QUALIFIER_STYLER);
		String declaringType= extractDeclaringTypeFQN(methodProposal);

		if (methodProposal.getRequiredProposals() != null) {
			String qualifier= Signature.getQualifier(declaringType);
			if (qualifier.length() > 0) {
				nameBuffer.append(qualifier, StyledString.QUALIFIER_STYLER);
				nameBuffer.append('.', StyledString.QUALIFIER_STYLER);
			}
		}

		declaringType= Signature.getSimpleName(declaringType);
		nameBuffer.append(declaringType, StyledString.QUALIFIER_STYLER);
		return org.eclipse.jdt.internal.corext.util.Strings.markJavaElementLabelLTR(nameBuffer);
	}

	/**
	 * Creates a display label for the given method proposal. The display label consists of:
	 * <ul>
	 * <li>the method name</li>
	 * <li>the raw simple name of the declaring type</li>
	 * </ul>
	 * <p>
	 * Examples: For the <code>get(int)</code> method of a variable of type
	 * <code>List<? extends Number></code>, the following display name is returned <code>get(int) - List</code>.<br>
	 * For the <code>add(E)</code> method of a variable of type <code>List</code>, the
	 * following display name is returned:
	 * <code>add(Object) - List</code>.<br>
	 * </p>
	 *
	 * @param methodProposal the method proposal to display
	 * @return the display label for the given method proposal
	 * @since 3.2
	 */
	StyledString createJavadocMethodProposalLabel(CompletionProposal methodProposal) {
		StyledString nameBuffer= new StyledString();

		// method name
		nameBuffer.append(methodProposal.getCompletion());

		// declaring type
		nameBuffer.append(QUALIFIER_SEPARATOR, StyledString.QUALIFIER_STYLER);
		String declaringType= extractDeclaringTypeFQN(methodProposal);
		declaringType= Signature.getSimpleName(declaringType);
		nameBuffer.append(declaringType, StyledString.QUALIFIER_STYLER);

		return org.eclipse.jdt.internal.corext.util.Strings.markJavaElementLabelLTR(nameBuffer);
	}

	StyledString createOverrideMethodProposalLabel(CompletionProposal methodProposal) {
		StyledString nameBuffer= new StyledString();

		// method name
		nameBuffer.append(methodProposal.getName());

		// parameters
		nameBuffer.append('(');
		appendUnboundedParameterList(nameBuffer, methodProposal);
		nameBuffer.append(')');

		nameBuffer.append(RETURN_TYPE_SEPARATOR);

		// return type
		// TODO remove SignatureUtil.fix83600 call when bugs are fixed
		char[] returnType= createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(methodProposal.getSignature()))));
		nameBuffer.append(returnType);

		// declaring type
		nameBuffer.append(QUALIFIER_SEPARATOR, StyledString.QUALIFIER_STYLER);

		String declaringType= extractDeclaringTypeFQN(methodProposal);
		declaringType= Signature.getSimpleName(declaringType);
		nameBuffer.append(Messages.format(JavaTextMessages.ResultCollector_overridingmethod, BasicElementLabels.getJavaElementName(declaringType)), StyledString.QUALIFIER_STYLER);

		return nameBuffer;
	}

	/**
	 * Extracts the fully qualified name of the declaring type of a method
	 * reference.
	 *
	 * @param methodProposal a proposed method
	 * @return the qualified name of the declaring type
	 */
	private String extractDeclaringTypeFQN(CompletionProposal methodProposal) {
		char[] declaringTypeSignature= methodProposal.getDeclarationSignature();
		// special methods may not have a declaring type: methods defined on arrays etc.
		// TODO remove when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=84690 gets fixed
		if (declaringTypeSignature == null)
			return "java.lang.Object"; //$NON-NLS-1$
		return Signature.toString(Signature.getTypeErasure(String.valueOf(declaringTypeSignature)));
	}

	/**
	 * Creates a display label for a given type proposal. The display label
	 * consists of:
	 * <ul>
	 *   <li>the simple type name (erased when the context is in javadoc)</li>
	 *   <li>the package name</li>
	 * </ul>
	 * <p>
	 * Examples:
	 * A proposal for the generic type <code>java.util.List&lt;E&gt;</code>, the display label
	 * is: <code>List<E> - java.util</code>.
	 * </p>
	 *
	 * @param typeProposal the method proposal to display
	 * @return the display label for the given type proposal
	 */
	StyledString createTypeProposalLabel(CompletionProposal typeProposal) {
		char[] signature;
		if (fContext != null && fContext.isInJavadoc())
			signature= Signature.getTypeErasure(typeProposal.getSignature());
		else
			signature= typeProposal.getSignature();
		char[] fullName= Signature.toCharArray(signature);
		return createTypeProposalLabel(fullName);
	}

	StyledString createJavadocTypeProposalLabel(CompletionProposal typeProposal) {
		char[] fullName= Signature.toCharArray(typeProposal.getSignature());
		return createJavadocTypeProposalLabel(fullName);
	}

	StyledString createJavadocSimpleProposalLabel(CompletionProposal proposal) {
		// TODO get rid of this
		return createSimpleLabel(proposal);
	}

	StyledString createTypeProposalLabel(char[] fullName) {
		// only display innermost type name as type name, using any
		// enclosing types as qualification
		int qIndex= findSimpleNameStart(fullName);

		StyledString buf= new StyledString();
		buf.append(new String(fullName, qIndex, fullName.length - qIndex));
		if (qIndex > 0) {
			buf.append(JavaElementLabels.CONCAT_STRING, StyledString.QUALIFIER_STYLER);
			buf.append(new String(fullName, 0, qIndex - 1), StyledString.QUALIFIER_STYLER);
		}
		return org.eclipse.jdt.internal.corext.util.Strings.markJavaElementLabelLTR(buf);
	}

	StyledString createJavadocTypeProposalLabel(char[] fullName) {
		// only display innermost type name as type name, using any
		// enclosing types as qualification
		int qIndex= findSimpleNameStart(fullName);

		StyledString buf= new StyledString("{@link "); //$NON-NLS-1$
		buf.append(new String(fullName, qIndex, fullName.length - qIndex));
		buf.append('}');
		if (qIndex > 0) {
			buf.append(JavaElementLabels.CONCAT_STRING, StyledString.QUALIFIER_STYLER);
			buf.append(new String(fullName, 0, qIndex - 1), StyledString.QUALIFIER_STYLER);
		}
		return org.eclipse.jdt.internal.corext.util.Strings.markJavaElementLabelLTR(buf);
	}

	private int findSimpleNameStart(char[] array) {
		int lastDot= 0;
		for (int i= 0, len= array.length; i < len; i++) {
			char ch= array[i];
			if (ch == '<') {
				return lastDot;
			} else if (ch == '.') {
				lastDot= i + 1;
			}
		}
		return lastDot;
	}

	StyledString createSimpleLabelWithType(CompletionProposal proposal) {
		StyledString buf= new StyledString();
		buf.append(proposal.getCompletion());
		char[] typeName= Signature.getSignatureSimpleName(proposal.getSignature());
		if (typeName.length > 0) {
			buf.append(VAR_TYPE_SEPARATOR);
			buf.append(typeName);
		}
		return Strings.markJavaElementLabelLTR(buf);
	}

	/**
	 * Returns whether the given string starts with "this.".
	 *
	 * @param string string to test
	 * @return <code>true</code> if the given string starts with "this."
	 * @since 3.3
	 */
	private boolean isThisPrefix(char[] string) {
		if (string == null || string.length < 5)
			return false;
		return string[0] == 't' && string[1] == 'h' && string[2] == 'i' && string[3] == 's' && string[4] == '.';
	}

	StyledString createLabelWithTypeAndDeclaration(CompletionProposal proposal) {
		char[] name= proposal.getCompletion();
		if (!isThisPrefix(name))
			name= proposal.getName();

		StyledString buf= new StyledString();
		buf.append(name);
		char[] typeName= Signature.getSignatureSimpleName(proposal.getSignature());
		if (typeName.length > 0) {
			buf.append(VAR_TYPE_SEPARATOR);
			buf.append(typeName);
		}
		char[] declaration= proposal.getDeclarationSignature();
		if (declaration != null) {
			declaration= Signature.getSignatureSimpleName(declaration);
			if (declaration.length > 0) {
				buf.append(QUALIFIER_SEPARATOR, StyledString.QUALIFIER_STYLER);
				if (proposal.getRequiredProposals() != null) {
					String declaringType= extractDeclaringTypeFQN(proposal);
					String qualifier= Signature.getQualifier(declaringType);
					if (qualifier.length() > 0) {
						buf.append(qualifier, StyledString.QUALIFIER_STYLER);
						buf.append('.', StyledString.QUALIFIER_STYLER);
					}
				}
				buf.append(declaration, StyledString.QUALIFIER_STYLER);
			}
		}

		return Strings.markJavaElementLabelLTR(buf);
	}

	StyledString createModuleProposalLabel(CompletionProposal proposal) {
		int kind= proposal.getKind();
		Assert.isTrue(kind == CompletionProposal.MODULE_REF || kind == CompletionProposal.MODULE_DECLARATION);
		char[] label= proposal.getDeclarationSignature();
		Assert.isNotNull(label);
		return Strings.markJavaElementLabelLTR(new StyledString(String.valueOf(label)));
	}

	StyledString createPackageProposalLabel(CompletionProposal proposal) {
		Assert.isTrue(proposal.getKind() == CompletionProposal.PACKAGE_REF);
		return Strings.markJavaElementLabelLTR(new StyledString(String.valueOf(proposal.getDeclarationSignature())));
	}

	StyledString createSimpleLabel(CompletionProposal proposal) {
		return Strings.markJavaElementLabelLTR(new StyledString(String.valueOf(proposal.getCompletion())));
	}

	StyledString createAnonymousTypeLabel(CompletionProposal proposal) {
		char[] declaringTypeSignature= proposal.getDeclarationSignature();
		declaringTypeSignature= Signature.getTypeErasure(declaringTypeSignature);

		StyledString buffer= new StyledString();
		buffer.append(Signature.getSignatureSimpleName(declaringTypeSignature));
		buffer.append('(');
		appendUnboundedParameterList(buffer, proposal);
		buffer.append(')');
		buffer.append("  "); //$NON-NLS-1$
		buffer.append(JavaTextMessages.ResultCollector_anonymous_type);

		if (proposal.getRequiredProposals() != null) {
			char[] signatureQualifier= Signature.getSignatureQualifier(declaringTypeSignature);
			if (signatureQualifier.length > 0) {
				buffer.append(JavaElementLabels.CONCAT_STRING, StyledString.QUALIFIER_STYLER);
				buffer.append(signatureQualifier, StyledString.QUALIFIER_STYLER);
			}
		}

		return Strings.markJavaElementLabelLTR(buffer);
	}

	/**
	 * Creates the display label for a given <code>CompletionProposal</code>.
	 *
	 * @param proposal the completion proposal to create the display label for
	 * @return the display label for <code>proposal</code>
	 */
	public String createLabel(CompletionProposal proposal) {
		return createStyledLabel(proposal).getString();
	}

	/**
	 * Creates a display label with styles for a given <code>CompletionProposal</code>.
	 *
	 * @param proposal the completion proposal to create the display label for
	 * @return the display label for <code>proposal</code>
	 *
	 * @since 3.4
	 */
	public StyledString createStyledLabel(CompletionProposal proposal) {
		switch (proposal.getKind()) {
			case CompletionProposal.METHOD_NAME_REFERENCE:
			case CompletionProposal.METHOD_REF:
			case CompletionProposal.CONSTRUCTOR_INVOCATION:
			case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER:
			case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
				if (fContext != null && fContext.isInJavadoc())
					return createJavadocMethodProposalLabel(proposal);
				return createMethodProposalLabel(proposal);
			case CompletionProposal.METHOD_DECLARATION:
				return createOverrideMethodProposalLabel(proposal);
			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
				return createAnonymousTypeLabel(proposal);
			case CompletionProposal.TYPE_REF:
				return createTypeProposalLabel(proposal);
			case CompletionProposal.JAVADOC_TYPE_REF:
				return createJavadocTypeProposalLabel(proposal);
			case CompletionProposal.JAVADOC_FIELD_REF:
			case CompletionProposal.JAVADOC_VALUE_REF:
			case CompletionProposal.JAVADOC_BLOCK_TAG:
			case CompletionProposal.JAVADOC_INLINE_TAG:
			case CompletionProposal.JAVADOC_PARAM_REF:
				return createJavadocSimpleProposalLabel(proposal);
			case CompletionProposal.JAVADOC_METHOD_REF:
				return createJavadocMethodProposalLabel(proposal);
			case CompletionProposal.PACKAGE_REF:
				return createPackageProposalLabel(proposal);
			case CompletionProposal.MODULE_REF:
			case CompletionProposal.MODULE_DECLARATION:
				return createModuleProposalLabel(proposal);
			case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
			case CompletionProposal.FIELD_REF:
			case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER:
				return createLabelWithTypeAndDeclaration(proposal);
			case CompletionProposal.LOCAL_VARIABLE_REF:
			case CompletionProposal.VARIABLE_DECLARATION:
				return createSimpleLabelWithType(proposal);
			case CompletionProposal.KEYWORD:
			case CompletionProposal.LABEL_REF:
				return createSimpleLabel(proposal);
			default:
				Assert.isTrue(false);
				return null;
		}
	}

	/**
	 * Creates and returns a decorated image descriptor for a completion proposal.
	 *
	 * @param proposal the proposal for which to create an image descriptor
	 * @return the created image descriptor, or <code>null</code> if no image is available
	 */
	public ImageDescriptor createImageDescriptor(CompletionProposal proposal) {
		final int flags= proposal.getFlags();

		ImageDescriptor descriptor;
		switch (proposal.getKind()) {
			case CompletionProposal.METHOD_DECLARATION:
			case CompletionProposal.METHOD_NAME_REFERENCE:
			case CompletionProposal.METHOD_REF:
			case CompletionProposal.CONSTRUCTOR_INVOCATION:
			case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER:
			case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
			case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
				descriptor= JavaElementImageProvider.getMethodImageDescriptor(false, flags);
				break;
			case CompletionProposal.TYPE_REF:
				switch (Signature.getTypeSignatureKind(proposal.getSignature())) {
					case Signature.CLASS_TYPE_SIGNATURE:
						descriptor= JavaElementImageProvider.getTypeImageDescriptor(false, false, flags, false);
						break;
					case Signature.TYPE_VARIABLE_SIGNATURE:
						descriptor= JavaPluginImages.DESC_OBJS_TYPEVARIABLE;
						break;
					default:
						descriptor= null;
				}
				break;
			case CompletionProposal.FIELD_REF:
			case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER:
				descriptor= JavaElementImageProvider.getFieldImageDescriptor(false, flags);
				break;
			case CompletionProposal.LOCAL_VARIABLE_REF:
			case CompletionProposal.VARIABLE_DECLARATION:
				descriptor= JavaPluginImages.DESC_OBJS_LOCAL_VARIABLE;
				break;
			case CompletionProposal.PACKAGE_REF:
				descriptor= JavaPluginImages.DESC_OBJS_PACKAGE;
				break;
			case CompletionProposal.MODULE_REF:
			case CompletionProposal.MODULE_DECLARATION:
				descriptor= JavaPluginImages.DESC_OBJS_MODULE;
				break;
			case CompletionProposal.KEYWORD:
			case CompletionProposal.LABEL_REF:
				descriptor= null;
				break;
			case CompletionProposal.JAVADOC_METHOD_REF:
			case CompletionProposal.JAVADOC_TYPE_REF:
			case CompletionProposal.JAVADOC_FIELD_REF:
			case CompletionProposal.JAVADOC_VALUE_REF:
			case CompletionProposal.JAVADOC_BLOCK_TAG:
			case CompletionProposal.JAVADOC_INLINE_TAG:
			case CompletionProposal.JAVADOC_PARAM_REF:
				descriptor = JavaPluginImages.DESC_OBJS_JAVADOCTAG;
				break;
			default:
				descriptor= null;
				Assert.isTrue(false);
		}

		if (descriptor == null)
			return null;
		return decorateImageDescriptor(descriptor, proposal);
	}

	ImageDescriptor createMethodImageDescriptor(CompletionProposal proposal) {
		final int flags= proposal.getFlags();
		return decorateImageDescriptor(JavaElementImageProvider.getMethodImageDescriptor(false, flags), proposal);
	}

	ImageDescriptor createTypeImageDescriptor(CompletionProposal proposal) {
		final int flags= proposal.getFlags();
		boolean isInterfaceOrAnnotation= Flags.isInterface(flags) || Flags.isAnnotation(flags);
		return decorateImageDescriptor(JavaElementImageProvider.getTypeImageDescriptor(true /* in order to get all visibility decorations */, isInterfaceOrAnnotation, flags, false), proposal);
	}

	ImageDescriptor createFieldImageDescriptor(CompletionProposal proposal) {
		final int flags= proposal.getFlags();
		return decorateImageDescriptor(JavaElementImageProvider.getFieldImageDescriptor(false, flags), proposal);
	}

	ImageDescriptor createLocalImageDescriptor(CompletionProposal proposal) {
		return decorateImageDescriptor(JavaPluginImages.DESC_OBJS_LOCAL_VARIABLE, proposal);
	}

	ImageDescriptor createPackageImageDescriptor(CompletionProposal proposal) {
		return decorateImageDescriptor(JavaPluginImages.DESC_OBJS_PACKAGE, proposal);
	}

	/**
	 * Returns a version of <code>descriptor</code> decorated according to
	 * the passed <code>modifier</code> flags.
	 *
	 * @param descriptor the image descriptor to decorate
	 * @param proposal the proposal
	 * @return an image descriptor for a method proposal
	 * @see Flags
	 */
	private ImageDescriptor decorateImageDescriptor(ImageDescriptor descriptor, CompletionProposal proposal) {
		int adornments= 0;
		int flags= proposal.getFlags();
		int kind= proposal.getKind();

		boolean deprecated= Flags.isDeprecated(flags);
		if (!deprecated) {
			CompletionProposal[] requiredProposals= proposal.getRequiredProposals();
			if (requiredProposals != null) {
				for (int i= 0; i < requiredProposals.length; i++) {
					CompletionProposal requiredProposal= requiredProposals[i];
					if (requiredProposal.getKind() == CompletionProposal.TYPE_REF) {
						deprecated |= Flags.isDeprecated(requiredProposal.getFlags());
					}
				}
			}
		}
		if (deprecated)
			adornments |= JavaElementImageDescriptor.DEPRECATED;

		if (kind == CompletionProposal.FIELD_REF || kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_NAME_REFERENCE
				|| kind == CompletionProposal.METHOD_REF || kind == CompletionProposal.CONSTRUCTOR_INVOCATION)
			if (Flags.isStatic(flags))
				adornments |= JavaElementImageDescriptor.STATIC;

		if (kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_NAME_REFERENCE || kind == CompletionProposal.METHOD_REF
				|| kind == CompletionProposal.CONSTRUCTOR_INVOCATION)
			if (Flags.isSynchronized(flags))
				adornments |= JavaElementImageDescriptor.SYNCHRONIZED;

		if (kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_NAME_REFERENCE || kind == CompletionProposal.METHOD_REF) {
			if (Flags.isDefaultMethod(flags))
				adornments|= JavaElementImageDescriptor.DEFAULT_METHOD;
			else if (Flags.isAbstract(flags))
				adornments|= JavaElementImageDescriptor.ABSTRACT;
		}

		if (kind == CompletionProposal.ANNOTATION_ATTRIBUTE_REF)
			if (Flags.isAnnnotationDefault(flags))
				adornments|= JavaElementImageDescriptor.ANNOTATION_DEFAULT;

		if (kind == CompletionProposal.TYPE_REF && Flags.isAbstract(flags) && !Flags.isInterface(flags))
			adornments |= JavaElementImageDescriptor.ABSTRACT;

		if (kind == CompletionProposal.FIELD_REF) {
			if (Flags.isFinal(flags))
				adornments |= JavaElementImageDescriptor.FINAL;
			if (Flags.isTransient(flags))
				adornments |= JavaElementImageDescriptor.TRANSIENT;
			if (Flags.isVolatile(flags))
				adornments |= JavaElementImageDescriptor.VOLATILE;
		}

		return new JavaElementImageDescriptor(descriptor, adornments, JavaElementImageProvider.SMALL_SIZE);
	}

	/**
	 * Sets the completion context.
	 *
	 * @param context the completion context
	 * @since 3.2
	 */
	void setContext(CompletionContext context) {
		fContext= context;
	}

}
