// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/cachetagmodifier/CacheTagModifier.java
// public interface CacheTagModifier {
// 
// 	/**
// 	 * CacheTagInterceptor that does not do anything.
// 	 * 
// 	 */
// 	CacheTagModifier NULL_CACHETAG_MODIFIER = new CacheTagModifier() {
// 		
// 		@Override
// 		public void init(ServletContext servletContext) {
// 		}
// 		
// 		@Override
// 		public void beforeLookup(CacheTag cacheTag, JspContext jspContext) {
// 		}
// 		
// 		@Override
// 		public String afterRetrieval(CacheTag cacheTag, JspContext jspContext,
// 				String content) {
// 			return content;
// 		}
// 		
// 		@Override
// 		public void destroy() {
// 		}
// 
// 		@Override
// 		public String beforeUpdate(CacheTag cacheTag, JspContext jspContext,
// 				String content) {
// 			return content;
// 		}
// 
// 	};
// 	
// 	/**
// 	 * Called once on Application startup.
// 	 * 
// 	 * @param properties
// 	 */
// 	void init(ServletContext servletContext);
// 	
// 	/**
// 	 * Called before Cache lookup.
// 	 * 
// 	 * Will be called by different threads concurrently.
// 	 */
// 	void beforeLookup(CacheTag cacheTag, JspContext jspContext);
// 	
// 	/**
// 	 * Called before updating the cache with the given content.
// 	 * 
// 	 * @param cacheTag
// 	 * @param jspContext
// 	 * @param content the content that will be stored in the cache
// 	 * @return the content to store in the cache.
// 	 */
// 	String beforeUpdate(CacheTag cacheTag, JspContext jspContext, String content);
// 	
// 	
// 	/**
// 	 * Called after retrieving content from the cache but before it's written to the output.
// 	 * 
// 	 * @param cacheTag
// 	 * @param jspContext
// 	 * @param content the content that will be sent back to the client
// 	 * @return The content to send back to the client
// 	 */
// 	String afterRetrieval(CacheTag cacheTag, JspContext jspContext, String content);
// 
// 	/**
// 	 * Called on Application shutdown.
// 	 */
// 	void destroy();
// }
// 
// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/cachetagmodifier/CacheTagModifierFactory.java
// public interface CacheTagModifierFactory {
// 
// 	/**
// 	 * Called once after application is initialized.
// 	 * 
// 	 * @param servletContext
// 	 */
// 	void init(ServletContext servletContext);
// 
// 	/**
// 	 * The names of the available cacheTagModifiers
// 	 * 
// 	 * @return The names of the available cacheTagModifiers
// 	 */
// 	Collection<String> getCacheTagModifierNames();
// 
// 	/**
// 	 * Gets the cacheTagModifier with the given name, null if not found.
// 	 * 
// 	 * @param cacheTagModifierName name of the CacheTagModifier we're looking for.
// 	 * 
// 	 * @return the CacheTagModifier with the given name, null if not found.
// 	 */
// 	CacheTagModifier getCacheTagModifier(String cacheTagModifierName);
// 
// 	/**
// 	 * Called once on application destroy.
// 	 * 
// 	 */
// 	void destroy();
// }
// 
// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/util/StringUtil.java
// public class StringUtil {
// 
// 	/**
// 	 * Finds and returns the string from the alternatives that closest matches the input string based on the Levenshtein distance.
// 	 * 
// 	 * @see <a href="http://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance</a>
// 	 * 
// 	 * @param input
// 	 * @param alternatives
// 	 * @return the string from the alternatives that closest matches the input string based on the Levenshtein distance.
// 	 */
// 	public static String getClosestMatchingString(String input, Collection<String> alternatives) {
// 		if (input == null || alternatives == null || alternatives.isEmpty()) {
// 			return null;
// 		}
// 		String current = null;
// 		int minDistance = Integer.MAX_VALUE;
// 		for (String alternative: alternatives) {
// 			int currentDistance = StringUtils.getLevenshteinDistance(input, alternative);
// 			if ((current == null) || (currentDistance < minDistance)) {
// 				current = alternative;
// 				minDistance = currentDistance;
// 			}
// 		}
// 		return current;
// 	}
// 
// }


import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import nl.siegmann.ehcachetag.cachetagmodifier.CacheTagModifier;
import nl.siegmann.ehcachetag.cachetagmodifier.CacheTagModifierFactory;
import nl.siegmann.ehcachetag.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
			
			// set cacheKey to null so that the endTag knows
			// it does not have to store anything in the cache
			key = null;
			
			result = BodyTagSupport.SKIP_BODY;
		}
		return result;
	}

	/**
	 * Internal exception that is used in case a modifier is search for but not found.
	 * 
	 * @author paul
	 *
	 */
	static final class ModifierNotFoundException extends Exception {

		private static final long serialVersionUID = 4535024464306691589L;

		public ModifierNotFoundException(String message) {
			super(message);
		}
	}
	
	/**
	 * This method is called before doing a lookup in the cache.
	 * Invoke the cacheTagInterceptor.beforeLookup.
	 */
	void doBeforeLookup() throws Exception {
// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/cachetagmodifier/CacheTagModifier.java
// public interface CacheTagModifier {
// 
// 	/**
// 	 * CacheTagInterceptor that does not do anything.
// 	 * 
// 	 */
// 	CacheTagModifier NULL_CACHETAG_MODIFIER = new CacheTagModifier() {
// 		
// 		@Override
// 		public void init(ServletContext servletContext) {
// 		}
// 		
// 		@Override
// 		public void beforeLookup(CacheTag cacheTag, JspContext jspContext) {
// 		}
// 		
// 		@Override
// 		public String afterRetrieval(CacheTag cacheTag, JspContext jspContext,
// 				String content) {
// 			return content;
// 		}
// 		
// 		@Override
// 		public void destroy() {
// 		}
// 
// 		@Override
// 		public String beforeUpdate(CacheTag cacheTag, JspContext jspContext,
// 				String content) {
// 			return content;
// 		}
// 
// 	};
// 	
// 	/**
// 	 * Called once on Application startup.
// 	 * 
// 	 * @param properties
// 	 */
// 	void init(ServletContext servletContext);
// 	
// 	/**
// 	 * Called before Cache lookup.
// 	 * 
// 	 * Will be called by different threads concurrently.
// 	 */
// 	void beforeLookup(CacheTag cacheTag, JspContext jspContext);
// 	
// 	/**
// 	 * Called before updating the cache with the given content.
// 	 * 
// 	 * @param cacheTag
// 	 * @param jspContext
// 	 * @param content the content that will be stored in the cache
// 	 * @return the content to store in the cache.
// 	 */
// 	String beforeUpdate(CacheTag cacheTag, JspContext jspContext, String content);
// 	
// 	
// 	/**
// 	 * Called after retrieving content from the cache but before it's written to the output.
// 	 * 
// 	 * @param cacheTag
// 	 * @param jspContext
// 	 * @param content the content that will be sent back to the client
// 	 * @return The content to send back to the client
// 	 */
// 	String afterRetrieval(CacheTag cacheTag, JspContext jspContext, String content);
// 
// 	/**
// 	 * Called on Application shutdown.
// 	 */
// 	void destroy();
// }
// 
// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/cachetagmodifier/CacheTagModifierFactory.java
// public interface CacheTagModifierFactory {
// 
// 	/**
// 	 * Called once after application is initialized.
// 	 * 
// 	 * @param servletContext
// 	 */
// 	void init(ServletContext servletContext);
// 
// 	/**
// 	 * The names of the available cacheTagModifiers
// 	 * 
// 	 * @return The names of the available cacheTagModifiers
// 	 */
// 	Collection<String> getCacheTagModifierNames();
// 
// 	/**
// 	 * Gets the cacheTagModifier with the given name, null if not found.
// 	 * 
// 	 * @param cacheTagModifierName name of the CacheTagModifier we're looking for.
// 	 * 
// 	 * @return the CacheTagModifier with the given name, null if not found.
// 	 */
// 	CacheTagModifier getCacheTagModifier(String cacheTagModifierName);
// 
// 	/**
// 	 * Called once on application destroy.
// 	 * 
// 	 */
// 	void destroy();
// }
// 
// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/util/StringUtil.java
// public class StringUtil {
// 
// 	/**
// 	 * Finds and returns the string from the alternatives that closest matches the input string based on the Levenshtein distance.
// 	 * 
// 	 * @see <a href="http://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance</a>
// 	 * 
// 	 * @param input
// 	 * @param alternatives
// 	 * @return the string from the alternatives that closest matches the input string based on the Levenshtein distance.
// 	 */
// 	public static String getClosestMatchingString(String input, Collection<String> alternatives) {
// 		if (input == null || alternatives == null || alternatives.isEmpty()) {
// 			return null;
// 		}
// 		String current = null;
// 		int minDistance = Integer.MAX_VALUE;
// 		for (String alternative: alternatives) {
// 			int currentDistance = StringUtils.getLevenshteinDistance(input, alternative);
// 			if ((current == null) || (currentDistance < minDistance)) {
// 				current = alternative;
// 				minDistance = currentDistance;
// 			}
// 		}
// 		return current;
// 	}
// 
// }


// Path: ehcachetag/src/main/java/nl/siegmann/ehcachetag/CacheTag.java
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import nl.siegmann.ehcachetag.cachetagmodifier.CacheTagModifier;
import nl.siegmann.ehcachetag.cachetagmodifier.CacheTagModifierFactory;
import nl.siegmann.ehcachetag.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

			
			// set cacheKey to null so that the endTag knows
			// it does not have to store anything in the cache
			key = null;
			
			result = BodyTagSupport.SKIP_BODY;
		}
		return result;
	}

	/**
	 * Internal exception that is used in case a modifier is search for but not found.
	 * 
	 * @author paul
	 *
	 */
	static final class ModifierNotFoundException extends Exception {

		private static final long serialVersionUID = 4535024464306691589L;

		public ModifierNotFoundException(String message) {
			super(message);
		}
	}
	
	/**
	 * This method is called before doing a lookup in the cache.
	 * Invoke the cacheTagInterceptor.beforeLookup.
	 */
	void doBeforeLookup() throws Exception {
		CacheTagModifierFactory cacheTagModifierFactory = getCacheTagModifierFactory();