[406262] [xsl][validation] StackOverflow when checking for circular
includes on next level import
diff --git a/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF
index 3b5ed4f..5abf2bd 100644
--- a/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name.0
 Bundle-SymbolicName: org.eclipse.wst.xsl.core;singleton:=true
-Bundle-Version: 1.1.300.qualifier
+Bundle-Version: 1.1.301.qualifier
 Bundle-Activator: org.eclipse.wst.xsl.core.internal.XSLCorePlugin
 Require-Bundle: org.apache.xalan;bundle-version="[2.7.1,2.8.0)",
  org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
diff --git a/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java b/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java
index 339301e..098ad9d 100644
--- a/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java
+++ b/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java
@@ -16,6 +16,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.Stack;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.wst.xsl.core.XSLCore;
@@ -195,6 +196,7 @@
 		for (Import inc : stylesheet.getImports()) {
 			handleInclude(inc);
 		}
+		circularReference = checkCycles();
 		if (Debug.debugXSLModel) {
 			long end = System.currentTimeMillis();
 			System.out
@@ -202,6 +204,36 @@
 		}
 	}
 
+	private boolean checkCycles() {
+		Set<IFile> seen = new HashSet<IFile>();
+		IFile mainFile = getStylesheet().getFile();
+		if (checkCycles(mainFile, seen)) return true;
+
+		// For the remaining files, assume 
+		seen.add(mainFile);
+		for (IFile file : files) {
+			if (file.equals(mainFile)) continue;
+			if (checkCycles(file, seen)) return true;
+		}
+		return false;
+	}
+	
+	public static boolean checkCycles(IFile included, Set<IFile> seen) {
+		if (seen.contains(included)) return true;
+		seen.add(included);
+		
+		StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
+				included);
+
+		for (Include inc : includedModel.getIncludes()) {
+			IFile includedFile = inc.getHrefAsFile();
+			if (checkCycles(includedFile, seen)) return true;
+		}
+
+		seen.remove(included);
+		return false;
+	}
+	
 	private void handleInclude(Include include) {
 		IFile file = include.getHrefAsFile();
 
@@ -209,12 +241,6 @@
 			return;
 		}
 
-		if (stylesheet.getFile().equals(file) || files.contains(file)) {
-			circularReference = true;
-			return;
-		} else if (isNestedInclude(include, stylesheet.getFile())) {
-			circularReference = true;
-		}
 		files.add(file);
 
 		StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
@@ -239,26 +265,6 @@
 		}
 	}
 
-	/**
-	 * Is the current stylesheet nested in one of the included stylesheets
-	 * 
-	 * @return
-	 */
-	private boolean isNestedInclude(Include include, IFile compareTo) {
-		StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
-				include.getHrefAsFile());
-
-		for (Include inc : includedModel.getIncludes()) {
-			if (inc.getHrefAsFile().equals(compareTo)
-					|| isNestedInclude(inc, compareTo)) {
-				return true;
-			}
-		}
-
-		return false;
-
-	}
-
 	@Override
 	public Type getModelType() {
 		return Type.STYLESHEET_MODEL;