[110355] context info no longer bolds existing attributes
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JavaParameterListValidator.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JavaParameterListValidator.java
index 3eb1f56..633a4c2 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JavaParameterListValidator.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JavaParameterListValidator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -27,190 +27,202 @@
  * @plannedfor 1.0
  */
 public class JavaParameterListValidator implements IContextInformationValidator, IContextInformationPresenter {
-    
-    private int fPosition;
-    private ITextViewer fViewer;
-    private IContextInformation fInformation;
-    
-    private int fCurrentParameter;
-    
-    /**
-     * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
-     * @see IContextInformationPresenter#install(IContextInformation, ITextViewer, int)
-     */
-    public void install(IContextInformation info, ITextViewer viewer, int documentPosition) {
-        fPosition= documentPosition;
-        fViewer= viewer;
-        fInformation= info;
-        
-        fCurrentParameter= -1;
-    }
-    
-    private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
-        while (pos < end) {
-            char curr= d.getChar(pos);
-            pos++;
-            if (curr == '*') {
-                if (pos < end && d.getChar(pos) == '/') {
-                    return pos + 1;
-                }
-            }
-        }
-        return end;
-    }
 
-    private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
-        while (pos < end) {
-            char curr= d.getChar(pos);
-            pos++;
-            if (curr == '\\') {
-                // ignore escaped characters
-                pos++;
-            } else if (curr == ch) {
-                return pos;
-            }
-        }
-        return end;
-    }
-    
-    private int getCharCount(IDocument document, int start, int end, char increment, char decrement, boolean considerNesting) throws BadLocationException {
-        
-        Assert.isTrue((increment != 0 || decrement != 0) && increment != decrement);
-        
-        int nestingLevel= 0;
-        int charCount= 0;
-        while (start < end) {
-            char curr= document.getChar(start++);
-            switch (curr) {
-                case '/':
-                    if (start < end) {
-                        char next= document.getChar(start);
-                        if (next == '*') {
-                            // a comment starts, advance to the comment end
-                            start= getCommentEnd(document, start + 1, end);
-                        } else if (next == '/') {
-                            // '//'-comment: nothing to do anymore on this line 
-                            start= end;
-                        }
-                    }
-                    break;
-                case '*':
-                    if (start < end) {
-                        char next= document.getChar(start);
-                        if (next == '/') {
-                            // we have been in a comment: forget what we read before
-                            charCount= 0;
-                            ++ start;
-                        }
-                    }
-                    break;
-                case '"':
-                case '\'':
-                    start= getStringEnd(document, start, end, curr);
-                    break;
-                default:
-                    
-                    if (considerNesting) {
-                        
-                        if ('(' == curr)
-                            ++ nestingLevel;
-                        else if (')' == curr)
-                            -- nestingLevel;
-                            
-                        if (nestingLevel != 0)
-                            break;
-                    }
-                    
-                    if (increment != 0) {
-                        if (curr == increment)
-                            ++ charCount;
-                    }
-                    
-                    if (decrement != 0) {
-                        if (curr == decrement)
-                            -- charCount;
-                    }
-            }
-        }
-        
-        return charCount;
-    }
-    
-    /**
-     * @see IContextInformationValidator#isContextInformationValid(int)
-     */
-    public boolean isContextInformationValid(int position) {        
-        
-        try {
-            if (position < fPosition)
-                return false;
-                
-            IDocument document= fViewer.getDocument();
-            IRegion line= document.getLineInformationOfOffset(fPosition);
-            
-            if (position < line.getOffset() || position >= document.getLength())
-                return false;
-                
-            return (getCharCount(document, fPosition, position, '(', ')', false) >= 0);
-            
-        } catch (BadLocationException x) {
-            return false;
-        }
-    }
-    
-    /**
-     * @see IContextInformationPresenter#updatePresentation(int, TextPresentation)
-     */
-    public boolean updatePresentation(int position, TextPresentation presentation) {
-        
-        int currentParameter= -1;
-        
-        try {
-            currentParameter= getCharCount(fViewer.getDocument(), fPosition, position, ',', (char) 0, true);
-        } catch (BadLocationException x) {
-            return false;
-        }
-        
-        if (fCurrentParameter != -1) {
-            if (currentParameter == fCurrentParameter)
-                return false;
-        }
-        
-        presentation.clear();
-        fCurrentParameter= currentParameter;
-        
-        String s= fInformation.getInformationDisplayString();
-        int start= 0;
-        int occurrences= 0;
-        while (occurrences < fCurrentParameter) {
-            int found= s.indexOf(',', start);
-            if (found == -1)
-                break;
-            start= found + 1;
-            ++ occurrences;
-        }
-        
-        if (occurrences < fCurrentParameter) {
-            presentation.addStyleRange(new StyleRange(0, s.length(), null, null, SWT.NORMAL));
-            return true;
-        }
-        
-        if (start == -1)
-            start= 0;
-        
-        int end= s.indexOf(',', start);
-        if (end == -1)
-            end= s.length();
-            
-        if (start > 0)  
-            presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL));
-        
-        if (end > start)
-            presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD));
-        
-        if (end < s.length())
-            presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL));
-            
-        return true;
-    }
+	private int fPosition;
+	private ITextViewer fViewer;
+	private IContextInformation fInformation;
+
+	private int fCurrentParameter;
+
+	/**
+	 * @see IContextInformationValidator#install(IContextInformation,
+	 *      ITextViewer, int)
+	 * @see IContextInformationPresenter#install(IContextInformation,
+	 *      ITextViewer, int)
+	 */
+	public void install(IContextInformation info, ITextViewer viewer, int documentPosition) {
+		fPosition = documentPosition;
+		fViewer = viewer;
+		fInformation = info;
+
+		fCurrentParameter = -1;
+	}
+
+	private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
+		while (pos < end) {
+			char curr = d.getChar(pos);
+			pos++;
+			if (curr == '*') {
+				if (pos < end && d.getChar(pos) == '/') {
+					return pos + 1;
+				}
+			}
+		}
+		return end;
+	}
+
+	private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
+		while (pos < end) {
+			char curr = d.getChar(pos);
+			pos++;
+			if (curr == '\\') {
+				// ignore escaped characters
+				pos++;
+			}
+			else if (curr == ch) {
+				return pos;
+			}
+		}
+		return end;
+	}
+
+	private int getCharCount(IDocument document, int start, int end, char increment, char decrement, boolean considerNesting) throws BadLocationException {
+
+		Assert.isTrue((increment != 0 || decrement != 0) && increment != decrement);
+
+		int nestingLevel = 0;
+		int charCount = 0;
+		while (start < end) {
+			char curr = document.getChar(start++);
+			switch (curr) {
+				case '/' :
+					if (start < end) {
+						char next = document.getChar(start);
+						if (next == '*') {
+							// a comment starts, advance to the comment end
+							start = getCommentEnd(document, start + 1, end);
+						}
+						else if (next == '/') {
+							// '//'-comment: nothing to do anymore on this
+							// line
+							start = end;
+						}
+					}
+					break;
+				case '*' :
+					if (start < end) {
+						char next = document.getChar(start);
+						if (next == '/') {
+							// we have been in a comment: forget what we read
+							// before
+							charCount = 0;
+							++start;
+						}
+					}
+					break;
+				case '"' :
+				case '\'' :
+					start = getStringEnd(document, start, end, curr);
+					break;
+				default :
+
+					if (considerNesting) {
+
+						if ('(' == curr)
+							++nestingLevel;
+						else if (')' == curr)
+							--nestingLevel;
+
+						if (nestingLevel != 0)
+							break;
+					}
+
+					if (increment != 0) {
+						if (curr == increment)
+							++charCount;
+					}
+
+					if (decrement != 0) {
+						if (curr == decrement)
+							--charCount;
+					}
+			}
+		}
+
+		return charCount;
+	}
+
+	/**
+	 * @see IContextInformationValidator#isContextInformationValid(int)
+	 */
+	public boolean isContextInformationValid(int position) {
+
+		try {
+			if (position < fPosition)
+				return false;
+
+			IDocument document = fViewer.getDocument();
+			IRegion line = document.getLineInformationOfOffset(fPosition);
+
+			if (position < line.getOffset() || position >= document.getLength())
+				return false;
+
+			return (getCharCount(document, fPosition, position, '(', ')', false) >= 0);
+
+		}
+		catch (BadLocationException x) {
+			return false;
+		}
+	}
+
+	/**
+	 * @see IContextInformationPresenter#updatePresentation(int,
+	 *      TextPresentation)
+	 */
+	public boolean updatePresentation(int position, TextPresentation presentation) {
+
+		int currentParameter = -1;
+
+		try {
+			currentParameter = getCharCount(fViewer.getDocument(), fPosition, position, ',', (char) 0, true);
+		}
+		catch (BadLocationException x) {
+			return false;
+		}
+
+		if (fCurrentParameter != -1) {
+			if (currentParameter == fCurrentParameter)
+				return false;
+		}
+
+		if (fInformation == null)
+			return false;
+
+		presentation.clear();
+		fCurrentParameter = currentParameter;
+
+		String s = fInformation.getInformationDisplayString();
+		int start = 0;
+		int occurrences = 0;
+		while (occurrences < fCurrentParameter) {
+			int found = s.indexOf(',', start);
+			if (found == -1)
+				break;
+			start = found + 1;
+			++occurrences;
+		}
+
+		if (occurrences < fCurrentParameter) {
+			presentation.addStyleRange(new StyleRange(0, s.length(), null, null, SWT.NORMAL));
+			return true;
+		}
+
+		if (start == -1)
+			start = 0;
+
+		int end = s.indexOf(',', start);
+		if (end == -1)
+			end = s.length();
+
+		if (start > 0)
+			presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL));
+
+		if (end > start)
+			presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD));
+
+		if (end < s.length())
+			presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL));
+
+		return true;
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CustomCompletionProposal.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CustomCompletionProposal.java
index 013799b..67c2f9b 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CustomCompletionProposal.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CustomCompletionProposal.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -31,303 +31,311 @@
  * creation.
  */
 public class CustomCompletionProposal implements ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, IRelevanceCompletionProposal {
-    
+
 	private String fAdditionalProposalInfo;
 
-    private IContextInformation fContextInformation;
+	private IContextInformation fContextInformation;
 
-    private int fCursorPosition = 0;
+	private int fCursorPosition = 0;
 
-    private String fDisplayString;
+	private String fDisplayString;
 
-    private Image fImage;
+	private Image fImage;
 
-    private int fOriginalReplacementLength;
+	private int fOriginalReplacementLength;
 
-    private int fRelevance = IRelevanceConstants.R_NONE;
+	private int fRelevance = IRelevanceConstants.R_NONE;
 
-    private int fReplacementLength = 0;
+	private int fReplacementLength = 0;
 
-    private int fReplacementOffset = 0;
+	private int fReplacementOffset = 0;
 
-    private String fReplacementString = null;
+	private String fReplacementString = null;
 
-    private boolean fUpdateLengthOnValidate;
+	private boolean fUpdateLengthOnValidate;
 
-    private char[] fTriggers;
+	private char[] fTriggers;
 
-    /**
-     * Constructor with relevance and replacement length update flag.
-     * 
-     * If the <code>updateReplacementLengthOnValidate</code> flag is true,
-     * then when the user types, the replacement length will be incremented by
-     * the number of new characters inserted from the original position.
-     * Otherwise the replacement length will not change on validate.
-     * 
-     * ex.
-     * 
-     * <tag |name="attr"> - the replacement length is 4 <tag i|name="attr"> -
-     * the replacement length is now 5 <tag id|name="attr"> - the replacement
-     * length is now 6 <tag |name="attr"> - the replacementlength is now 4 again
-     * <tag |name="attr"> - the replacment length remains 4
-     * 
-     */
-    public CustomCompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString,
-            IContextInformation contextInformation, String additionalProposalInfo, int relevance, boolean updateReplacementLengthOnValidate) {
-        fReplacementString = replacementString;
-        fReplacementOffset = replacementOffset;
-        fReplacementLength = replacementLength;
-        fCursorPosition = cursorPosition;
-        fImage = image;
-        fDisplayString = displayString;
-        fContextInformation = contextInformation;
-        fAdditionalProposalInfo = additionalProposalInfo;
-        fRelevance = relevance;
-        fUpdateLengthOnValidate = updateReplacementLengthOnValidate;
-        fOriginalReplacementLength = fReplacementLength;
-    }
+	/**
+	 * Constructor with relevance and replacement length update flag.
+	 * 
+	 * If the <code>updateReplacementLengthOnValidate</code> flag is true,
+	 * then when the user types, the replacement length will be incremented by
+	 * the number of new characters inserted from the original position.
+	 * Otherwise the replacement length will not change on validate.
+	 * 
+	 * ex.
+	 * 
+	 * <tag |name="attr"> - the replacement length is 4 <tag i|name="attr"> -
+	 * the replacement length is now 5 <tag id|name="attr"> - the replacement
+	 * length is now 6 <tag |name="attr"> - the replacementlength is now 4
+	 * again <tag |name="attr"> - the replacment length remains 4
+	 * 
+	 */
+	public CustomCompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int relevance, boolean updateReplacementLengthOnValidate) {
+		fReplacementString = replacementString;
+		fReplacementOffset = replacementOffset;
+		fReplacementLength = replacementLength;
+		fCursorPosition = cursorPosition;
+		fImage = image;
+		fDisplayString = displayString;
+		fContextInformation = contextInformation;
+		fAdditionalProposalInfo = additionalProposalInfo;
+		fRelevance = relevance;
+		fUpdateLengthOnValidate = updateReplacementLengthOnValidate;
+		fOriginalReplacementLength = fReplacementLength;
+	}
 
-    public CustomCompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString,
-            IContextInformation contextInformation, String additionalProposalInfo, int relevance) {
-        this(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, contextInformation, additionalProposalInfo, relevance, true);
-    }
+	public CustomCompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int relevance) {
+		this(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, contextInformation, additionalProposalInfo, relevance, true);
+	}
 
-    public void apply(IDocument document) {
-        CompletionProposal proposal = new CompletionProposal(getReplacementString(), getReplacementOffset(), getReplacementLength(), getCursorPosition(), getImage(), getDisplayString(),
-                getContextInformation(), getAdditionalProposalInfo());
-        proposal.apply(document);
-    }
+	public void apply(IDocument document) {
+		CompletionProposal proposal = new CompletionProposal(getReplacementString(), getReplacementOffset(), getReplacementLength(), getCursorPosition(), getImage(), getDisplayString(), getContextInformation(), getAdditionalProposalInfo());
+		proposal.apply(document);
+	}
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#apply(org.eclipse.jface.text.IDocument,
-     *      char, int)
-     */
-    public void apply(IDocument document, char trigger, int offset) {
-        CompletionProposal proposal = new CompletionProposal(getReplacementString(), getReplacementOffset(), getReplacementLength(), getCursorPosition(), getImage(), getDisplayString(),
-                getContextInformation(), getAdditionalProposalInfo());
-        // we currently don't do anything special for which character
-        // selected the proposal, and where the cursor offset is
-        // but we might in the future...
-        proposal.apply(document);
-        // we want to ContextInformationPresenter.updatePresentation() here
-    }
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#apply(org.eclipse.jface.text.IDocument,
+	 *      char, int)
+	 */
+	public void apply(IDocument document, char trigger, int offset) {
+		CompletionProposal proposal = new CompletionProposal(getReplacementString(), getReplacementOffset(), getReplacementLength(), getCursorPosition(), getImage(), getDisplayString(), getContextInformation(), getAdditionalProposalInfo());
+		// we currently don't do anything special for which character
+		// selected the proposal, and where the cursor offset is
+		// but we might in the future...
+		proposal.apply(document);
+		// we want to ContextInformationPresenter.updatePresentation() here
+	}
 
-    public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
-        IDocument document = viewer.getDocument();
-        // CMVC 252634 to compensate for "invisible" initial region
-        int caretOffset = viewer.getTextWidget().getCaretOffset();
-        if (viewer instanceof ITextViewerExtension5) {
-            ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
-            caretOffset = extension.widgetOffset2ModelOffset(caretOffset);
-        } else {
-            caretOffset = viewer.getTextWidget().getCaretOffset() + viewer.getVisibleRegion().getOffset();
-        }
+	public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
+		IDocument document = viewer.getDocument();
+		// CMVC 252634 to compensate for "invisible" initial region
+		int caretOffset = viewer.getTextWidget().getCaretOffset();
+		if (viewer instanceof ITextViewerExtension5) {
+			ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+			caretOffset = extension.widgetOffset2ModelOffset(caretOffset);
+		}
+		else {
+			caretOffset = viewer.getTextWidget().getCaretOffset() + viewer.getVisibleRegion().getOffset();
+		}
 
-        if (caretOffset == getReplacementOffset()) {
-            apply(document);
-        } else {
-            // replace the text without affecting the caret Position as this
-            // causes the cursor to move on its own
-            try {
-                int endOffsetOfChanges = getReplacementString().length() + getReplacementOffset();
-                // Insert the portion of the new text that comes after the
-                // current caret position
-                if (endOffsetOfChanges >= caretOffset) {
-                    int postCaretReplacementLength = getReplacementOffset() + getReplacementLength() - caretOffset;
-                    int preCaretReplacementLength = getReplacementString().length() - (endOffsetOfChanges - caretOffset);
-                    if (postCaretReplacementLength < 0) {
-                        if (Debug.displayWarnings) {
-                            System.out.println("** postCaretReplacementLength was negative: " + postCaretReplacementLength); //$NON-NLS-1$
-                        }
-                        // This is just a quick fix while I figure out what
-                        // replacement length is supposed to be
-                        // in each case, otherwise we'll get negative
-                        // replacment length sometimes
-                        postCaretReplacementLength = 0;
-                    }
-                    document.replace(caretOffset, postCaretReplacementLength, getReplacementString().substring(preCaretReplacementLength));
-                }
-                // Insert the portion of the new text that comes before the
-                // current caret position
-                // Done second since offsets would change for the post text
-                // otherwise
-                // Outright insertions are handled here
-                if (caretOffset > getReplacementOffset()) {
-                    int preCaretTextLength = caretOffset - getReplacementOffset();
-                    document.replace(getReplacementOffset(), preCaretTextLength, getReplacementString().substring(0, preCaretTextLength));
-                }
-            } catch (BadLocationException x) {
-                apply(document);
-            } catch (StringIndexOutOfBoundsException e) {
-                apply(document);
-            }
-        }
-    }
+		if (caretOffset == getReplacementOffset()) {
+			apply(document);
+		}
+		else {
+			// replace the text without affecting the caret Position as this
+			// causes the cursor to move on its own
+			try {
+				int endOffsetOfChanges = getReplacementString().length() + getReplacementOffset();
+				// Insert the portion of the new text that comes after the
+				// current caret position
+				if (endOffsetOfChanges >= caretOffset) {
+					int postCaretReplacementLength = getReplacementOffset() + getReplacementLength() - caretOffset;
+					int preCaretReplacementLength = getReplacementString().length() - (endOffsetOfChanges - caretOffset);
+					if (postCaretReplacementLength < 0) {
+						if (Debug.displayWarnings) {
+							System.out.println("** postCaretReplacementLength was negative: " + postCaretReplacementLength); //$NON-NLS-1$
+						}
+						// This is just a quick fix while I figure out what
+						// replacement length is supposed to be
+						// in each case, otherwise we'll get negative
+						// replacment length sometimes
+						postCaretReplacementLength = 0;
+					}
+					document.replace(caretOffset, postCaretReplacementLength, getReplacementString().substring(preCaretReplacementLength));
+				}
+				// Insert the portion of the new text that comes before the
+				// current caret position
+				// Done second since offsets would change for the post text
+				// otherwise
+				// Outright insertions are handled here
+				if (caretOffset > getReplacementOffset()) {
+					int preCaretTextLength = caretOffset - getReplacementOffset();
+					document.replace(getReplacementOffset(), preCaretTextLength, getReplacementString().substring(0, preCaretTextLength));
+				}
+			}
+			catch (BadLocationException x) {
+				apply(document);
+			}
+			catch (StringIndexOutOfBoundsException e) {
+				apply(document);
+			}
+		}
+	}
 
-    public String getAdditionalProposalInfo() {
-        // return fProposal.getAdditionalProposalInfo();
-        return fAdditionalProposalInfo;
-    }
+	public String getAdditionalProposalInfo() {
+		// return fProposal.getAdditionalProposalInfo();
+		return fAdditionalProposalInfo;
+	}
 
-    public IContextInformation getContextInformation() {
-        // return fProposal.getContextInformation();
-        return fContextInformation;
-    }
+	public IContextInformation getContextInformation() {
+		// return fProposal.getContextInformation();
+		return fContextInformation;
+	}
 
-    public void setContextInformation(IContextInformation contextInfo) {
-        fContextInformation = contextInfo;
-    }
+	public void setContextInformation(IContextInformation contextInfo) {
+		fContextInformation = contextInfo;
+	}
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition()
-     */
-    public int getContextInformationPosition() {
-        return getCursorPosition();
-    }
-    
-    public int getCursorPosition() {
-        return fCursorPosition;
-    }
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition()
+	 */
+	public int getContextInformationPosition() {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=110355
+		// return getCursorPosition();
+		if (getContextInformation() == null)
+			return getReplacementOffset() - 1;
+		return getReplacementOffset() + getCursorPosition();
+	}
 
-    public void setCursorPosition(int pos) {
-        fCursorPosition = pos;
-    }
+	public int getCursorPosition() {
+		return fCursorPosition;
+	}
 
-    public void setDisplayString(String newDisplayString) {
-    	fDisplayString = newDisplayString;
-    }
-    
-    public String getDisplayString() {
-        // return fProposal.getDisplayString();
-        return fDisplayString;
-    }
+	public void setCursorPosition(int pos) {
+		fCursorPosition = pos;
+	}
 
-    public Image getImage() {
-        // return fProposal.getImage();
-        return fImage;
-    }
+	public void setDisplayString(String newDisplayString) {
+		fDisplayString = newDisplayString;
+	}
 
-    public int getRelevance() {
-        return fRelevance;
-    }
+	public String getDisplayString() {
+		// return fProposal.getDisplayString();
+		return fDisplayString;
+	}
 
-    public void setReplacementLength(int newReplacementLength) {
-        fReplacementLength = newReplacementLength;
-    }  
-    public int getReplacementLength() {
-        return fReplacementLength;
-    }
+	public Image getImage() {
+		// return fProposal.getImage();
+		return fImage;
+	}
 
-    public int getReplacementOffset() {
-        return fReplacementOffset;
-    }
+	public int getRelevance() {
+		return fRelevance;
+	}
 
-    public String getReplacementString() {
-        return fReplacementString;
-    }
+	public void setReplacementLength(int newReplacementLength) {
+		fReplacementLength = newReplacementLength;
+	}
 
-    public Point getSelection(IDocument document) {
-        // return fProposal.getSelection(document);
-        CompletionProposal proposal = new CompletionProposal(getReplacementString(), getReplacementOffset(), getReplacementLength(), getCursorPosition(), getImage(), getDisplayString(),
-                getContextInformation(), getAdditionalProposalInfo());
-        return proposal.getSelection(document);
-    }
+	public int getReplacementLength() {
+		return fReplacementLength;
+	}
 
-    /**
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters()
-     */
+	public int getReplacementOffset() {
+		return fReplacementOffset;
+	}
 
-    public char[] getTriggerCharacters() {
-        return fTriggers;
-    }
+	public String getReplacementString() {
+		return fReplacementString;
+	}
 
-    public void setTriggerCharacters(char[] triggers) {
-        fTriggers = triggers;
-    }
+	public Point getSelection(IDocument document) {
+		// return fProposal.getSelection(document);
+		CompletionProposal proposal = new CompletionProposal(getReplacementString(), getReplacementOffset(), getReplacementLength(), getCursorPosition(), getImage(), getDisplayString(), getContextInformation(), getAdditionalProposalInfo());
+		return proposal.getSelection(document);
+	}
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#isValidFor(org.eclipse.jface.text.IDocument,
-     *      int)
-     */
-    public boolean isValidFor(IDocument document, int offset) {
-        return validate(document, offset, null);
-    }
+	/**
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters()
+	 */
 
-    /**
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer,
-     *      boolean)
-     */
-    public void selected(ITextViewer viewer, boolean smartToggle) {
-    }
+	public char[] getTriggerCharacters() {
+		return fTriggers;
+	}
 
-    // code is borrowed from JavaCompletionProposal
-    protected boolean startsWith(IDocument document, int offset, String word) {
-	
-    	int wordLength = word == null ? 0 : word.length();
-        if (offset > fReplacementOffset + wordLength)
-            return false;
+	public void setTriggerCharacters(char[] triggers) {
+		fTriggers = triggers;
+	}
 
-        try {
-            int length = offset - fReplacementOffset;
-            String start = document.get(fReplacementOffset, length);
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#isValidFor(org.eclipse.jface.text.IDocument,
+	 *      int)
+	 */
+	public boolean isValidFor(IDocument document, int offset) {
+		return validate(document, offset, null);
+	}
 
-            return word.substring(0, length).equalsIgnoreCase(start);
-        } catch (BadLocationException x) {
-        }
+	/**
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer,
+	 *      boolean)
+	 */
+	public void selected(ITextViewer viewer, boolean smartToggle) {
+	}
 
-        return false;
-    }
+	// code is borrowed from JavaCompletionProposal
+	protected boolean startsWith(IDocument document, int offset, String word) {
 
-    /**
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
-     */
-    public void unselected(ITextViewer viewer) {
-    }
+		int wordLength = word == null ? 0 : word.length();
+		if (offset > fReplacementOffset + wordLength)
+			return false;
 
-    /**
-     * borrowed from JavaCompletionProposal
-     * 
-     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument,
-     *      int, org.eclipse.jface.text.DocumentEvent)
-     */
-    public boolean validate(IDocument document, int offset, DocumentEvent event) {
-        if (offset < fReplacementOffset)
-            return false;
-        boolean validated = startsWith(document, offset, fDisplayString);
+		try {
+			int length = offset - fReplacementOffset;
+			String start = document.get(fReplacementOffset, length);
 
-        if (fUpdateLengthOnValidate) {
+			return word.substring(0, length).equalsIgnoreCase(start);
+		}
+		catch (BadLocationException x) {
+		}
 
-            // it would be better to use "originalCursorPosition" instead of
-            // getReplacementOffset(), but we don't have that info.
-            int newLength = offset - getReplacementOffset();
-            int delta = newLength - fOriginalReplacementLength;
-            fReplacementLength = delta + fOriginalReplacementLength;
-            
-        	// if it's an attribute value, replacement offset is
-            // going to be one off from the actual cursor offset...
-        	char firstChar = document.get().charAt(getReplacementOffset());
-        	if(firstChar == '"' || firstChar == '\'')
-        		fReplacementLength ++;
-        }
-        return validated;
-    }
-    
-    /**
-     * @param replacementOffset The fReplacementOffset to set.
-     */
-    public void setReplacementOffset(int replacementOffset) {
-        fReplacementOffset = replacementOffset;
-    }
-    /**
-     * @param replacementString The fReplacementString to set.
-     */
-    public void setReplacementString(String replacementString) {
-        fReplacementString = replacementString;
-    }
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
+	 */
+	public void unselected(ITextViewer viewer) {
+	}
+
+	/**
+	 * borrowed from JavaCompletionProposal
+	 * 
+	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument,
+	 *      int, org.eclipse.jface.text.DocumentEvent)
+	 */
+	public boolean validate(IDocument document, int offset, DocumentEvent event) {
+		if (offset < fReplacementOffset)
+			return false;
+		boolean validated = startsWith(document, offset, fDisplayString);
+
+		if (fUpdateLengthOnValidate) {
+
+			// it would be better to use "originalCursorPosition" instead of
+			// getReplacementOffset(), but we don't have that info.
+			int newLength = offset - getReplacementOffset();
+			int delta = newLength - fOriginalReplacementLength;
+			fReplacementLength = delta + fOriginalReplacementLength;
+
+			// if it's an attribute value, replacement offset is
+			// going to be one off from the actual cursor offset...
+			char firstChar = document.get().charAt(getReplacementOffset());
+			if (firstChar == '"' || firstChar == '\'')
+				fReplacementLength++;
+		}
+		return validated;
+	}
+
+	/**
+	 * @param replacementOffset
+	 *            The fReplacementOffset to set.
+	 */
+	public void setReplacementOffset(int replacementOffset) {
+		fReplacementOffset = replacementOffset;
+	}
+
+	/**
+	 * @param replacementString
+	 *            The fReplacementString to set.
+	 */
+	public void setReplacementString(String replacementString) {
+		fReplacementString = replacementString;
+	}
 }