/*******************************************************************************
 * Copyright (c) 2015 GK Software AG.
 * 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:
 *     Stephan Herrmann - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider;
import org.eclipse.jdt.internal.compiler.lookup.SignatureWrapper;
import org.eclipse.jdt.internal.core.ClasspathEntry;

/**
 * Utilities for accessing and manipulating text files that externally define annotations for a given Java type.
 * Files are assumed to be in ".eea format", a textual representation of annotated signatures of members of a given type.
 * 
 * @since 3.11
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
public final class ExternalAnnotationUtil {

	/** Representation of a 'nullable' annotation, independent of the concrete annotation name used in Java sources. */
	public static final char NULLABLE = ExternalAnnotationProvider.NULLABLE;

	/** Representation of a 'nonnull' annotation, independent of the concrete annotation name used in Java sources. */
	public static final char NONNULL = ExternalAnnotationProvider.NONNULL;

	/**
	 * Represents absence of a null annotation. Useful for removing an existing null annotation.
	 * This character is used only internally, it is not part of the Eclipse External Annotation file format.
	 */
	public static final char NO_ANNOTATION = ExternalAnnotationProvider.NO_ANNOTATION;

	/** Strategy for merging a new signature with an existing (possibly annotated) signature. */
	public static enum MergeStrategy {
		/** Unconditionally replace the signature. */
		REPLACE_SIGNATURE,
		/** Override existing annotations, keeping old annotations in locations that are not annotated in the new signature. */
		OVERWRITE_ANNOTATIONS,
		/** Only add new annotations, never remove or overwrite existing annotations. */
		ADD_ANNOTATIONS
	}

	private static final int POSITION_RETURN_TYPE = -1;
	private static final int POSITION_FULL_SIGNATURE = -2;

	/**
	 * Answer the give method's signature in class file format.
	 * @param methodBinding binding representing a method
	 * @return a signature in class file format
	 */
	public static String extractGenericSignature(IMethodBinding methodBinding) {
		// Note that IMethodBinding.binding is not accessible, hence we need to reverse engineer from the key:
		
		// method key contains the signature between '(' and '|': "class.selector(params)return|throws"
		int open= methodBinding.getKey().indexOf('(');
		int throwStart= methodBinding.getKey().indexOf('|');
		return throwStart == -1 ? methodBinding.getKey().substring(open) : methodBinding.getKey().substring(open, throwStart);
	}

	/**
	 * Answer the given types's signature in class file format.
	 * @param type binding representing a type
	 * @return a signature in class file format
	 */
	public static String extractGenericTypeSignature(ITypeBinding type) {
		String key = type.getKey();
		if (type.isTypeVariable()) {
			int colon= key.indexOf(':');
			if (colon > -1)
				return key.substring(colon+1); // cut of unwanted declaring type prefix
		}
		return key;
	}

	/**
	 * Insert an encoded annotation into the given methodSignature affecting its return type.
	 * <p>
	 * This method is suitable for declaration annotations.
	 * </p>
	 * @param methodSignature a method signature in class file format
	 * @param annotation one of {@link #NULLABLE} and {@link #NONNULL}.
	 * @param mergeStrategy when passing {@link MergeStrategy#ADD_ANNOTATIONS} this method will
	 * 	refuse to overwrite any existing annotation in the specified location
	 * @return the modified method signature, or the original signature if modification would
	 *	conflict with the given merge strategy.
	 * @throws IllegalArgumentException if the method signature is malformed or its return type is not a reference type.
	 */
	public static String insertReturnAnnotation(String methodSignature, char annotation, MergeStrategy mergeStrategy) {
		int close = methodSignature.indexOf(')');
		if (close == -1 || close > methodSignature.length()-4)
			throw new IllegalArgumentException("Malformed method signature"); //$NON-NLS-1$
		switch (methodSignature.charAt(close+1)) {
			case 'L': case 'T': case '[':
				return insertAt(methodSignature, close+2, annotation, mergeStrategy);
		}
		throw new IllegalArgumentException("Return type is not a reference type"); //$NON-NLS-1$
	}

	/**
	 * Insert an encoded annotation into the given methodSignature affecting one of its parameters.
	 * <p>
	 * This method is suitable for declaration annotations.
	 * </p>
	 * @param methodSignature a method signature in class file format
	 * @param paramIdx 0-based index of the parameter to which the annotation should be attached
	 * @param annotation one of {@link #NULLABLE} and {@link #NONNULL}.
	 * @param mergeStrategy when passing {@link MergeStrategy#ADD_ANNOTATIONS} this method will
	 * 	refuse to overwrite any existing annotation in the specified location
	 * @return the modified method signature, or the original signature if modification would
	 *	conflict with the given merge strategy.
	 * @throws IllegalArgumentException if the method signature is malformed or its specified parameter type is not a reference type.
	 */
	public static String insertParameterAnnotation(String methodSignature, int paramIdx, char annotation, MergeStrategy mergeStrategy)
	{
		SignatureWrapper wrapper = new SignatureWrapper(methodSignature.toCharArray());
		wrapper.start = 1;
		for (int i = 0; i < paramIdx; i++)
			wrapper.start = wrapper.computeEnd() + 1;
		int start = wrapper.start;
		switch (methodSignature.charAt(start)) {
			case 'L': case 'T': case '[':
				return insertAt(methodSignature, start+1, annotation, mergeStrategy);
		}
		throw new IllegalArgumentException("Paramter type is not a reference type"); //$NON-NLS-1$
	}

	/**
	 * Answer the external annotation file corresponding to the given type as seen from the given project.
	 * Note that manipulation of external annotations is only supported for annotation files in the workspace,
	 * and only in directory layout, not from zip files.
	 * @param project current project that references the given type from a jar file.
	 * @param type the type for which external annotations are sought
	 * @param monitor progress monitor to be passed through into file operations
	 * @return a file assumed (but not checked) to be in .eea format. The file may not "exist".
	 * 	Can be null if the given type is not contained in a jar file for which an external annotation path
	 *  has been defined in the context of the given project.
	 * @throws CoreException Signals a problem in accessing any of the relevant elements: the project, the type,
	 * the containing jar file and finally the sought annotation file.
	 */
	public static IFile getAnnotationFile(IJavaProject project, ITypeBinding type, IProgressMonitor monitor) throws CoreException {
	
		IType targetType = project.findType(type.getErasure().getQualifiedName());
		if (!targetType.exists())
			return null;

		String binaryTypeName = targetType.getFullyQualifiedName('.').replace('.', '/');
		
		IPackageFragmentRoot packageRoot = (IPackageFragmentRoot) targetType.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
		IClasspathEntry entry = packageRoot.getResolvedClasspathEntry();
		IPath annotationPath = ClasspathEntry.getExternalAnnotationPath(entry, project.getProject(), false);
	
		if (annotationPath == null) 
			return null;
		IWorkspaceRoot workspaceRoot = project.getProject().getWorkspace().getRoot();
		IFile annotationZip = workspaceRoot.getFile(annotationPath);
		if (annotationZip.exists())
			return null;
	
		annotationPath = annotationPath.append(binaryTypeName).addFileExtension(ExternalAnnotationProvider.ANNOTION_FILE_EXTENSION);
		return workspaceRoot.getFile(annotationPath);
	}

	/**
	 * Update the given external annotation file with details regarding annotations of one specific method or field.
	 * If the specified member already has external annotations, old and new annotations will be merged,
	 * with priorities controlled by the parameter 'mergeStrategy'.
	 * <p>
	 * This method is suitable for declaration annotations and type use annotations.
	 * </p>
	 * @param typeName binary name (slash separated) of the type being annotated
	 * @param file a file assumed to be in .eea format, will be created if it doesn't exist.
	 * @param selector selector of the method or field
	 * @param originalSignature unannotated signature of the member, used for identification
	 * @param annotatedSignature new signatures whose annotations should be superimposed on the member
	 * @param mergeStrategy controls how old and new signatures should be merged
	 * @param monitor progress monitor to be passed through into file operations, or null if no reporting is desired
	 * @throws CoreException if access to the file fails
	 * @throws IOException if reading file content fails
	 */
	public static void annotateMember(String typeName, IFile file, String selector, String originalSignature, String annotatedSignature,
										MergeStrategy mergeStrategy, IProgressMonitor monitor)
			throws CoreException, IOException
	{
		annotateMember(typeName, file, selector, originalSignature, annotatedSignature, POSITION_FULL_SIGNATURE, mergeStrategy, monitor);
	}

	/**
	 * Update the given external annotation file with details regarding annotations of the return type of a given method.
	 * If the specified method already has external annotations, old and new annotations will be merged,
	 * with priorities controlled by the parameter 'mergeStrategy'.
	 * <p>
	 * This method is suitable for declaration annotations and type use annotations.
	 * </p>
	 * @param typeName binary name (slash separated) of the type being annotated
	 * @param file a file assumed to be in .eea format, will be created if it doesn't exist.
	 * @param selector selector of the method
	 * @param originalSignature unannotated signature of the member, used for identification
	 * @param annotatedReturnType signature of the new return type whose annotations should be superimposed on the method
	 * @param mergeStrategy controls how old and new signatures should be merged
	 * @param monitor progress monitor to be passed through into file operations, or null if no reporting is desired
	 * @throws CoreException if access to the file fails
	 * @throws IOException if reading file content fails
	 * @throws IllegalArgumentException if the annotatedReturnType does not structurally match to originalSignature
	 */
	public static void annotateMethodReturnType(String typeName, IFile file, String selector, String originalSignature,
										String annotatedReturnType, MergeStrategy mergeStrategy, IProgressMonitor monitor)
			throws CoreException, IOException, IllegalArgumentException
	{
		annotateMember(typeName, file, selector, originalSignature, annotatedReturnType, POSITION_RETURN_TYPE, mergeStrategy, monitor);
	}

	/**
	 * Update the given external annotation file with details regarding annotations of a parameter type of a given method.
	 * If the specified method already has external annotations, old and new annotations will be merged,
	 * with priorities controlled by the parameter 'mergeStrategy'.
	 * <p>
	 * This method is suitable for declaration annotations and type use annotations.
	 * </p>
	 * @param typeName binary name (slash separated) of the type being annotated
	 * @param file a file assumed to be in .eea format, will be created if it doesn't exist.
	 * @param selector selector of the method
	 * @param originalSignature unannotated signature of the member, used for identification
	 * @param annotatedParameterType signature of the new parameter type whose annotations should be superimposed on the method
	 * @param paramIdx 0-based index of the parameter to which the annotation should be attached
	 * @param mergeStrategy controls how old and new signatures should be merged
	 * @param monitor progress monitor to be passed through into file operations, or null if no reporting is desired
	 * @throws CoreException if access to the file fails
	 * @throws IOException if reading file content fails
	 * @throws IllegalArgumentException if the annotatedParameterType does not structurally match to originalSignature
	 */
	public static void annotateMethodParameterType(String typeName, IFile file, String selector, String originalSignature,
										String annotatedParameterType, int paramIdx, MergeStrategy mergeStrategy, IProgressMonitor monitor)
			throws CoreException, IOException, IllegalArgumentException
	{
		annotateMember(typeName, file, selector, originalSignature, annotatedParameterType, paramIdx, mergeStrategy, monitor);
	}

	private static void annotateMember(String typeName, IFile file, String selector, String originalSignature, String annotatedSignature,
										int updatePosition, MergeStrategy mergeStrategy, IProgressMonitor monitor)
			throws CoreException, IOException, IllegalArgumentException
	{

		if (!file.exists()) {
			// assemble full annotatedSignature (don't bother merging since no previous signature exists):
			annotatedSignature = updateSignature(originalSignature, annotatedSignature, updatePosition, MergeStrategy.REPLACE_SIGNATURE);

			StringBuffer newContent= new StringBuffer();
			// header:
			newContent.append(ExternalAnnotationProvider.CLASS_PREFIX);
			newContent.append(typeName).append('\n');
			// new entry:
			newContent.append(selector).append('\n');
			newContent.append(' ').append(originalSignature).append('\n');
			newContent.append(' ').append(annotatedSignature).append('\n');

			createNewFile(file, newContent.toString(), monitor);
		} else {
			BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()));
			StringBuffer newContent = new StringBuffer();
			try {
				newContent.append(reader.readLine()).append('\n'); // skip class name
				String line;
				while ((line = reader.readLine()) != null) {
					if (line.isEmpty()) {
						newContent.append('\n');
						continue;
					}
					if (!Character.isJavaIdentifierStart(line.charAt(0))) {
						newContent.append(line).append('\n');
						continue;
					}
					// compare selectors:
					int relation = line.compareTo(selector);
					if (relation > 0) { // past the insertion point
						break;
					}
					if (relation < 0) {
						newContent.append(line).append('\n');
						continue;
					}
					if (relation == 0) {
						StringBuffer pending = new StringBuffer(line).append('\n');
						pending.append(line = reader.readLine());
						if (line == null) {
							break; // found only the selector at EOF, append right here, ignoring 'pending'
						}
						// compare original signatures:
						relation = line.trim().compareTo(originalSignature);
						if (relation > 0) { // past the insertion point
							// add new entry (below)
							line = pending.toString(); // push back
							break;
						}
						newContent.append(pending).append('\n');
						if (relation < 0)
							continue;
						if (relation == 0) {
							// update existing entry:
							String annotationLine = reader.readLine();
							String nextLine = null;
							if (annotationLine == null || annotationLine.isEmpty() || !annotationLine.startsWith(" ")) { //$NON-NLS-1$
								nextLine = annotationLine; // push back, since not a signature line
								annotationLine = line; // no annotated line yet, use unannotated line instead
							}
							if (annotationLine.startsWith(" ")) { //$NON-NLS-1$
								switch (mergeStrategy) {
									case REPLACE_SIGNATURE:
										break; // unconditionally use annotatedSignature
									case OVERWRITE_ANNOTATIONS:
									case ADD_ANNOTATIONS:
										annotatedSignature = updateSignature(annotationLine.trim(), annotatedSignature, updatePosition, mergeStrategy);
										break;
									default:
										JavaCore.getJavaCore().getLog().log(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID,
																				"Unexpected value for enum MergeStrategy")); //$NON-NLS-1$
								}
							}
							writeFile(file, newContent, annotatedSignature, nextLine, reader, monitor);
							return;
						}
					}
				}
				// add new entry:
				newContent.append(selector).append('\n');
				newContent.append(' ').append(originalSignature).append('\n');
				annotatedSignature = updateSignature(originalSignature, annotatedSignature, updatePosition, mergeStrategy);
				writeFile(file, newContent, annotatedSignature, line, reader, monitor);
			} finally {
				reader.close();
			}
		}
	}

	private static String updateSignature(String originalSignature, String annotatedSignature, int updatePosition, MergeStrategy mergeStrategy) {
		StringBuffer buf = new StringBuffer();
		String signatureToReplace;
		String postfix = null;
		switch (updatePosition) {
			case POSITION_FULL_SIGNATURE:
				signatureToReplace = originalSignature;
				break;
			case POSITION_RETURN_TYPE:
				assert originalSignature.charAt(0) == '(' : "signature must start with '('"; //$NON-NLS-1$
				int close = originalSignature.indexOf(')');
				buf.append(originalSignature, 0, close+1);
				signatureToReplace = originalSignature.substring(close+1);
				break;
			default: // parameter
				SignatureWrapper wrapper = new SignatureWrapper(originalSignature.toCharArray(), true, true); // may already contain annotations
				wrapper.start = 1;
				for (int i = 0; i < updatePosition; i++)
					wrapper.start = wrapper.computeEnd() + 1;
				int start = wrapper.start;
				int end = wrapper.computeEnd();
				end = wrapper.skipAngleContents(end);
				buf.append(originalSignature, 0, start);
				signatureToReplace = originalSignature.substring(start, end+1);
				postfix = originalSignature.substring(end+1, originalSignature.length());
		}
		updateType(buf, signatureToReplace.toCharArray(), annotatedSignature.toCharArray(), mergeStrategy);
		if (postfix != null)
			buf.append(postfix);
		return buf.toString();
	}

	/**
	 * Insert that given annotation at the given position into the given signature. 
	 * @param mergeStrategy if set to {@link MergeStrategy#ADD_ANNOTATIONS}, refuse to
	 *   overwrite any existing annotation in the specified location.
	 */
	private static String insertAt(String signature, int position, char annotation, MergeStrategy mergeStrategy) {
		StringBuffer result = new StringBuffer();
		result.append(signature, 0, position);
		result.append(annotation);
		char next = signature.charAt(position);
		switch (next) {
			case NULLABLE: case NONNULL:
				if (mergeStrategy == MergeStrategy.ADD_ANNOTATIONS)
					return signature; // refuse any change
				position++; // skip old annotation
		}
		result.append(signature, position, signature.length());
		return result.toString();
	}

	/**
	 * Update 'oldType' with annotations from 'newType' guided by 'mergeStrategy'.
	 * The result is written into 'buf' as we go.
	 */
	private static boolean updateType(StringBuffer buf, char[] oldType, char[] newType, MergeStrategy mergeStrategy) {
		if (mergeStrategy == MergeStrategy.REPLACE_SIGNATURE) {
			buf.append(newType);
			return false;
		}			
		try {
			SignatureWrapper oWrap = new SignatureWrapper(oldType, true, true); // may already contain annotations
			SignatureWrapper nWrap = new SignatureWrapper(newType, true, true); // may already contain annotations
			if (match(buf, oWrap, nWrap, 'L', false)
				|| match(buf, oWrap, nWrap, 'T', false))
			{
				mergeAnnotation(buf, oWrap, nWrap, mergeStrategy);
				buf.append(oWrap.nextName());
				nWrap.nextName(); // skip
				if (match(buf, oWrap, nWrap, '<', false)) {
					do {
						int oStart = oWrap.start;
						int nStart = nWrap.start;
						oWrap.computeEnd();
						nWrap.computeEnd();
						if (updateType(buf, oWrap.getFrom(oStart), nWrap.getFrom(nStart), mergeStrategy))
							mergeAnnotation(buf, oWrap, nWrap, mergeStrategy);
					} while (!match(buf, oWrap, nWrap, '>', false));
				}
				match(buf, oWrap, nWrap, ';', true);
			} else if (match(buf, oWrap, nWrap, '[', false)) {
				mergeAnnotation(buf, oWrap, nWrap, mergeStrategy);
				updateType(buf, oWrap.tail(), nWrap.tail(), mergeStrategy);
			} else if (match(buf, oWrap, nWrap, '*', false)
					|| match(buf, oWrap, nWrap, '+', false)
					|| match(buf, oWrap, nWrap, '-', false))
			{
				return true; // annotation allowed after this (not included in oldType / newType)
			} else {			
				buf.append(oldType);
			}
		} catch (ArrayIndexOutOfBoundsException aioobe) { // from several locations inside match() or mergeAnnotation().
			StringBuilder msg = new StringBuilder("Structural mismatch between ").append(oldType).append(" and ").append(newType); //$NON-NLS-1$ //$NON-NLS-2$
			throw new IllegalArgumentException(msg.toString(), aioobe);
		}
		return false;
	}
	/**
	 * Does the current char at both given signatures match the 'expected' char?
	 * If yes, print it into 'buf' and answer true.
	 * If no, if 'force' raise an exception, else quietly answer false without updating 'buf'.
	 */
	private static boolean match(StringBuffer buf, SignatureWrapper sig1, SignatureWrapper sig2, char expected, boolean force) {
		boolean match1 = sig1.signature[sig1.start] == expected;
		boolean match2 = sig2.signature[sig2.start] == expected;
		if (match1 != match2) {
			StringBuilder msg = new StringBuilder("Mismatching type structures ") //$NON-NLS-1$
									.append(sig1.signature).append(" vs ").append(sig2.signature); //$NON-NLS-1$
			throw new IllegalArgumentException(msg.toString()); 
		}
		if (match1) {
			buf.append(expected);
			sig1.start++;
			sig2.start++;
			return true;
		} else if (force) {
			throw new IllegalArgumentException("Expected char "+expected+" not found in "+new String(sig1.signature)); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			return false;
		}
	}

	/**
	 * If a current char of 'oldS' and/or 'newS' represents a null annotation, insert it into 'buf' guided by 'mergeStrategy'.
	 * If the new char is NO_ANNOTATION and strategy is OVERWRITE_ANNOTATIONS, silently skip over any null annotations in 'oldS'. 
	 */
	private static void mergeAnnotation(StringBuffer buf, SignatureWrapper oldS, SignatureWrapper newS, MergeStrategy mergeStrategy) {
		 // if atEnd use a char that's different from NULLABLE, NONNULL and NO_ANNOTATION:
		char oldAnn = !oldS.atEnd() ? oldS.signature[oldS.start] : '\0';
		char newAnn = !newS.atEnd() ? newS.signature[newS.start] : '\0';
		switch (mergeStrategy) {
			case ADD_ANNOTATIONS:
				switch (oldAnn) {
					case NULLABLE: case NONNULL:
						oldS.start++;
						buf.append(oldAnn); // old exists, so it remains
						switch (newAnn) { case NULLABLE: case NONNULL: newS.start++; } // just skip
						return;
				}
				//$FALL-THROUGH$
			case OVERWRITE_ANNOTATIONS:
				switch (newAnn) {
					case NULLABLE: case NONNULL:
						newS.start++;
						buf.append(newAnn); // new exists and is not suppressed by "ADD & old exists"
						switch (oldAnn) { case NULLABLE: case NONNULL: oldS.start++; } // just skip
						break;
					case NO_ANNOTATION:
						newS.start++; // don't insert
						switch (oldAnn) { case NULLABLE: case NONNULL: oldS.start++; } // just skip
						break;
					default:
						switch (oldAnn) { 
							case NULLABLE: case NONNULL: 
								oldS.start++;
								buf.append(oldAnn); // keep
						}
				}
		}
	}

	/**
	 * Write back the given annotationFile, with the following content:
	 * - head (assumed to include a member and its original signature
	 * - annotatedSignature
	 * - nextLines (optionally, may be null)
	 * - the still unconsumed content of tailReader
	 */
	private static void writeFile(IFile annotationFile, StringBuffer head, String annotatedSignature,
									String nextLines, BufferedReader tailReader, IProgressMonitor monitor)
			throws CoreException, IOException
	{
		head.append(' ').append(annotatedSignature).append('\n'); 
		if (nextLines != null)
			head.append(nextLines).append('\n');
		String line;
		while ((line = tailReader.readLine()) != null)
			head.append(line).append('\n');
		ByteArrayInputStream newContent = new ByteArrayInputStream(head.toString().getBytes("UTF-8")); //$NON-NLS-1$
		annotationFile.setContents(newContent, IResource.KEEP_HISTORY, monitor);
	}

	private static void createNewFile(IFile file, String newContent, IProgressMonitor monitor) throws CoreException {
		ensureExists(file.getParent(), monitor);
		
		try {
			file.create(new ByteArrayInputStream(newContent.getBytes("UTF-8")), false, monitor); //$NON-NLS-1$
		} catch (UnsupportedEncodingException e) {
			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, e.getMessage(), e));
		}
	}

	private static void ensureExists(IContainer container, IProgressMonitor monitor) throws CoreException {
		if (container.exists()) return;
		if (!(container instanceof IFolder)) throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, "not a folder: "+container)); //$NON-NLS-1$
		IContainer parent= container.getParent();
		if (parent instanceof IFolder) {
			ensureExists(parent, monitor);
		}
		((IFolder) container).create(false, true, monitor);
	}

	/**
	 * Retrieve the annotated signature of a specified member as found in the given external annotation file, if any.
	 * @param typeName fully qualified slash-separated name of the type for which the file defines external annotations
	 * @param file a file assumed to be in .eea format, must not be null, but may not exist
	 * @param selector name of the member whose annotation we are looking for
	 * @param originalSignature the unannotated signature by which the member is identified
	 * @return the annotated signature as found in the file, or null.
	 */
	public static String getAnnotatedSignature(String typeName, IFile file, String selector, String originalSignature) {
		if (file.exists()) {
			try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()))) {
				ExternalAnnotationProvider.assertClassHeader(reader.readLine(), typeName);
				while (true) {
					String line = reader.readLine();
					// selector:
					if (selector.equals(line)) {
						// original signature:
						line = reader.readLine();
						if (originalSignature.equals(ExternalAnnotationProvider.extractSignature(line))) {
							// annotated signature:
							return ExternalAnnotationProvider.extractSignature(reader.readLine());
						}
					}
					if (line == null)
						break;
				}
			} catch (IOException | CoreException e) {
				return null;
			}
		}
		return null;
	}

	/**
	 * Apply the specified changes on the given type.
	 * This method can be used as a dry run without modifying an annotation file.
	 * 
	 * @param originalSignature the original type signature, may be annotated already
	 * @param annotatedType a type signature with additional annotations (incl. {@link #NO_ANNOTATION}).
	 * @param mergeStrategy controls how old and new signatures should be merged
	 * @return an array of length four: <ul>
	 * <li>prefix up-to the changed type</li>
	 * <li>original type</li>
	 * <li>changed type</li>
	 * <li>postfix after the changed type <em>(here: empty string)</li>
	 * </ul>
	 */
	public static String[] annotateType(String originalSignature, String annotatedType, MergeStrategy mergeStrategy)
	{
		String[] result = new String[4]; // prefix, orig, replacement, postfix
		StringBuffer buf;
		result[0] = ""; //$NON-NLS-1$
		buf = new StringBuffer();
		result[1] = originalSignature;
		updateType(buf, originalSignature.toCharArray(), annotatedType.toCharArray(), mergeStrategy);
		result[2] = buf.toString();
		result[3] = ""; //$NON-NLS-1$
		return result;
	}

	/**
	 * Apply the specified changes on the return type of the given signature.
	 * This method can be used as a dry run without modifying an annotation file.
	 * 
	 * @param originalSignature the original full signature, may be annotated already
	 * @param annotatedType a type signature with additional annotations (incl. {@link #NO_ANNOTATION}).
	 * @param mergeStrategy controls how old and new signatures should be merged
	 * @return an array of length four: <ul>
	 * <li>prefix up-to the changed type</li>
	 * <li>original type</li>
	 * <li>changed type</li>
	 * <li>postfix after the changed type <em>(here: empty string)</li>
	 * </ul>
	 */
	public static String[] annotateReturnType(String originalSignature, String annotatedType, MergeStrategy mergeStrategy)
	{
		String[] result = new String[4]; // prefix, orig, replacement, postfix
		StringBuffer buf;
		assert originalSignature.charAt(0) == '(' : "signature must start with '('"; //$NON-NLS-1$
		int close = originalSignature.indexOf(')');
		result[0] = originalSignature.substring(0, close+1);
		buf = new StringBuffer();
		result[1] = originalSignature.substring(close+1);
		updateType(buf, result[1].toCharArray(), annotatedType.toCharArray(), mergeStrategy);
		result[2] = buf.toString();
		result[3] = ""; //$NON-NLS-1$
		return result;
	}
	

	/**
	 * Apply the specified changes on a parameter within the given signature.
	 * This method can be used as a dry run without modifying an annotation file.
	 * 
	 * @param originalSignature the original full signature, may be annotated already
	 * @param annotatedType a type signature with additional annotations (incl. {@link #NO_ANNOTATION}).
	 * @param paramIdx the index of a parameter to annotated
	 * @param mergeStrategy controls how old and new signatures should be merged
	 * @return an array of length four: <ul>
	 * <li>prefix up-to the changed type</li>
	 * <li>original type</li>
	 * <li>changed type</li>
	 * <li>postfix after the changed type</li>
	 * </ul>
	 */
	public static String[] annotateParameterType(String originalSignature, String annotatedType, int paramIdx, MergeStrategy mergeStrategy)
	{
		String[] result = new String[4]; // prefix, orig, replacement, postfix
		StringBuffer buf;
		SignatureWrapper wrapper = new SignatureWrapper(originalSignature.toCharArray(), true, true); // may already contain annotations
		wrapper.start = 1;
		for (int i = 0; i < paramIdx; i++)
			wrapper.start = wrapper.computeEnd() + 1;
		int start = wrapper.start;
		int end = wrapper.computeEnd();
		end = wrapper.skipAngleContents(end);
		result[0] = originalSignature.substring(0, start);				
		buf = new StringBuffer();
		result[1] = originalSignature.substring(start, end+1);
		updateType(buf, result[1].toCharArray(), annotatedType.toCharArray(), mergeStrategy);
		result[2] = buf.toString();
		result[3] = originalSignature.substring(end+1, originalSignature.length());
		return result;
	}
}
