[334150] Breakpoints in JSP fragment (.jspf) files are not hit
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/ClassPatternRegistry.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/ClassPatternRegistry.java
index 321570a..2c53099 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/ClassPatternRegistry.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/ClassPatternRegistry.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
+ * Copyright (c) 2010, 2011 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
@@ -11,13 +11,18 @@
 package org.eclipse.jst.jsp.ui.internal.breakpointproviders;
 
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.RegistryFactory;
 import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
 
+import com.ibm.icu.util.StringTokenizer;
+
 /**
  * This registry provides all additional class patterns to be associated with a specific content type
  *
@@ -36,16 +41,21 @@
 			for (int i = 0; i < elements.length; i++) {
 				final IConfigurationElement element = elements[i];
 				final String contentType = element.getAttribute("contentType"); //$NON-NLS-1$
-				String pattern = element.getAttribute("pattern"); //$NON-NLS-1$
+				final String pattern = element.getAttribute("pattern"); //$NON-NLS-1$
 				if (pattern != null && contentType != null) {
-					String old = (String) fPatterns.get(contentType);
-					final StringBuffer buffer = old == null ? new StringBuffer() : new StringBuffer(old);
-					pattern = pattern.trim();
-					if (pattern.length() > 0) {
-						if (pattern.charAt(0) != ',' && buffer.length() > 0 && buffer.charAt(buffer.length() - 1) != ',')
-							buffer.append(',');
-						buffer.append(pattern);
-						fPatterns.put(contentType, buffer.toString());
+					final StringTokenizer tokenizer = new StringTokenizer(pattern, ","); //$NON-NLS-1$
+					Set patterns = (Set) fPatterns.get(contentType);
+					if (patterns == null) {
+						patterns = new HashSet(0);
+						fPatterns.put(contentType, patterns);
+					}
+
+					while (tokenizer.hasMoreTokens()) {
+						String token = tokenizer.nextToken();
+						token = token.trim();
+						if (token.length() > 0) {
+							patterns.add(token);
+						}
 					}
 				}
 				
@@ -54,14 +64,60 @@
 	}
 
 	/**
-	 * Returns an iterator for the additional class patterns to be associated with the provided content type id.
+	 * Returns the additional class patterns to be associated with the provided content type id.
 	 * @param contentType the content type id to find patterns for
-	 * @return an iterator for the additional class patterns
+	 * @return an String for the additional class patterns
 	 */
 	public String getClassPattern(String contentType) {
-		return fPatterns != null ? (String) fPatterns.get(contentType) : null;
+		if (fPatterns == null)
+			return null;
+		final Set patterns = (Set) fPatterns.get(contentType);
+		if (patterns != null) {
+			final Iterator it = patterns.iterator();
+			final StringBuffer buffer = new StringBuffer();
+			while (it.hasNext()) {
+				if (buffer.length() > 0)
+					buffer.append(',');
+				buffer.append(it.next());
+			}
+			return buffer.toString();
+		}
+		return null;
 	}
 
+	public Iterator getClassPatternSegments(String contentType) {
+		Iterator result = EMPTY;
+		if (fPatterns != null) {
+			Set patterns = (Set) fPatterns.get(contentType);
+			if (patterns != null)
+				result = patterns.iterator();
+		}
+		return result;
+	}
+
+	private static final Iterator EMPTY = new Iterator() {
+
+		/* (non-Javadoc)
+		 * @see java.util.Iterator#hasNext()
+		 */
+		public boolean hasNext() {
+			return false;
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Iterator#next()
+		 */
+		public Object next() {
+			return null;
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Iterator#remove()
+		 */
+		public void remove() {}
+		
+	};
+
 	public static synchronized ClassPatternRegistry getInstance() {
 		if (fInstance == null) {
 			fInstance = new ClassPatternRegistry();
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/JavaStratumBreakpointProvider.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/JavaStratumBreakpointProvider.java
index c4e7bad..b97f332 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/JavaStratumBreakpointProvider.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/breakpointproviders/JavaStratumBreakpointProvider.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2010 IBM Corporation and others.
+ * Copyright (c) 2004, 2011 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
@@ -11,7 +11,10 @@
 package org.eclipse.jst.jsp.ui.internal.breakpointproviders;
 
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
@@ -125,6 +128,7 @@
 					types = Platform.getContentTypeManager().findContentTypesFor(resource.getName());
 				}
 				StringBuffer patternBuffer = new StringBuffer("_" + shortName);
+				final Set contributions = new HashSet(0);
 				for (int i = 0; i < types.length; i++) {
 					final String id = types[i].getId();
 					Object pattern = ((Map) fData).get(id);
@@ -133,11 +137,17 @@
 						patternBuffer.append(pattern);
 					}
 					 // Append contributions
-					final String contributions = ClassPatternRegistry.getInstance().getClassPattern(id);
-					if (contributions != null && contributions.length() > 0) {
-						if (contributions.charAt(0) != ',')
-							patternBuffer.append(',');
-						patternBuffer.append(contributions);
+					
+					final Iterator it = ClassPatternRegistry.getInstance().getClassPatternSegments(id);
+					while (it.hasNext()) {
+						contributions.add(it.next());
+					}
+				}
+				if (contributions.size() > 0) {
+					final Iterator it = contributions.iterator();
+					while (it.hasNext()) {
+						patternBuffer.append(',');
+						patternBuffer.append(it.next());
 					}
 				}
 				return patternBuffer.toString();