[295510] [content assist] Content assist can duplicate imports
[238101] [content assist] Page directive imports added by content assist mishandle inner class names
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/AutoImportProposal.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/AutoImportProposal.java
index 980b4a0..3740281 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/AutoImportProposal.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/AutoImportProposal.java
@@ -13,6 +13,7 @@
 
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jdt.core.IImportContainer;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.ITextViewer;
@@ -38,22 +39,29 @@
 	
 	// the import string, no quotes or colons
 	String fImportDeclaration;
-	
+	IImportContainer fImportContainer;
+
 	public AutoImportProposal(String importDeclaration, String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int relevance, boolean updateReplacementLengthOnValidate) {
 		super(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, contextInformation, additionalProposalInfo, relevance, updateReplacementLengthOnValidate);
 		setImportDeclaration(importDeclaration);
 	}
-	
+
+	public AutoImportProposal(String importDeclaration, IImportContainer importContainer ,String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int relevance, boolean updateReplacementLengthOnValidate) {
+		this(importDeclaration, replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, contextInformation, additionalProposalInfo, relevance, updateReplacementLengthOnValidate);
+		fImportContainer = importContainer;
+	}
+
 	public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
 		super.apply(viewer, trigger, stateMask, offset);
-		addImportDeclaration(viewer);
+		// if the import doesn't exist, add it
+		if (fImportContainer == null || !fImportContainer.getImport(getImportDeclaration()).exists())
+			addImportDeclaration(viewer);
 	}
 	/**
 	 * adds the import declaration to the document in the viewer in the appropriate position
 	 * @param viewer
 	 */
 	private void addImportDeclaration(ITextViewer viewer) {
-		
 		IDocument doc = viewer.getDocument();
 		
 		// calculate once and pass along
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPProposalCollector.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPProposalCollector.java
index 4c8b328..321e274 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPProposalCollector.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPProposalCollector.java
@@ -17,6 +17,7 @@
 
 import org.eclipse.jdt.core.CompletionProposal;
 import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportContainer;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.internal.ui.text.java.ProposalContextInformation;
 import org.eclipse.jdt.ui.text.java.CompletionProposalCollector;
@@ -40,7 +41,8 @@
 
 	private JSPTranslation fTranslation;
 	private Comparator fComparator;
-	
+	private IImportContainer fImportContainer;
+
 	public JSPProposalCollector(ICompilationUnit cu, JSPTranslation translation) {
 		super(cu);
 	
@@ -48,6 +50,7 @@
 			throw new IllegalArgumentException("JSPTranslation cannot be null"); //$NON-NLS-1$
 		
 		fTranslation = translation;
+		fImportContainer = cu.getImportContainer();
 	}
 
 	/**
@@ -102,19 +105,26 @@
 		return jspProposal;
 	}
 
-	
-	
+	/**
+	 * Retrieves the type name from the string <code>fullName</code>
+	 * @param fullName the fully qualified Java name
+	 * @return the type name
+	 */
+	private String getTypeName(String fullName) {
+		int index = fullName.lastIndexOf('.');
+		return (index != -1) ? fullName.substring(index + 1) : fullName;
+	}
+
 	private JSPCompletionProposal createAutoImportProposal(CompletionProposal proposal) {
 		
 		JSPCompletionProposal jspProposal = null;
 
-		String signature = new String(proposal.getDeclarationSignature());
 		String completion = new String(proposal.getCompletion());
 		
 		// it's fully qualified so we should
 		// add an import statement
 		// create an autoimport proposal
-		String newCompletion = completion.replaceAll(signature + "\\.", ""); //$NON-NLS-1$ //$NON-NLS-2$
+		String newCompletion = getTypeName(completion);
 		
 		// java offset
 		int offset = proposal.getReplaceStart();
@@ -138,7 +148,7 @@
 		
 		boolean updateLengthOnValidate = true;
 		
-		jspProposal = new AutoImportProposal(completion, newCompletion, offset, length, positionAfter, image, displayString, contextInformation, null, relevance, updateLengthOnValidate);
+		jspProposal = new AutoImportProposal(completion, fImportContainer, newCompletion, offset, length, positionAfter, image, displayString, contextInformation, null, relevance, updateLengthOnValidate);
 		
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=124483
 		// set wrapped java proposal so additional info can be calculated on demand