Index: trunk/de.ugoe.cs.swe.bnftools.ebnf/src/de/ugoe/cs/swe/bnftools/validation/EbnfJavaValidator.java
===================================================================
--- trunk/de.ugoe.cs.swe.bnftools.ebnf/src/de/ugoe/cs/swe/bnftools/validation/EbnfJavaValidator.java	(revision 48)
+++ trunk/de.ugoe.cs.swe.bnftools.ebnf/src/de/ugoe/cs/swe/bnftools/validation/EbnfJavaValidator.java	(revision 49)
@@ -3,7 +3,9 @@
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Stack;
 
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.xtext.parsetree.AbstractNode;
@@ -336,10 +338,148 @@
 	
 	@Check(CheckType.EXPENSIVE)
-	public void checkSubruleDuplicates(Rule rule) {
+	public void checkSubruleDuplicates(EtsiBnf bnf) {
 		if (!checkSubruleDuplicates)
 			return;
 
-		//TODO: currently compares complete rules and not subrules
-		
+		for (int i=0; i < bnf.getBnfEntry().size(); i++) {
+			BnfEntry currentBnfEntry = bnf.getBnfEntry().get(i);
+			if ((currentBnfEntry.getRule() != null) && (currentBnfEntry.getRule().getDefinitionList() != null)) {
+				
+				CompositeNode ruleParserNode = NodeUtil.getNodeAdapter(currentBnfEntry.getRule().getDefinitionList()).getParserNode();
+				String ruleText = ruleParserNode.serialize().trim();
+				ruleText = ruleText + " ";
+				String processedRuleText = ruleText.replaceAll("([^\"])\\(([^\"])", "$1 ( $2"); // ( case 1
+				processedRuleText = processedRuleText.replaceAll("\\(([^\"])", " ( $1"); // ( case 2
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\(\"", "$1 ( \""); // ( case 3
+
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\)([^\"])", "$1 ) $2"); // ) case 1
+				processedRuleText = processedRuleText.replaceAll("\\)([^\"])", " ) $1"); // ) case 2
+				processedRuleText = processedRuleText.replaceAll("\"\\)([^\"])", "\" ) $1"); // ) case 3
+				
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\{([^\"])", "$1 { $2"); // { case 1
+				processedRuleText = processedRuleText.replaceAll("\\{([^\"])", " { $1"); // { case 2
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\{\"", "$1 { \""); // { case 3
+				
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\}([^\\+\"])", "$1 } $2"); // } case 1
+				processedRuleText = processedRuleText.replaceAll("\\}([^\\+\"])", " } $1"); // } case 2
+				processedRuleText = processedRuleText.replaceAll("\"\\}([^\\+\"])", "\" } $1"); // } case 3
+				
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\}\\+([^\"])", "$1 }\\+ $2"); // }+ case 1
+				processedRuleText = processedRuleText.replaceAll("\\}\\+([^\"])", " }\\+ $1 "); // }+ case 2
+				processedRuleText = processedRuleText.replaceAll("\"\\}\\+([^\"])", "\" }\\+ $1 "); // }+ case 3
+				
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\[([^\"])", "$1 [ $2"); // [ case 1
+				processedRuleText = processedRuleText.replaceAll("\\[([^\"])", " [ $1"); // [ case 2
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\[\"", "$1 [ \""); // [ case 3
+
+				processedRuleText = processedRuleText.replaceAll("([^\"])\\]([^\"])", "$1 ] $2"); // ] case 1
+				processedRuleText = processedRuleText.replaceAll("\\]([^\"])", " ] $1"); // ] case 2
+				processedRuleText = processedRuleText.replaceAll("\"\\]([^\"])", "\" ] $1"); // ] case 3
+
+				
+				String trimmedRuleText = processedRuleText.replaceAll("[\t\n\r]", " ").replaceAll("[ ]+", " ");
+				System.out.println("rule: " + trimmedRuleText);
+				
+//				System.out.println(trimmedRuleText);
+				String[] parts = trimmedRuleText.split(" ");
+				
+				for (int j=0; j <= parts.length; j++) {
+					for (int k=j; k <= parts.length; k++) {
+						if (isBalancedPairs(parts, j, k) && (k-j > 1)) {
+							String balancedSubString = createString(parts, j, k);
+							System.out.println(balancedSubString);
+						}
+
+//						combined.append(parts[k]);
+//						combined.append(" ");
+					}
+				}
+				
+				System.out.println("---------------------------------------------");
+
+				
+				
+				
+			}
+		}
+		
+		
+		
+		
+//		System.out.println("rule name: " + rule.getName());
+//		for (int i=0; i < definitionLists.size(); i++) {
+//			DefinitionList currentDefList = definitionLists.get(i);
+//			
+//			CompositeNode currentRuleDefinitionList = NodeUtil.getNodeAdapter(currentDefList).getParserNode();
+//			String currentRuleDefinitionListText = currentRuleDefinitionList.serialize().trim();
+//			String trimmedCurrentRuleDefinitionListText = currentRuleDefinitionListText.replaceAll("[ \t\n\r]", "");
+//			System.out.println(trimmedCurrentRuleDefinitionListText);
+////			System.out.println("  -> " + currentRuleDefinitionListText);
+//
+//			
+//		}
+		
+	}
+	
+	private boolean isBalancedPairs(String[] parts, int start, int end) {
+		Stack<String> pairStack = new Stack<String>();
+
+		if (start == end)
+			return false;
+		
+		if (parts[start].contains("|"))
+			return false;
+
+		if (parts[start].contains("}"))
+			return false;
+
+		if (parts[start].contains("}+"))
+			return false;
+		
+		if (parts[start].contains("]"))
+			return false;
+
+		if (parts[end-1].contains("|"))
+			return false;
+		
+		for (int i=start; i < end; i++) {
+			String currentPart = parts[i];
+			if (currentPart.equals("(") || currentPart.equals("{") || currentPart.equals("[")) {
+				pairStack.push(currentPart);
+			} 
+			
+			if (!pairStack.isEmpty()) {
+				if (currentPart.equals(")") && pairStack.peek().equals("(")) {
+					pairStack.pop();
+				} else if (currentPart.equals("}") && pairStack.peek().equals("{")) {
+					pairStack.pop();
+				} else if (currentPart.equals("}+") && pairStack.peek().equals("{")) {
+					pairStack.pop();
+				} else if (currentPart.equals("]") && pairStack.peek().equals("[")) {
+					pairStack.pop();
+				}
+			} else {
+				if (currentPart.equals(")") || currentPart.equals("}") || currentPart.equals("}+") || currentPart.equals("]")) {
+					return false;
+				}
+			}
+		}
+		
+		if (pairStack.empty())
+			return true;
+		
+		return false;
+		
+	}
+	
+	private String createString(String[] parts, int start, int end) {
+		StringBuffer result = new StringBuffer();
+		
+		for (int i=start; i < end; i++) {
+			result.append(parts[i]);
+			result.append(" ");
+		}
+		
+		return result.toString().trim();
 	}
 	
