[304575] [translation] Cannot be resolved errors when Struts <bean:define> is defined within <input type> HTML tag
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
index e31c359..a565019 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 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
@@ -102,6 +102,7 @@
 	private static final boolean DEBUG;
 	private static final boolean DEBUG_SAVE_OUTPUT = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jsptranslationstodisk")); //$NON-NLS-1$  //$NON-NLS-2$
 
+	private static final String JSP_PREFIX = "jsp:"; //$NON-NLS-1$
 	private IJSPELTranslator fELTranslator = null;
 
 	static {
@@ -769,126 +770,141 @@
 	}
 
 	protected void addTaglibVariables(String tagToAdd, ITextRegionCollection customTag) {
+		if (customTag.getFirstRegion().getType().equals(DOMRegionContext.XML_TAG_OPEN)) {
+			/*
+			 * Start tag
+			 */
+			addStartTagVariable(tagToAdd, customTag);
+		}
+		else if (customTag.getFirstRegion().getType().equals(DOMRegionContext.XML_END_TAG_OPEN)) {
+			/*
+			 * End tag
+			 */
+			addEndTagVariable(tagToAdd, customTag);
+		}
+	}
+
+	private void addEndTagVariable(String tagToAdd, ITextRegionCollection customTag){
+		IFile f = getFile();
+		if (f == null || !f.exists())
+				return;
+		String decl = ""; //$NON-NLS-1$
+		RegionTag regionAndTags = (RegionTag) fTagToVariableMap.pop(tagToAdd);
+		if (regionAndTags != null) {
+			TaglibVariable[] taglibVars = regionAndTags.tag.getTagVariables();
+			StringBuffer text = new StringBuffer();
+			if (regionAndTags.tag.isIterationTag())
+				doAfterBody(text, regionAndTags);
+			text.append("} // </"); //$NON-NLS-1$
+			text.append(tagToAdd);
+			text.append(">\n"); //$NON-NLS-1$
+			appendToBuffer(text.toString(), fUserCode, false, customTag);
+			for (int i = 0; i < taglibVars.length; i++) {
+				if (taglibVars[i].getScope() == VariableInfo.AT_END) {
+					decl = taglibVars[i].getDeclarationString();
+					appendToBuffer(decl, fUserCode, false, customTag);
+				}
+			}
+		}
+		else {
+			// report an unmatched end tag in fTranslationProblems ?
+		}
+	}
+
+	private void addStartTagVariable(String tagToAdd,ITextRegionCollection customTag){
 		IFile f = getFile();
 
 		if (f == null || !f.exists())
 			return;
-
 		TaglibHelper helper = TaglibHelperManager.getInstance().getTaglibHelper(f);
-		/*
-		 * Variables can declare as available when NESTED, AT_BEGIN, or
-		 * AT_END. For AT_END variables, store the entire list of variables in
-		 * the map field so it can be used on the end tag.
-		 */
 		String decl = ""; //$NON-NLS-1$
-		if (customTag.getFirstRegion().getType().equals(DOMRegionContext.XML_TAG_OPEN)) {
-			CustomTag tag = helper.getCustomTag(tagToAdd, getStructuredDocument(), customTag);
-			TaglibVariable[] taglibVars = tag.getTagVariables();
+		CustomTag tag = helper.getCustomTag(tagToAdd, getStructuredDocument(), customTag);
+		TaglibVariable[] taglibVars = tag.getTagVariables();
+		/*
+		 * Add AT_BEGIN variables
+		 */
+		for (int i = 0; i < taglibVars.length; i++) {
+			if (taglibVars[i].getScope() == VariableInfo.AT_BEGIN) {
+				decl = taglibVars[i].getDeclarationString();
+				appendToBuffer(decl, fUserCode, false, customTag);
+			}
+		}
+		boolean isEmptyTag = isEmptyTag(customTag);
+		/*
+		 * Add a single  { to limit the scope of NESTED variables
+		 */
+		StringBuffer text = new StringBuffer();
+		if (!isEmptyTag && tag.isIterationTag() && tag.getTagClassName() != null) {
+			text.append("\nwhile(true) "); //$NON-NLS-1$
+		}
+		text.append("{ // <"); //$NON-NLS-1$
+		text.append(tagToAdd);
+		if (isEmptyTag)
+			text.append("/>\n"); //$NON-NLS-1$
+		else
+			text.append(">\n"); //$NON-NLS-1$
+
+		appendToBuffer(text.toString(), fUserCode, false, customTag);
+
+		for (int i = 0; i < taglibVars.length; i++) {
+			if (taglibVars[i].getScope() == VariableInfo.NESTED) {
+				decl = taglibVars[i].getDeclarationString();
+				appendToBuffer(decl, fUserCode, false, customTag);
+			}
+		}
+		/*
+		 * For empty tags, add the corresponding } and AT_END variables immediately.  
+		 */
+		if (isEmptyTag) {
+			text = new StringBuffer();
+			text.append("} // <"); //$NON-NLS-1$
+			text.append(tagToAdd);
+			text.append("/>\n"); //$NON-NLS-1$
+			appendToBuffer(text.toString(), fUserCode, false, customTag);
+			/* Treat this as the end for empty tags */
+			for (int i = 0; i < taglibVars.length; i++) {
+				if (taglibVars[i].getScope() == VariableInfo.AT_END) {
+					decl = taglibVars[i].getDeclarationString();
+					appendToBuffer(decl, fUserCode, false, customTag);
+				}
+			}
+		}
+		else {
 			/*
-			 * Store for use at end tag and for accurate pairing even with
-			 * extra end tags (with empty non-null array)
+			 * For non-empty tags, remember the variable information
 			 */
 			fTagToVariableMap.push(tagToAdd, new RegionTag(customTag, tag));
+		}
+		
+	}
 
-			// Bug 199047
+	private void addCustomTaglibVariables(String tagToAdd, ITextRegionCollection customTag, ITextRegion prevRegion) {
+		//Can't judge by first region as start and end tag are part of same ContextRegionContainer		
+		if (prevRegion != null && prevRegion.getType().equals(DOMRegionContext.XML_END_TAG_OPEN)) {
 			/*
-			 * Add AT_BEGIN variables
+			 * End tag
 			 */
-			for (int i = 0; i < taglibVars.length; i++) {
-				if (taglibVars[i].getScope() == VariableInfo.AT_BEGIN) {
-					decl = taglibVars[i].getDeclarationString();
-					appendToBuffer(decl, fUserCode, false, customTag);
-				}
-			}
+			addEndTagVariable(tagToAdd, customTag);
+		}
+		else if (prevRegion != null && prevRegion.getType().equals(DOMRegionContext.XML_TAG_OPEN)) {
+			/*
+			 * Start tag
+			 */
+			addStartTagVariable(tagToAdd,customTag);
+		}
+	}
 
-			boolean isEmptyTag = customTag.getLastRegion().getType().equals(DOMRegionContext.XML_EMPTY_TAG_CLOSE);
-			/**
-			 * Add single opening curly brace
-			 */
-			StringBuffer text = new StringBuffer();
-			if (!isEmptyTag && tag.isIterationTag() && tag.getTagClassName() != null)
-				text.append("\nwhile (true) "); //$NON-NLS-1$
-			text.append("{ // <"); //$NON-NLS-1$
-			text.append(tagToAdd);
-			if (isEmptyTag) {
-				text.append("/>\n"); //$NON-NLS-1$
-			}
-			else {
-				text.append(">\n"); //$NON-NLS-1$
-			}
-			appendToBuffer(text.toString(), fUserCode, false, customTag); //$NON-NLS-1$
-
-			/**
-			 * Add NESTED variables 
-			 */
-			for (int i = 0; i < taglibVars.length; i++) {
-				if (taglibVars[i].getScope() == VariableInfo.NESTED) {
-					decl = taglibVars[i].getDeclarationString();
-					appendToBuffer(decl, fUserCode, false, customTag);
-				}
-			}
-
-			/**
-			 * If empty, pop from stack, add ending curly brace and AT_END
-			 * variables
-			 */
-			if (isEmptyTag) {
-				// Add single closing curly brace
-				text = new StringBuffer();
-				text.append("} // <"); //$NON-NLS-1$
-				text.append(tagToAdd);
-					text.append("/>\n"); //$NON-NLS-1$
-				appendToBuffer(text.toString(), fUserCode, false, customTag); //$NON-NLS-1$
-				// pop them off since there won't be a separate end tag to do so
-				fTagToVariableMap.pop(tagToAdd);
-				/*
-				 * Add AT_END variables 
-				 */
-				for (int i = 0; i < taglibVars.length; i++) {
-					if (taglibVars[i].getScope() == VariableInfo.AT_END) {
-						decl = taglibVars[i].getDeclarationString();
-						appendToBuffer(decl, fUserCode, false, customTag);
-					}
-				}
+	private boolean isEmptyTag(ITextRegionCollection customTag) {
+		ITextRegion lastRegion = customTag.getLastRegion();
+		// custom tag is embedded
+		if (customTag instanceof ITextRegionContainer) {
+			ITextRegionList regions = customTag.getRegions();
+			int size = customTag.getNumberOfRegions() - 1;
+			while (size > 0 && !(DOMRegionContext.XML_EMPTY_TAG_CLOSE.equals(lastRegion.getType()) || DOMRegionContext.XML_TAG_NAME.equals(lastRegion.getType()) || DOMRegionContext.XML_TAG_CLOSE.equals(lastRegion.getType()) )) {
+				lastRegion = regions.get(--size);
 			}
 		}
-		/**
-		 * Pop from stack, add ending curly brace and AT_END
-		 * variables
-		 */
-		else if (customTag.getFirstRegion().getType().equals(DOMRegionContext.XML_END_TAG_OPEN)) {
-			// pop the variables
-			RegionTag regionTag = (RegionTag) fTagToVariableMap.pop(tagToAdd);
-			if (regionTag != null) {
-				TaglibVariable[] taglibVars = regionTag.tag.getTagVariables();
-				/*
-				 * Even an empty array will indicate a need for a closing
-				 * brace, so add one. If "taglibVars" is null, that means
-				 * there was no start tag for use with this end tag. Adding a
-				 * '}' even then would cause a Java translation fault, but
-				 * that's not particularly helpful to a user who may only know
-				 * how to use custom tags. Ultimately unbalanced custom tags
-				 * should just be reported as unbalanced tags.
-				 */
-				StringBuffer text = new StringBuffer();
-				if (regionTag.tag.isIterationTag())
-					doAfterBody(text, regionTag);
-				text.append("} // </"); //$NON-NLS-1$
-				text.append(tagToAdd);
-				text.append(">\n"); //$NON-NLS-1$
-				appendToBuffer(text.toString(), fUserCode, false, customTag); //$NON-NLS-1$
-
-				/*
-				 * Add AT_END variables 
-				 */
-				for (int i = 0; i < taglibVars.length; i++) {
-					if (taglibVars[i].getScope() == VariableInfo.AT_END) {
-						decl = taglibVars[i].getDeclarationString();
-						appendToBuffer(decl, fUserCode, false, customTag);
-					}
-				}
-			}
-		}
+		return DOMRegionContext.XML_EMPTY_TAG_CLOSE.equals(lastRegion.getType());
 	}
 
 	private void doAfterBody(StringBuffer buffer, RegionTag regionTag) {
@@ -1656,6 +1672,15 @@
 			// possible delimiter, check later
 			delim = embeddedRegions.get(i);
 			type = delim.getType();
+			if (type == DOMRegionContext.XML_TAG_NAME )	{
+				String fullTagName = embeddedContainer.getText(delim);
+				if (fullTagName.indexOf(':') > -1 && !fullTagName.startsWith(JSP_PREFIX)) {
+					ITextRegion prevRegion =null;
+					if (i>0)
+						prevRegion = embeddedRegions.get(i-1);
+					addCustomTaglibVariables(fullTagName, embeddedContainer,prevRegion); // it may be a custom tag
+				}
+			}
 			if(type == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE || type == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_SQUOTE
 				|| type == DOMJSPRegionContexts.JSP_TAG_ATTRIBUTE_VALUE_DQUOTE || type == DOMJSPRegionContexts.JSP_TAG_ATTRIBUTE_VALUE_SQUOTE)
 				quotetype = type;