[115927] First attribute quote is deleted if insert JSP expression through statement completion
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java
index 77a04bb..39858f5 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java
@@ -1145,7 +1145,8 @@
 			}
 		}
 		
-		addTemplates(request, TemplateContextTypeIdsJSP.ALL);
+		// bug115927 use original document position for all/any region templates
+		addTemplates(request, TemplateContextTypeIdsJSP.ALL, documentPosition);
 		return request;
 	}
 
@@ -1163,6 +1164,17 @@
 	 * @param context
 	 */
 	private void addTemplates(ContentAssistRequest contentAssistRequest, String context) {
+		addTemplates(contentAssistRequest, context, contentAssistRequest.getReplacementBeginPosition());
+	}
+	
+	/**
+	 * Adds templates to the list of proposals
+	 * 
+	 * @param contentAssistRequest
+	 * @param context
+	 * @param startOffset
+	 */
+	private void addTemplates(ContentAssistRequest contentAssistRequest, String context, int startOffset) {
 		if (contentAssistRequest == null)
 			return;
 		
@@ -1174,7 +1186,7 @@
 
 			if (getTemplateCompletionProcessor() != null) {
 				getTemplateCompletionProcessor().setContextType(context);
-				ICompletionProposal[] proposals = getTemplateCompletionProcessor().computeCompletionProposals(fTextViewer, contentAssistRequest.getReplacementBeginPosition());
+				ICompletionProposal[] proposals = getTemplateCompletionProcessor().computeCompletionProposals(fTextViewer, startOffset);
 				for (int i = 0; i < proposals.length; ++i) {
 					if (useProposalList)
 						contentAssistRequest.addProposal(proposals[i]);
@@ -1184,8 +1196,7 @@
 			}
 		}
 	}
-
-
+	
 	protected void addEntityProposals(ContentAssistRequest contentAssistRequest, int documentPosition, ITextRegion completionRegion, IDOMNode treeNode) {
 		// ignore
 	}
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPTemplateCompletionProcessor.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPTemplateCompletionProcessor.java
index f3214dc..e835787 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPTemplateCompletionProcessor.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPTemplateCompletionProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2006 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
@@ -10,14 +10,24 @@
  *******************************************************************************/
 package org.eclipse.jst.jsp.ui.internal.contentassist;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.jface.text.templates.ContextTypeRegistry;
 import org.eclipse.jface.text.templates.Template;
 import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
 import org.eclipse.jface.text.templates.TemplateContext;
 import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateProposal;
 import org.eclipse.jface.text.templates.persistence.TemplateStore;
 import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
 import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImageHelper;
@@ -30,12 +40,90 @@
  * JSPTemplateCompletionProcessor is asked for content assist proposals, the
  * jsp content assist processor has already set the context type for
  * templates.
- * 
- * @plannedfor 1.0
  */
 class JSPTemplateCompletionProcessor extends TemplateCompletionProcessor {
+	private static final class ProposalComparator implements Comparator {
+		public int compare(Object o1, Object o2) {
+			return ((TemplateProposal) o2).getRelevance() - ((TemplateProposal) o1).getRelevance();
+		}
+	}
+
+	private static final Comparator fgProposalComparator = new ProposalComparator();
 	private String fContextTypeId = null;
 
+	/*
+	 * Copied from super class except instead of calling createContext(viewer,
+	 * region) call createContext(viewer, region, offset) instead
+	 */
+	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+
+		ITextSelection selection = (ITextSelection) viewer.getSelectionProvider().getSelection();
+
+		// adjust offset to end of normalized selection
+		if (selection.getOffset() == offset)
+			offset = selection.getOffset() + selection.getLength();
+
+		String prefix = extractPrefix(viewer, offset);
+		Region region = new Region(offset - prefix.length(), prefix.length());
+		TemplateContext context = createContext(viewer, region, offset);
+		if (context == null)
+			return new ICompletionProposal[0];
+
+		context.setVariable("selection", selection.getText()); // name of the
+																// selection
+																// variables
+																// {line,
+																// word}_selection
+																// //$NON-NLS-1$
+
+		Template[] templates = getTemplates(context.getContextType().getId());
+
+		List matches = new ArrayList();
+		for (int i = 0; i < templates.length; i++) {
+			Template template = templates[i];
+			try {
+				context.getContextType().validate(template.getPattern());
+			}
+			catch (TemplateException e) {
+				continue;
+			}
+			if (template.matches(prefix, context.getContextType().getId()))
+				matches.add(createProposal(template, context, (IRegion) region, getRelevance(template, prefix)));
+		}
+
+		Collections.sort(matches, fgProposalComparator);
+
+		return (ICompletionProposal[]) matches.toArray(new ICompletionProposal[matches.size()]);
+	}
+
+	/**
+	 * Creates a concrete template context for the given region in the
+	 * document. This involves finding out which context type is valid at the
+	 * given location, and then creating a context of this type. The default
+	 * implementation returns a <code>SmartReplaceTemplateContext</code> for
+	 * the context type at the given location. This takes the offset at which
+	 * content assist was invoked into consideration.
+	 * 
+	 * @param viewer
+	 *            the viewer for which the context is created
+	 * @param region
+	 *            the region into <code>document</code> for which the
+	 *            context is created
+	 * @param offset
+	 *            the original offset where content assist was invoked
+	 * @return a template context that can handle template insertion at the
+	 *         given location, or <code>null</code>
+	 */
+	private TemplateContext createContext(ITextViewer viewer, IRegion region, int offset) {
+		// pretty much same code as super.createContext except create SmartReplaceTemplateContext
+		TemplateContextType contextType = getContextType(viewer, region);
+		if (contextType != null) {
+			IDocument document = viewer.getDocument();
+			return new ReplaceNameTemplateContext(contextType, document, region.getOffset(), region.getLength(), offset);
+		}
+		return null;
+	}
+	
 	protected ICompletionProposal createProposal(Template template, TemplateContext context, IRegion region, int relevance) {
 		return new CustomTemplateProposal(template, context, region, getImage(template), relevance);
 	}
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/ReplaceNameTemplateContext.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/ReplaceNameTemplateContext.java
new file mode 100644
index 0000000..1f4e9d1
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/ReplaceNameTemplateContext.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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.jst.jsp.ui.internal.contentassist;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+
+/**
+ * Just like DocumentTemplateContext except if an insert offset is passed in,
+ * during evaluation, the "prefix" before the template will be checked to see
+ * if it matches the template name. If so, overwrite the template name.
+ * Otherwise, just insert the template at the insert offset location (by not
+ * overwriting the prefix text)
+ */
+public class ReplaceNameTemplateContext extends DocumentTemplateContext {
+	private int fInsertOffset = -1;
+
+	/**
+	 * Creates a document template context.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param offset
+	 *            the offset of the document region
+	 * @param length
+	 *            the length of the document region
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, int offset, int length) {
+		this(type, document, new Position(offset, length));
+	}
+
+	/**
+	 * Creates a document template context. The supplied <code>Position</code>
+	 * will be queried to compute the <code>getStart</code> and
+	 * <code>getEnd</code> methods, which will therefore answer updated
+	 * position data if it is registered with the document.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param position
+	 *            the position describing the area of the document which forms
+	 *            the template context
+	 * @since 3.1
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, Position position) {
+		super(type, document, position);
+	}
+
+	/**
+	 * Creates a document template context.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param offset
+	 *            the offset of the document region
+	 * @param length
+	 *            the length of the document region
+	 * @param insertOffset
+	 *            the offset of the document region where insert was
+	 *            originally requested
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, int offset, int length, int insertOffset) {
+		this(type, document, new Position(offset, length));
+		fInsertOffset = insertOffset;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.templates.TemplateContext#evaluate(org.eclipse.jface.text.templates.Template)
+	 */
+	public TemplateBuffer evaluate(Template template) throws BadLocationException, TemplateException {
+		TemplateBuffer buffer = super.evaluate(template);
+		if (buffer != null) {
+			if (fInsertOffset > -1 && fInsertOffset > getStart()) {
+				String prefix = getDocument().get(getStart(), fInsertOffset - getStart());
+				if (!template.getName().startsWith(prefix)) {
+					// generate a new buffer that actually contains the
+					// text that was going to be overwritten
+					buffer = new TemplateBuffer(prefix + buffer.getString(), buffer.getVariables());
+				}
+			}
+		}
+		return buffer;
+	}
+}
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLContentAssistProcessor.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLContentAssistProcessor.java
index ff35669..f605ba6 100644
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLContentAssistProcessor.java
+++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLContentAssistProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2006 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
@@ -119,9 +119,20 @@
 	 * @param context
 	 */
 	private void addTemplates(ContentAssistRequest contentAssistRequest, String context) {
+		addTemplates(contentAssistRequest, context, contentAssistRequest.getReplacementBeginPosition());
+	}
+	
+	/**
+	 * Adds templates to the list of proposals
+	 * 
+	 * @param contentAssistRequest
+	 * @param context
+	 * @param startOffset
+	 */
+	private void addTemplates(ContentAssistRequest contentAssistRequest, String context, int startOffset) {
 		if (contentAssistRequest == null)
 			return;
-
+		
 		// if already adding template proposals for a certain context type, do
 		// not add again
 		if (!fTemplateContexts.contains(context)) {
@@ -130,7 +141,7 @@
 
 			if (getTemplateCompletionProcessor() != null) {
 				getTemplateCompletionProcessor().setContextType(context);
-				ICompletionProposal[] proposals = getTemplateCompletionProcessor().computeCompletionProposals(fTextViewer, contentAssistRequest.getReplacementBeginPosition());
+				ICompletionProposal[] proposals = getTemplateCompletionProcessor().computeCompletionProposals(fTextViewer, startOffset);
 				for (int i = 0; i < proposals.length; ++i) {
 					if (useProposalList)
 						contentAssistRequest.addProposal(proposals[i]);
@@ -151,7 +162,8 @@
 
 	protected ContentAssistRequest computeCompletionProposals(int documentPosition, String matchString, ITextRegion completionRegion, IDOMNode treeNode, IDOMNode xmlnode) {
 		ContentAssistRequest request = super.computeCompletionProposals(documentPosition, matchString, completionRegion, treeNode, xmlnode);
-		addTemplates(request, TemplateContextTypeIdsHTML.ALL);
+		// bug115927 use original document position for all/any region templates
+		addTemplates(request, TemplateContextTypeIdsHTML.ALL, documentPosition);
 		return request;
 	}
 
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLTemplateCompletionProcessor.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLTemplateCompletionProcessor.java
index cc01530..1013fab 100644
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLTemplateCompletionProcessor.java
+++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/HTMLTemplateCompletionProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2006 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
@@ -10,14 +10,24 @@
  *******************************************************************************/
 package org.eclipse.wst.html.ui.internal.contentassist;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.jface.text.templates.ContextTypeRegistry;
 import org.eclipse.jface.text.templates.Template;
 import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
 import org.eclipse.jface.text.templates.TemplateContext;
 import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateProposal;
 import org.eclipse.jface.text.templates.persistence.TemplateStore;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.wst.html.ui.internal.HTMLUIPlugin;
@@ -33,8 +43,88 @@
  * templates.
  */
 class HTMLTemplateCompletionProcessor extends TemplateCompletionProcessor {
+	private static final class ProposalComparator implements Comparator {
+		public int compare(Object o1, Object o2) {
+			return ((TemplateProposal) o2).getRelevance() - ((TemplateProposal) o1).getRelevance();
+		}
+	}
+
+	private static final Comparator fgProposalComparator = new ProposalComparator();
 	private String fContextTypeId = null;
 
+	/*
+	 * Copied from super class except instead of calling createContext(viewer,
+	 * region) call createContext(viewer, region, offset) instead
+	 */
+	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+
+		ITextSelection selection = (ITextSelection) viewer.getSelectionProvider().getSelection();
+
+		// adjust offset to end of normalized selection
+		if (selection.getOffset() == offset)
+			offset = selection.getOffset() + selection.getLength();
+
+		String prefix = extractPrefix(viewer, offset);
+		Region region = new Region(offset - prefix.length(), prefix.length());
+		TemplateContext context = createContext(viewer, region, offset);
+		if (context == null)
+			return new ICompletionProposal[0];
+
+		context.setVariable("selection", selection.getText()); // name of the
+																// selection
+																// variables
+																// {line,
+																// word}_selection
+																// //$NON-NLS-1$
+
+		Template[] templates = getTemplates(context.getContextType().getId());
+
+		List matches = new ArrayList();
+		for (int i = 0; i < templates.length; i++) {
+			Template template = templates[i];
+			try {
+				context.getContextType().validate(template.getPattern());
+			}
+			catch (TemplateException e) {
+				continue;
+			}
+			if (template.matches(prefix, context.getContextType().getId()))
+				matches.add(createProposal(template, context, (IRegion) region, getRelevance(template, prefix)));
+		}
+
+		Collections.sort(matches, fgProposalComparator);
+
+		return (ICompletionProposal[]) matches.toArray(new ICompletionProposal[matches.size()]);
+	}
+
+	/**
+	 * Creates a concrete template context for the given region in the
+	 * document. This involves finding out which context type is valid at the
+	 * given location, and then creating a context of this type. The default
+	 * implementation returns a <code>SmartReplaceTemplateContext</code> for
+	 * the context type at the given location. This takes the offset at which
+	 * content assist was invoked into consideration.
+	 * 
+	 * @param viewer
+	 *            the viewer for which the context is created
+	 * @param region
+	 *            the region into <code>document</code> for which the
+	 *            context is created
+	 * @param offset
+	 *            the original offset where content assist was invoked
+	 * @return a template context that can handle template insertion at the
+	 *         given location, or <code>null</code>
+	 */
+	private TemplateContext createContext(ITextViewer viewer, IRegion region, int offset) {
+		// pretty much same code as super.createContext except create SmartReplaceTemplateContext
+		TemplateContextType contextType = getContextType(viewer, region);
+		if (contextType != null) {
+			IDocument document = viewer.getDocument();
+			return new ReplaceNameTemplateContext(contextType, document, region.getOffset(), region.getLength(), offset);
+		}
+		return null;
+	}
+
 	protected ICompletionProposal createProposal(Template template, TemplateContext context, IRegion region, int relevance) {
 		return new CustomTemplateProposal(template, context, region, getImage(template), relevance);
 	}
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/ReplaceNameTemplateContext.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/ReplaceNameTemplateContext.java
new file mode 100644
index 0000000..eef8962
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/ReplaceNameTemplateContext.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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.wst.html.ui.internal.contentassist;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+
+/**
+ * Just like DocumentTemplateContext except if an insert offset is passed in,
+ * during evaluation, the "prefix" before the template will be checked to see
+ * if it matches the template name. If so, overwrite the template name.
+ * Otherwise, just insert the template at the insert offset location (by not
+ * overwriting the prefix text)
+ */
+public class ReplaceNameTemplateContext extends DocumentTemplateContext {
+	private int fInsertOffset = -1;
+
+	/**
+	 * Creates a document template context.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param offset
+	 *            the offset of the document region
+	 * @param length
+	 *            the length of the document region
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, int offset, int length) {
+		this(type, document, new Position(offset, length));
+	}
+
+	/**
+	 * Creates a document template context. The supplied <code>Position</code>
+	 * will be queried to compute the <code>getStart</code> and
+	 * <code>getEnd</code> methods, which will therefore answer updated
+	 * position data if it is registered with the document.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param position
+	 *            the position describing the area of the document which forms
+	 *            the template context
+	 * @since 3.1
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, Position position) {
+		super(type, document, position);
+	}
+
+	/**
+	 * Creates a document template context.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param offset
+	 *            the offset of the document region
+	 * @param length
+	 *            the length of the document region
+	 * @param insertOffset
+	 *            the offset of the document region where insert was
+	 *            originally requested
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, int offset, int length, int insertOffset) {
+		this(type, document, new Position(offset, length));
+		fInsertOffset = insertOffset;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.templates.TemplateContext#evaluate(org.eclipse.jface.text.templates.Template)
+	 */
+	public TemplateBuffer evaluate(Template template) throws BadLocationException, TemplateException {
+		TemplateBuffer buffer = super.evaluate(template);
+		if (buffer != null) {
+			if (fInsertOffset > -1 && fInsertOffset > getStart()) {
+				String prefix = getDocument().get(getStart(), fInsertOffset - getStart());
+				if (!template.getName().startsWith(prefix)) {
+					// generate a new buffer that actually contains the
+					// text that was going to be overwritten
+					buffer = new TemplateBuffer(prefix + buffer.getString(), buffer.getVariables());
+				}
+			}
+		}
+		return buffer;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/ReplaceNameTemplateContext.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/ReplaceNameTemplateContext.java
new file mode 100644
index 0000000..9eb98c4
--- /dev/null
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/ReplaceNameTemplateContext.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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.wst.xml.ui.internal.contentassist;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+
+/**
+ * Just like DocumentTemplateContext except if an insert offset is passed in,
+ * during evaluation, the "prefix" before the template will be checked to see
+ * if it matches the template name. If so, overwrite the template name.
+ * Otherwise, just insert the template at the insert offset location (by not
+ * overwriting the prefix text)
+ */
+public class ReplaceNameTemplateContext extends DocumentTemplateContext {
+	private int fInsertOffset = -1;
+
+	/**
+	 * Creates a document template context.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param offset
+	 *            the offset of the document region
+	 * @param length
+	 *            the length of the document region
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, int offset, int length) {
+		this(type, document, new Position(offset, length));
+	}
+
+	/**
+	 * Creates a document template context. The supplied <code>Position</code>
+	 * will be queried to compute the <code>getStart</code> and
+	 * <code>getEnd</code> methods, which will therefore answer updated
+	 * position data if it is registered with the document.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param position
+	 *            the position describing the area of the document which forms
+	 *            the template context
+	 * @since 3.1
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, Position position) {
+		super(type, document, position);
+	}
+
+	/**
+	 * Creates a document template context.
+	 * 
+	 * @param type
+	 *            the context type
+	 * @param document
+	 *            the document this context applies to
+	 * @param offset
+	 *            the offset of the document region
+	 * @param length
+	 *            the length of the document region
+	 * @param insertOffset
+	 *            the offset of the document region where insert was
+	 *            originally requested
+	 */
+	public ReplaceNameTemplateContext(TemplateContextType type, IDocument document, int offset, int length, int insertOffset) {
+		this(type, document, new Position(offset, length));
+		fInsertOffset = insertOffset;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.templates.TemplateContext#evaluate(org.eclipse.jface.text.templates.Template)
+	 */
+	public TemplateBuffer evaluate(Template template) throws BadLocationException, TemplateException {
+		TemplateBuffer buffer = super.evaluate(template);
+		if (buffer != null) {
+			if (fInsertOffset > -1 && fInsertOffset > getStart()) {
+				String prefix = getDocument().get(getStart(), fInsertOffset - getStart());
+				if (!template.getName().startsWith(prefix)) {
+					// generate a new buffer that actually contains the
+					// text that was going to be overwritten
+					buffer = new TemplateBuffer(prefix + buffer.getString(), buffer.getVariables());
+				}
+			}
+		}
+		return buffer;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLContentAssistProcessor.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLContentAssistProcessor.java
index 01068ba..32b40df 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLContentAssistProcessor.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLContentAssistProcessor.java
@@ -65,9 +65,20 @@
 	 * @param context
 	 */
 	private void addTemplates(ContentAssistRequest contentAssistRequest, String context) {
+		addTemplates(contentAssistRequest, context, contentAssistRequest.getReplacementBeginPosition());
+	}
+	
+	/**
+	 * Adds templates to the list of proposals
+	 * 
+	 * @param contentAssistRequest
+	 * @param context
+	 * @param startOffset
+	 */
+	private void addTemplates(ContentAssistRequest contentAssistRequest, String context, int startOffset) {
 		if (contentAssistRequest == null)
 			return;
-
+		
 		// if already adding template proposals for a certain context type, do
 		// not add again
 		if (!fTemplateContexts.contains(context)) {
@@ -76,7 +87,7 @@
 
 			if (getTemplateCompletionProcessor() != null) {
 				getTemplateCompletionProcessor().setContextType(context);
-				ICompletionProposal[] proposals = getTemplateCompletionProcessor().computeCompletionProposals(fTextViewer, contentAssistRequest.getReplacementBeginPosition());
+				ICompletionProposal[] proposals = getTemplateCompletionProcessor().computeCompletionProposals(fTextViewer, startOffset);
 				for (int i = 0; i < proposals.length; ++i) {
 					if (useProposalList)
 						contentAssistRequest.addProposal(proposals[i]);
@@ -89,7 +100,8 @@
 	
 	protected ContentAssistRequest computeCompletionProposals(int documentPosition, String matchString, ITextRegion completionRegion, IDOMNode treeNode, IDOMNode xmlnode) {
 		ContentAssistRequest request = super.computeCompletionProposals(documentPosition, matchString, completionRegion, treeNode, xmlnode);
-		addTemplates(request, TemplateContextTypeIdsXML.ALL);
+		// bug115927 use original document position for all/any region templates
+		addTemplates(request, TemplateContextTypeIdsXML.ALL, documentPosition);
 		return request;
 	}
 	
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLTemplateCompletionProcessor.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLTemplateCompletionProcessor.java
index a789a47..619bcae 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLTemplateCompletionProcessor.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLTemplateCompletionProcessor.java
@@ -12,14 +12,24 @@
  *******************************************************************************/
 package org.eclipse.wst.xml.ui.internal.contentassist;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.jface.text.templates.ContextTypeRegistry;
 import org.eclipse.jface.text.templates.Template;
 import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
 import org.eclipse.jface.text.templates.TemplateContext;
 import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateProposal;
 import org.eclipse.jface.text.templates.persistence.TemplateStore;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
@@ -35,8 +45,88 @@
  * templates.
  */
 class XMLTemplateCompletionProcessor extends TemplateCompletionProcessor {
+	private static final class ProposalComparator implements Comparator {
+		public int compare(Object o1, Object o2) {
+			return ((TemplateProposal) o2).getRelevance() - ((TemplateProposal) o1).getRelevance();
+		}
+	}
+
+	private static final Comparator fgProposalComparator = new ProposalComparator();
 	private String fContextTypeId = null;
 
+	/*
+	 * Copied from super class except instead of calling createContext(viewer,
+	 * region) call createContext(viewer, region, offset) instead
+	 */
+	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+
+		ITextSelection selection = (ITextSelection) viewer.getSelectionProvider().getSelection();
+
+		// adjust offset to end of normalized selection
+		if (selection.getOffset() == offset)
+			offset = selection.getOffset() + selection.getLength();
+
+		String prefix = extractPrefix(viewer, offset);
+		Region region = new Region(offset - prefix.length(), prefix.length());
+		TemplateContext context = createContext(viewer, region, offset);
+		if (context == null)
+			return new ICompletionProposal[0];
+
+		context.setVariable("selection", selection.getText()); // name of the
+																// selection
+																// variables
+																// {line,
+																// word}_selection
+																// //$NON-NLS-1$
+
+		Template[] templates = getTemplates(context.getContextType().getId());
+
+		List matches = new ArrayList();
+		for (int i = 0; i < templates.length; i++) {
+			Template template = templates[i];
+			try {
+				context.getContextType().validate(template.getPattern());
+			}
+			catch (TemplateException e) {
+				continue;
+			}
+			if (template.matches(prefix, context.getContextType().getId()))
+				matches.add(createProposal(template, context, (IRegion) region, getRelevance(template, prefix)));
+		}
+
+		Collections.sort(matches, fgProposalComparator);
+
+		return (ICompletionProposal[]) matches.toArray(new ICompletionProposal[matches.size()]);
+	}
+
+	/**
+	 * Creates a concrete template context for the given region in the
+	 * document. This involves finding out which context type is valid at the
+	 * given location, and then creating a context of this type. The default
+	 * implementation returns a <code>SmartReplaceTemplateContext</code> for
+	 * the context type at the given location. This takes the offset at which
+	 * content assist was invoked into consideration.
+	 * 
+	 * @param viewer
+	 *            the viewer for which the context is created
+	 * @param region
+	 *            the region into <code>document</code> for which the
+	 *            context is created
+	 * @param offset
+	 *            the original offset where content assist was invoked
+	 * @return a template context that can handle template insertion at the
+	 *         given location, or <code>null</code>
+	 */
+	private TemplateContext createContext(ITextViewer viewer, IRegion region, int offset) {
+		// pretty much same code as super.createContext except create SmartReplaceTemplateContext
+		TemplateContextType contextType = getContextType(viewer, region);
+		if (contextType != null) {
+			IDocument document = viewer.getDocument();
+			return new ReplaceNameTemplateContext(contextType, document, region.getOffset(), region.getLength(), offset);
+		}
+		return null;
+	}
+	
 	protected ICompletionProposal createProposal(Template template, TemplateContext context, IRegion region, int relevance) {
 		return new CustomTemplateProposal(template, context, region, getImage(template), relevance);
 	}