// Path: src/main/java/com/connect_group/thymesheet/ServletContextURLFactory.java
// public interface ServletContextURLFactory {
// 	URL getURL(String filePath) throws MalformedURLException;
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/ThymesheetLocator.java
// public interface ThymesheetLocator {
// 	List<String> getThymesheetPaths(Document document);
// 	void removeThymesheetLinks(Document document);
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/ThymesheetParserPostProcessor.java
// public interface ThymesheetParserPostProcessor {
// 	void postProcess(String documentName, Document document) throws Exception;
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/ThymesheetProcessorException.java
// public class ThymesheetProcessorException extends IOException {
// 
// 	private static final long serialVersionUID = 6752946320942025461L;
// 	
// 	public ThymesheetProcessorException() {
// 		super();
// 	}
// 	
// 	public ThymesheetProcessorException(String message) {
// 		super(message);
// 	}
// 	
// 	public ThymesheetProcessorException(String message, Throwable t) {
// 		super(message, t);
// 	}
// 	
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/css/selectors/NodeSelectorException.java
// public class NodeSelectorException extends Exception {
// 
//     /** Serial version UID. */
//     private static final long serialVersionUID = -3786197030095043071L;
// 
//     /**
//      * Constructs a new exception with the specified detail message and cause.
//      *
//      * @param message The detail message.
//      * @param cause The cause.
//      */
//     public NodeSelectorException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     /**
//      * Constructs a new exception with the specified detail message.
//      *
//      * @param message The detail message.
//      */
//     public NodeSelectorException(String message) {
//         super(message);
//     }
// 
//     /**
//      * Constructs a new exception with the specified cause and a detail
//      *
//      * @param cause The cause.
//      */
//     public NodeSelectorException(Throwable cause) {
//         super(cause);
//     }
//     
// }


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.SequenceInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.steadystate.css.util.ThrowCssExceptionErrorHandler;
import org.thymeleaf.dom.Document;
import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleSheet;
import com.connect_group.thymesheet.ServletContextURLFactory;
import com.connect_group.thymesheet.ThymesheetLocator;
import com.connect_group.thymesheet.ThymesheetParserPostProcessor;
import com.connect_group.thymesheet.ThymesheetProcessorException;
import com.connect_group.thymesheet.css.selectors.NodeSelectorException;
import com.steadystate.css.parser.CSSOMParser;
import com.steadystate.css.parser.SACParserCSS3;
	protected PseudoClass getDOMModifier(String selectorText) {
		
		PseudoClass pseudoClass = PseudoClass.lastPseudoClassFromSelector(selectorText);
		if(ElementRuleFactory.isDOMModifierPsuedoElement(pseudoClass.getName())) {
			return pseudoClass;
		}
		return null;
	}
	
	AttributeRuleList getRuleList(InputStream stream) throws IOException {
		InputSource source = new InputSource(new InputStreamReader(stream));
        CSSOMParser parser = new CSSOMParser(new SACParserCSS3());
        parser.setErrorHandler(ThrowCssExceptionErrorHandler.INSTANCE);
        CSSStyleSheet stylesheet = parser.parseStyleSheet(source, null, null);
        CSSRuleList ruleList = stylesheet.getCssRules();
        
        return new AttributeRuleList(ruleList);
	}

	protected InputStream getInputStream(List<String> filePaths) throws IOException {
		List<InputStream> opened = new ArrayList<InputStream>(filePaths.size());
		
		try {
			openFiles(filePaths, opened);
		} catch (IOException ex) {
			closeInputStreams(opened);
			throw ex;
		}
		
		InputStream is = new SequenceInputStream(Collections.enumeration(opened));
// Path: src/main/java/com/connect_group/thymesheet/ServletContextURLFactory.java
// public interface ServletContextURLFactory {
// 	URL getURL(String filePath) throws MalformedURLException;
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/ThymesheetLocator.java
// public interface ThymesheetLocator {
// 	List<String> getThymesheetPaths(Document document);
// 	void removeThymesheetLinks(Document document);
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/ThymesheetParserPostProcessor.java
// public interface ThymesheetParserPostProcessor {
// 	void postProcess(String documentName, Document document) throws Exception;
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/ThymesheetProcessorException.java
// public class ThymesheetProcessorException extends IOException {
// 
// 	private static final long serialVersionUID = 6752946320942025461L;
// 	
// 	public ThymesheetProcessorException() {
// 		super();
// 	}
// 	
// 	public ThymesheetProcessorException(String message) {
// 		super(message);
// 	}
// 	
// 	public ThymesheetProcessorException(String message, Throwable t) {
// 		super(message, t);
// 	}
// 	
// }
// 
// Path: src/main/java/com/connect_group/thymesheet/css/selectors/NodeSelectorException.java
// public class NodeSelectorException extends Exception {
// 
//     /** Serial version UID. */
//     private static final long serialVersionUID = -3786197030095043071L;
// 
//     /**
//      * Constructs a new exception with the specified detail message and cause.
//      *
//      * @param message The detail message.
//      * @param cause The cause.
//      */
//     public NodeSelectorException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     /**
//      * Constructs a new exception with the specified detail message.
//      *
//      * @param message The detail message.
//      */
//     public NodeSelectorException(String message) {
//         super(message);
//     }
// 
//     /**
//      * Constructs a new exception with the specified cause and a detail
//      *
//      * @param cause The cause.
//      */
//     public NodeSelectorException(Throwable cause) {
//         super(cause);
//     }
//     
// }


// Path: src/main/java/com/connect_group/thymesheet/impl/ThymesheetPreprocessor.java
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.SequenceInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.steadystate.css.util.ThrowCssExceptionErrorHandler;
import org.thymeleaf.dom.Document;
import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleSheet;
import com.connect_group.thymesheet.ServletContextURLFactory;
import com.connect_group.thymesheet.ThymesheetLocator;
import com.connect_group.thymesheet.ThymesheetParserPostProcessor;
import com.connect_group.thymesheet.ThymesheetProcessorException;
import com.connect_group.thymesheet.css.selectors.NodeSelectorException;
import com.steadystate.css.parser.CSSOMParser;
import com.steadystate.css.parser.SACParserCSS3;

	protected PseudoClass getDOMModifier(String selectorText) {
		
		PseudoClass pseudoClass = PseudoClass.lastPseudoClassFromSelector(selectorText);
		if(ElementRuleFactory.isDOMModifierPsuedoElement(pseudoClass.getName())) {
			return pseudoClass;
		}
		return null;
	}
	
	AttributeRuleList getRuleList(InputStream stream) throws IOException {
		InputSource source = new InputSource(new InputStreamReader(stream));
        CSSOMParser parser = new CSSOMParser(new SACParserCSS3());
        parser.setErrorHandler(ThrowCssExceptionErrorHandler.INSTANCE);
        CSSStyleSheet stylesheet = parser.parseStyleSheet(source, null, null);
        CSSRuleList ruleList = stylesheet.getCssRules();
        
        return new AttributeRuleList(ruleList);
	}

	protected InputStream getInputStream(List<String> filePaths) throws IOException {
		List<InputStream> opened = new ArrayList<InputStream>(filePaths.size());
		
		try {
			openFiles(filePaths, opened);
		} catch (IOException ex) {
			closeInputStreams(opened);
			throw ex;
		}
		
		InputStream is = new SequenceInputStream(Collections.enumeration(opened));
		return is;