[maven-scm] copy for tag tobago-1.0.30
diff --git a/core/src/main/java/org/apache/myfaces/tobago/config/ThemeConfig.java b/core/src/main/java/org/apache/myfaces/tobago/config/ThemeConfig.java
index 39bc5d7..be54ad5 100644
--- a/core/src/main/java/org/apache/myfaces/tobago/config/ThemeConfig.java
+++ b/core/src/main/java/org/apache/myfaces/tobago/config/ThemeConfig.java
@@ -20,7 +20,6 @@
 import org.apache.commons.lang.ClassUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_IN;
 import org.apache.myfaces.tobago.component.ComponentUtil;
 import org.apache.myfaces.tobago.context.ClientProperties;
 import org.apache.myfaces.tobago.context.ResourceManager;
@@ -32,18 +31,22 @@
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
 import javax.faces.render.Renderer;
+import javax.servlet.ServletContext;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_IN;
 
 public class ThemeConfig {
 
   private static final Log LOG = LogFactory.getLog(ThemeConfig.class);
 
-  public static final String THEME_CONFIG_CACHE
-      = "org.apache.myfaces.tobago.config.ThemeConfig.CACHE";
+  public static final String THEME_CONFIG_CACHE = "org.apache.myfaces.tobago.config.ThemeConfig.CACHE";
 
-  public static int getValue(FacesContext facesContext, UIComponent component,
-      String name) {
+  private static final Integer NULL_VALUE = Integer.MIN_VALUE;
+
+  public static int getValue(FacesContext facesContext, UIComponent component, String name) {
 
     CacheKey key = new CacheKey(facesContext.getViewRoot(), component, name);
     Map<CacheKey, Integer> cache
@@ -52,9 +55,12 @@
     Integer value = cache.get(key);
     if (value == null) {
       value = createValue(facesContext, component, name);
+      if (value == null) {
+        value = NULL_VALUE;
+      }
       cache.put(key, value);
     }
-    if (value != null) {
+    if (!NULL_VALUE.equals(value)) {
       return value;
     } else {
       // todo: remove condition, is only temporary to ignore wml errors.
@@ -132,6 +138,15 @@
     return null;
   }
 
+  public static void init(ServletContext servletContext) {
+    servletContext.setAttribute(THEME_CONFIG_CACHE, new ConcurrentHashMap<CacheKey, Integer>(100, 0.75f, 1));
+  }
+
+  public static void shutdown(ServletContext servletContext) {
+    Map<CacheKey, Integer> cache = (Map<CacheKey, Integer>) servletContext.getAttribute(THEME_CONFIG_CACHE);
+    cache.clear();
+    servletContext.removeAttribute(THEME_CONFIG_CACHE);
+  }
 
   private static class CacheKey {
     private String clientProperties;
diff --git a/core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoServletContextListener.java b/core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoServletContextListener.java
index 4d9f9e2..c9a6f0d 100644
--- a/core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoServletContextListener.java
+++ b/core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoServletContextListener.java
@@ -28,7 +28,6 @@
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
-import java.util.HashMap;
 
 public class TobagoServletContextListener implements ServletContextListener {
 
@@ -37,17 +36,18 @@
 
   public void contextInitialized(ServletContextEvent event) {
 
-    if (LOG.isInfoEnabled()) {
-      LOG.info("*** contextInitialized ***");
-    }
-
     ServletContext servletContext = event.getServletContext();
 
     if (servletContext.getAttribute(TobagoConfig.TOBAGO_CONFIG) != null) {
-      LOG.warn("Tobago has been already initialized. Do nothing.");
+      LOG.warn("Tobago has been already initialized. Do nothing. "
+          + "(This may happen when there is a TobagoServletContextListener configured manually.)");
       return;
     }
 
+    if (LOG.isInfoEnabled()) {
+      LOG.info("*** contextInitialized ***");
+    }
+
     try {
 
       // tobago-config.xml
@@ -66,7 +66,7 @@
       tobagoConfig.resolveThemes();
 
       // theme config cache
-      servletContext.setAttribute(ThemeConfig.THEME_CONFIG_CACHE, new HashMap());
+      ThemeConfig.init(servletContext);
 
     } catch (Throwable e) {
       if (LOG.isFatalEnabled()) {
@@ -79,16 +79,25 @@
   }
 
   public void contextDestroyed(ServletContextEvent event) {
-    if (LOG.isInfoEnabled()) {
-      LOG.info("*** contextDestroyed ***\n--- snip ---------"
-          + "--------------------------------------------------------------");
-    }
 
     ServletContext servletContext = event.getServletContext();
 
+    if (servletContext.getAttribute(TobagoConfig.TOBAGO_CONFIG) == null) {
+      LOG.warn("Tobago is not initialized. Do nothing. "
+          + "(This may happen when there is a TobagoServletContextListener configured manually.)");
+      return;
+    }
+
+    if (LOG.isInfoEnabled()) {
+      LOG.info("*** contextDestroyed ***\n"
+          + "--- snip -----------------------------------------------------------------------");
+    }
+
     servletContext.removeAttribute(TobagoConfig.TOBAGO_CONFIG);
     ResourceManagerFactory.release(servletContext);
-    servletContext.removeAttribute(ThemeConfig.THEME_CONFIG_CACHE);
+
+    // theme config cache
+    ThemeConfig.shutdown(servletContext);
 
     LogFactory.releaseAll();
 //    LogManager.shutdown();