]> source.dussan.org Git - vaadin-framework.git/commitdiff
Widgetset extension changes, reservr example
authorMarc Englund <marc.englund@itmill.com>
Tue, 18 Sep 2007 14:31:18 +0000 (14:31 +0000)
committerMarc Englund <marc.englund@itmill.com>
Tue, 18 Sep 2007 14:31:18 +0000 (14:31 +0000)
svn changeset:2312/svn branch:trunk

src/com/itmill/toolkit/demo/reservation/GoogleMap.java [new file with mode: 0644]
src/com/itmill/toolkit/demo/reservation/ReservationApplication.java
src/com/itmill/toolkit/demo/reservation/gwt/WidgetSet.gwt.xml
src/com/itmill/toolkit/terminal/gwt/DefaultWidgetSet.gwt.xml [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/WidgetSet.gwt.xml [deleted file]
src/com/itmill/toolkit/terminal/gwt/WidgetSetNoEntry.gwt.xml [deleted file]
src/com/itmill/toolkit/terminal/gwt/public/component-themes/button/css/button.css [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/public/component-themes/collection.css
src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java

diff --git a/src/com/itmill/toolkit/demo/reservation/GoogleMap.java b/src/com/itmill/toolkit/demo/reservation/GoogleMap.java
new file mode 100644 (file)
index 0000000..68402a4
--- /dev/null
@@ -0,0 +1,215 @@
+package com.itmill.toolkit.demo.reservation;\r
+\r
+import java.awt.geom.Point2D;\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+\r
+import com.itmill.toolkit.data.Container;\r
+import com.itmill.toolkit.data.Item;\r
+import com.itmill.toolkit.data.Property;\r
+import com.itmill.toolkit.data.util.IndexedContainer;\r
+import com.itmill.toolkit.terminal.PaintException;\r
+import com.itmill.toolkit.terminal.PaintTarget;\r
+import com.itmill.toolkit.terminal.Sizeable;\r
+import com.itmill.toolkit.ui.AbstractComponent;\r
+\r
+public class GoogleMap extends AbstractComponent implements Sizeable,\r
+       Container.Viewer {\r
+    private String TAG_MARKERS = "markers";\r
+    private String TAG_MARKER = "marker";\r
+    private int width = 400;\r
+    private int height = 300;\r
+    private int zoomLevel = 15;\r
+    private Point2D.Float mapCenter;\r
+\r
+    private Container dataSource;\r
+    private Object itemMarkerHtmlPropertyId = new Object();\r
+    private Object itemMarkerXPropertyId = new Object();\r
+    private Object itemMarkerYPropertyId = new Object();\r
+\r
+    public String getTag() {\r
+       return "googlemap";\r
+    }\r
+\r
+    public void paintContent(PaintTarget target) throws PaintException {\r
+       super.paintContent(target);\r
+       if (null != mapCenter) {\r
+           target.addAttribute("centerX", mapCenter.getX());\r
+           target.addAttribute("centerY", mapCenter.getY());\r
+       }\r
+       target.addAttribute("zoom", zoomLevel);\r
+       target.addAttribute("width", width);\r
+       target.addAttribute("height", height);\r
+\r
+       if (this.dataSource != null) {\r
+           target.startTag(TAG_MARKERS);\r
+           Collection itemIds = this.dataSource.getItemIds();\r
+           for (Iterator it = itemIds.iterator(); it.hasNext();) {\r
+               Object itemId = it.next();\r
+               Item item = this.dataSource.getItem(itemId);\r
+               Property p = item.getItemProperty(getItemMarkerXPropertyId());\r
+               Float x = (Float) (p != null ? p.getValue() : null);\r
+               p = item.getItemProperty(getItemMarkerYPropertyId());\r
+               Float y = (Float) (p != null ? p.getValue() : null);\r
+               if (x == null || y == null) {\r
+                   continue;\r
+               }\r
+               target.startTag(TAG_MARKER);\r
+               target.addAttribute("x", x.floatValue());\r
+               target.addAttribute("y", y.floatValue());\r
+               p = item.getItemProperty(getItemMarkerHtmlPropertyId());\r
+               String h = (String) (p != null ? p.getValue() : null);\r
+               target.addAttribute("html", h);\r
+               target.endTag(TAG_MARKER);\r
+           }\r
+           target.endTag(TAG_MARKERS);\r
+       }\r
+    }\r
+\r
+    public void setZoomLevel(int zoomLevel) {\r
+       this.zoomLevel = zoomLevel;\r
+       requestRepaint();\r
+    }\r
+\r
+    public int getZoomLevel() {\r
+       return this.zoomLevel;\r
+    }\r
+\r
+    // Sizeable methods:\r
+\r
+    public int getHeight() {\r
+       return this.height;\r
+    }\r
+\r
+    public int getHeightUnits() {\r
+       return Sizeable.UNITS_PIXELS;\r
+    }\r
+\r
+    public int getWidth() {\r
+       return this.width;\r
+    }\r
+\r
+    public int getWidthUnits() {\r
+       return Sizeable.UNITS_PIXELS;\r
+    }\r
+\r
+    public void setHeight(int height) {\r
+       this.height = height;\r
+       requestRepaint();\r
+    }\r
+\r
+    public void setHeightUnits(int units) {\r
+       throw new UnsupportedOperationException();\r
+    }\r
+\r
+    public void setWidth(int width) {\r
+       this.width = width;\r
+       requestRepaint();\r
+    }\r
+\r
+    public void setWidthUnits(int units) {\r
+       throw new UnsupportedOperationException();\r
+    }\r
+\r
+    public void setMapCenter(Point2D.Float center) {\r
+       this.mapCenter = center;\r
+    }\r
+    \r
+    public Point2D.Float getMapCenter() {\r
+       return this.mapCenter;\r
+    }\r
+    \r
+    // Container.Viewer methods:\r
+\r
+    public Container getContainerDataSource() {\r
+       return this.dataSource;\r
+    }\r
+\r
+    public void setContainerDataSource(Container newDataSource) {\r
+\r
+       this.dataSource = newDataSource;\r
+\r
+       requestRepaint();\r
+    }\r
+\r
+    // Item methods\r
+\r
+    public Object getItemMarkerHtmlPropertyId() {\r
+       return itemMarkerHtmlPropertyId;\r
+    }\r
+\r
+    public void setItemMarkerHtmlPropertyId(Object itemMarkerHtmlPropertyId) {\r
+       this.itemMarkerHtmlPropertyId = itemMarkerHtmlPropertyId;\r
+       requestRepaint();\r
+    }\r
+\r
+    public Object getItemMarkerXPropertyId() {\r
+       return itemMarkerXPropertyId;\r
+    }\r
+\r
+    public void setItemMarkerXPropertyId(Object itemMarkerXPropertyId) {\r
+       this.itemMarkerXPropertyId = itemMarkerXPropertyId;\r
+       requestRepaint();\r
+    }\r
+\r
+    public Object getItemMarkerYPropertyId() {\r
+       return itemMarkerYPropertyId;\r
+    }\r
+\r
+    public void setItemMarkerYPropertyId(Object itemMarkerYPropertyId) {\r
+       this.itemMarkerYPropertyId = itemMarkerYPropertyId;\r
+       requestRepaint();\r
+    }\r
+\r
+    // Marker add\r
+\r
+    public Object addMarker(String html, Point2D.Float location) {\r
+       if (location == null) {\r
+           throw new IllegalArgumentException("Location must be non-null");\r
+       }\r
+       if (this.dataSource == null) {\r
+           initDataSource();\r
+       }\r
+       Object markerId = this.dataSource.addItem();\r
+       if (markerId == null) {\r
+           return null;\r
+       }\r
+       Item marker = this.dataSource.getItem(markerId);\r
+       Property p = marker.getItemProperty(getItemMarkerXPropertyId());\r
+       p.setValue(new Float(location.x));\r
+       p = marker.getItemProperty(getItemMarkerYPropertyId());\r
+       p.setValue(new Float(location.y));\r
+       p = marker.getItemProperty(getItemMarkerHtmlPropertyId());\r
+       p.setValue(html);\r
+\r
+       requestRepaint();\r
+\r
+       return markerId;\r
+    }\r
+\r
+    public void removeMarker(Object markerId) {\r
+       if (this.dataSource != null) {\r
+           this.dataSource.removeItem(markerId);\r
+           requestRepaint();\r
+       }\r
+    }\r
+\r
+    public Item getMarkerItem(Object markerId) {\r
+       if (this.dataSource != null) {\r
+           return this.dataSource.getItem(markerId);\r
+       } else {\r
+           return null;\r
+       }\r
+    }\r
+\r
+    // dataSource init helper:\r
+    private void initDataSource() {\r
+       this.dataSource = new IndexedContainer();\r
+       this.dataSource.addContainerProperty(this.itemMarkerHtmlPropertyId,\r
+               String.class, null);\r
+       this.dataSource.addContainerProperty(this.itemMarkerXPropertyId,\r
+               Float.class, new Float(0));\r
+       this.dataSource.addContainerProperty(this.itemMarkerYPropertyId,\r
+               Float.class, new Float(0));\r
+    }\r
+}
\ No newline at end of file
index 9e6363427adfebe423a15fd3224a5688038f9d8f..42ebd7d74c5290fd4b541e08f537e818984f5824 100644 (file)
@@ -1,5 +1,6 @@
 package com.itmill.toolkit.demo.reservation;\r
 \r
+import java.awt.Point;\r
 import java.util.Date;\r
 import java.util.Iterator;\r
 import java.util.List;\r
@@ -44,7 +45,7 @@ public class ReservationApplication extends Application {
 \r
        Window mainWindow = new Window("Reservr");\r
        setMainWindow(mainWindow);\r
-       setTheme("example");\r
+       setTheme("reservr");\r
 \r
        TabSheet mainTabs = new TabSheet();\r
        mainWindow.addComponent(mainTabs);\r
@@ -79,7 +80,18 @@ public class ReservationApplication extends Application {
        infoLayout.addComponent(reservationButton);\r
        statusLabel = new Label();\r
        infoLayout.addComponent(statusLabel);\r
-\r
+       \r
+       // TODO map\r
+       GoogleMap map = new GoogleMap();\r
+       map.setWidth(290);\r
+       map.setHeight(150);\r
+       map.setZoomLevel(2);\r
+       //map.setMapCenter(new Point.Float(60.453380f, 22.301850f));\r
+       infoLayout.addComponent(map);\r
+       \r
+       map.addMarker("IT Mill", new Point.Float(60.453380f, 22.301850f));\r
+       map.addMarker("Romson a.k.a Rodskar", new Point.Float(63.509433f,22.276711f));\r
+       \r
        // TODO Use calendar, set following hour\r
        Date now = new Date();\r
        reservedFrom = new CalendarField();\r
index 2a360b617969e0a71ab69bd57f82b6d3a69da8eb..bcff23a08781284bc2830da201402d7e47ad8d9e 100644 (file)
@@ -1,6 +1,6 @@
 <module>
 \r
-       <inherits name="com.itmill.toolkit.terminal.gwt.WidgetSetNoEntry" /> \r
+       <inherits name="com.itmill.toolkit.terminal.gwt.DefaultWidgetSetNoEntry" /> \r
        \r
        <inherits name='com.mapitz.gwt.googleMaps.GoogleMaps' /> 
        
diff --git a/src/com/itmill/toolkit/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/itmill/toolkit/terminal/gwt/DefaultWidgetSet.gwt.xml
new file mode 100644 (file)
index 0000000..30ead61
--- /dev/null
@@ -0,0 +1,7 @@
+<module>
+       <source path="client"/>\r
+
+       <inherits name="com.itmill.toolkit.terminal.gwt.DefaultWidgetSetNoEntry"/>
+
+       <entry-point class="com.itmill.toolkit.terminal.gwt.client.DefaultWidgetSet"/>
+</module>
diff --git a/src/com/itmill/toolkit/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml b/src/com/itmill/toolkit/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml
new file mode 100644 (file)
index 0000000..8c1c5f4
--- /dev/null
@@ -0,0 +1,19 @@
+<module>
+
+       <inherits name="com.google.gwt.user.User"/>
+
+       <inherits name="com.google.gwt.http.HTTP"/>
+
+       <inherits name="com.google.gwt.xml.XML"/>
+
+       <inherits name="com.google.gwt.json.JSON"/>\r
+
+       <source path="client"/>
+       
+       <source path="gwtwidgets"/>
+       
+       <!-- Component stylesheets                                -->
+       
+       <stylesheet src="component-themes/collection.css"/>
+
+</module>
diff --git a/src/com/itmill/toolkit/terminal/gwt/WidgetSet.gwt.xml b/src/com/itmill/toolkit/terminal/gwt/WidgetSet.gwt.xml
deleted file mode 100644 (file)
index a5d027b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<module>
-       <source path="client"/>\r
-
-       <inherits name="com.itmill.toolkit.terminal.gwt.WidgetSetNoEntry"/>
-
-       <entry-point class="com.itmill.toolkit.terminal.gwt.client.DefaultWidgetSet"/>
-</module>
diff --git a/src/com/itmill/toolkit/terminal/gwt/WidgetSetNoEntry.gwt.xml b/src/com/itmill/toolkit/terminal/gwt/WidgetSetNoEntry.gwt.xml
deleted file mode 100644 (file)
index 62b1618..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<module>
-
-       <inherits name="com.google.gwt.user.User"/>
-
-       <inherits name="com.google.gwt.http.HTTP"/>
-
-       <inherits name="com.google.gwt.xml.XML"/>
-
-       <inherits name="com.google.gwt.json.JSON"/>\r
-
-       <source path="client"/>
-       
-       <source path="gwtwidgets"/>
-       
-       <!-- Component stylesheets                                -->
-       
-       <stylesheet src="component-themes/collection.css"/>
-
-
-</module>
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/button/css/button.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/button/css/button.css
new file mode 100644 (file)
index 0000000..9bc7b86
--- /dev/null
@@ -0,0 +1,9 @@
+button {\r
+       cursor: pointer;\r
+}\r
+button.link {\r
+       border: 0px;\r
+       text-align: left;\r
+       text-decoration: underline;\r
+       background: none;\r
+}\r
index f3145a8b7d388175eff33863f83a4d7ad8b41540..28e8abb3e2fc6e94acf8940676e58513a2b5d5df 100644 (file)
@@ -1,4 +1,5 @@
 @import "common/css/common.css";\r
+@import "button/css/button.css";\r
 @import "textfield/css/textfield.css";\r
 @import "select/css/select.css";\r
 @import "panel/css/panel.css";\r
index cd76d4c1e7755f5fc66649eee93f64c4ce8c9d37..7ad8a3258f9d28a82a03079a025cd3573be4fa35 100644 (file)
@@ -68,7 +68,7 @@ import com.itmill.toolkit.terminal.URIHandler;
 import com.itmill.toolkit.ui.Window;
 
 /**
- * This servlet connects IT Mill Toolkit Application to Web. 
+ * This servlet connects IT Mill Toolkit Application to Web.
  * 
  * @author IT Mill Ltd.
  * @version
@@ -78,1086 +78,1108 @@ import com.itmill.toolkit.ui.Window;
 
 public class ApplicationServlet extends HttpServlet {
 
-       private static final long serialVersionUID = -4937882979845826574L;
+    private static final long serialVersionUID = -4937882979845826574L;
 
-       /**
-        * Version number of this release. For example "4.0.0".
-        */
-       public static final String VERSION;
-
-       /**
-        * Major version number. For example 4 in 4.1.0.
-        */
-       public static final int VERSION_MAJOR;
+    /**
+     * Version number of this release. For example "4.0.0".
+     */
+    public static final String VERSION;
 
-       /**
-        * Minor version number. For example 1 in 4.1.0.
-        */
-       public static final int VERSION_MINOR;
+    /**
+     * Major version number. For example 4 in 4.1.0.
+     */
+    public static final int VERSION_MAJOR;
 
-       /**
-        * Builds number. For example 0-beta1 in 4.0.0-beta1.
-        */
-       public static final String VERSION_BUILD;
-
-       /* Initialize version numbers from string replaced by build-script. */
-       static {
-               if ("@VERSION@".equals("@" + "VERSION" + "@"))
-                       VERSION = "4.9.9-INTERNAL-NONVERSIONED-DEBUG-BUILD";
-               else
-                       VERSION = "@VERSION@";
-               String[] digits = VERSION.split("\\.");
-               VERSION_MAJOR = Integer.parseInt(digits[0]);
-               VERSION_MINOR = Integer.parseInt(digits[1]);
-               VERSION_BUILD = digits[2];
-       }
+    /**
+     * Minor version number. For example 1 in 4.1.0.
+     */
+    public static final int VERSION_MINOR;
 
-       // Configurable parameter names
-       private static final String PARAMETER_DEBUG = "Debug";
+    /**
+     * Builds number. For example 0-beta1 in 4.0.0-beta1.
+     */
+    public static final String VERSION_BUILD;
 
-       private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
+    /* Initialize version numbers from string replaced by build-script. */
+    static {
+       if ("@VERSION@".equals("@" + "VERSION" + "@"))
+           VERSION = "4.9.9-INTERNAL-NONVERSIONED-DEBUG-BUILD";
+       else
+           VERSION = "@VERSION@";
+       String[] digits = VERSION.split("\\.");
+       VERSION_MAJOR = Integer.parseInt(digits[0]);
+       VERSION_MINOR = Integer.parseInt(digits[1]);
+       VERSION_BUILD = digits[2];
+    }
 
-       private static final int MAX_BUFFER_SIZE = 64 * 1024;
+    // Configurable parameter names
+    private static final String PARAMETER_DEBUG = "Debug";
 
-       private static WeakHashMap applicationToLastRequestDate = new WeakHashMap();
+    private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
 
-       private static WeakHashMap applicationToAjaxAppMgrMap = new WeakHashMap();
+    private static final int MAX_BUFFER_SIZE = 64 * 1024;
 
-       // License for ApplicationServlets
-       private static WeakHashMap licenseForApplicationClass = new WeakHashMap();
+    private static WeakHashMap applicationToLastRequestDate = new WeakHashMap();
 
-       private static WeakHashMap licensePrintedForApplicationClass = new WeakHashMap();
+    private static WeakHashMap applicationToAjaxAppMgrMap = new WeakHashMap();
 
-       private static final String RESOURCE_URI = "/RES/";
+    // License for ApplicationServlets
+    private static WeakHashMap licenseForApplicationClass = new WeakHashMap();
 
-       private static final String AJAX_UIDL_URI = "/UIDL/";
+    private static WeakHashMap licensePrintedForApplicationClass = new WeakHashMap();
 
-       static final String THEME_DIRECTORY_PATH = "/theme/";
+    private static final String RESOURCE_URI = "/RES/";
 
-       // Maximum delay between request for an user to be considered active (in ms)
-       private static final long ACTIVE_USER_REQUEST_INTERVAL = 1000 * 45;
-       
-       private static final int DEFAULT_THEME_CACHETIME = 1000 * 60 * 60 * 24;
+    private static final String AJAX_UIDL_URI = "/UIDL/";
 
-       // Private fields
-       private Class applicationClass;
+    static final String THEME_DIRECTORY_PATH = "/theme/";
 
-       private Properties applicationProperties;
+    // Maximum delay between request for an user to be considered active (in ms)
+    private static final long ACTIVE_USER_REQUEST_INTERVAL = 1000 * 45;
 
-       private String resourcePath = null;
+    private static final int DEFAULT_THEME_CACHETIME = 1000 * 60 * 60 * 24;
 
-       private String debugMode = "";
+    // Name of the default widget set, used if not specified in web.xml
+    private static final String DEFAULT_WIDGETSET = "com.itmill.toolkit.terminal.gwt.DefaultWidgetSet";
+    // Widget set narameter name
+    private static final String PARAMETER_WIDGETSET = "widgetset";
 
-       /**
-        * Called by the servlet container to indicate to a servlet that the servlet
-        * is being placed into service.
-        * 
-        * @param servletConfig
-        *            the object containing the servlet's configuration and
-        *            initialization parameters
-        * @throws javax.servlet.ServletException
-        *             if an exception has occurred that interferes with the
-        *             servlet's normal operation.
-        */
-       public void init(javax.servlet.ServletConfig servletConfig)
-                       throws javax.servlet.ServletException {
-               super.init(servletConfig);
-
-               // Gets the application class name
-               String applicationClassName = servletConfig
-                               .getInitParameter("application");
-               if (applicationClassName == null) {
-                       Log.error("Application not specified in servlet parameters");
-               }
+    // Private fields
+    private Class applicationClass;
 
-               // Stores the application parameters into Properties object
-               this.applicationProperties = new Properties();
-               for (Enumeration e = servletConfig.getInitParameterNames(); e
-                               .hasMoreElements();) {
-                       String name = (String) e.nextElement();
-                       this.applicationProperties.setProperty(name, servletConfig
-                                       .getInitParameter(name));
-               }
+    private Properties applicationProperties;
 
-               // Overrides with server.xml parameters
-               ServletContext context = servletConfig.getServletContext();
-               for (Enumeration e = context.getInitParameterNames(); e
-                               .hasMoreElements();) {
-                       String name = (String) e.nextElement();
-                       this.applicationProperties.setProperty(name, context
-                                       .getInitParameter(name));
-               }
+    private String resourcePath = null;
 
-               // Gets the debug window parameter
-               String debug = getApplicationOrSystemProperty(PARAMETER_DEBUG, "")
-                               .toLowerCase();
-
-               // Enables application specific debug
-               if (!"".equals(debug) && !"true".equals(debug)
-                               && !"false".equals(debug))
-                       throw new ServletException(
-                                       "If debug parameter is given for an application, it must be 'true' or 'false'");
-               this.debugMode = debug;
-
-               // Gets custom class loader
-               String classLoaderName = getApplicationOrSystemProperty(
-                               "ClassLoader", null);
-               ClassLoader classLoader;
-               if (classLoaderName == null) 
-                       classLoader = getClass().getClassLoader();
-               else {
-                       try {
-                               Class classLoaderClass = getClass().getClassLoader().loadClass(classLoaderName);
-                               Constructor c = classLoaderClass.getConstructor(new Class[] {ClassLoader.class});
-                               classLoader = (ClassLoader) c.newInstance(new Object[] {getClass().getClassLoader()});
-                       } catch (Exception e) {
-                               Log.error("Could not find specified class loader: " + classLoaderName);
-                               throw new ServletException(e);
-                       } 
-               }
+    private String debugMode = "";
 
-               // Loads the application class using the same class loader
-               // as the servlet itself
-               try {
-                       this.applicationClass = classLoader.loadClass(applicationClassName);
-               } catch (ClassNotFoundException e) {
-                       throw new ServletException("Failed to load application class: "
-                                       + applicationClassName);
-               }
+    /**
+     * Called by the servlet container to indicate to a servlet that the servlet
+     * is being placed into service.
+     * 
+     * @param servletConfig
+     *                the object containing the servlet's configuration and
+     *                initialization parameters
+     * @throws javax.servlet.ServletException
+     *                 if an exception has occurred that interferes with the
+     *                 servlet's normal operation.
+     */
+    public void init(javax.servlet.ServletConfig servletConfig)
+           throws javax.servlet.ServletException {
+       super.init(servletConfig);
 
+       // Gets the application class name
+       String applicationClassName = servletConfig
+               .getInitParameter("application");
+       if (applicationClassName == null) {
+           Log.error("Application not specified in servlet parameters");
        }
 
-       /**
-        * Gets an application or system property value.
-        * 
-        * @param parameterName
-        *            the Name or the parameter.
-        * @param defaultValue
-        *            the Default to be used.
-        * @return String value or default if not found
-        */
-       private String getApplicationOrSystemProperty(String parameterName,
-                       String defaultValue) {
-
-               // Try application properties
-               String val = this.applicationProperties.getProperty(parameterName);
-               if (val != null) {
-                       return val;
-               }
+       // Stores the application parameters into Properties object
+       this.applicationProperties = new Properties();
+       for (Enumeration e = servletConfig.getInitParameterNames(); e
+               .hasMoreElements();) {
+           String name = (String) e.nextElement();
+           this.applicationProperties.setProperty(name, servletConfig
+                   .getInitParameter(name));
+       }
 
-               // Try lowercased application properties for backward compability with
-               // 3.0.2 and earlier
-               val = this.applicationProperties.getProperty(parameterName
-                               .toLowerCase());
-               if (val != null) {
-                       return val;
-               }
+       // Overrides with server.xml parameters
+       ServletContext context = servletConfig.getServletContext();
+       for (Enumeration e = context.getInitParameterNames(); e
+               .hasMoreElements();) {
+           String name = (String) e.nextElement();
+           this.applicationProperties.setProperty(name, context
+                   .getInitParameter(name));
+       }
 
-               // Try system properties
-               String pkgName;
-               Package pkg = this.getClass().getPackage();
-               if (pkg != null) {
-                       pkgName = pkg.getName();
-               } else {
-                       String className = this.getClass().getName();
-                       pkgName = new String(className.toCharArray(), 0, className
-                                       .lastIndexOf('.'));
-               }
-               val = System.getProperty(pkgName + "." + parameterName);
-               if (val != null) {
-                       return val;
-               }
+       // Gets the debug window parameter
+       String debug = getApplicationOrSystemProperty(PARAMETER_DEBUG, "")
+               .toLowerCase();
+
+       // Enables application specific debug
+       if (!"".equals(debug) && !"true".equals(debug)
+               && !"false".equals(debug))
+           throw new ServletException(
+                   "If debug parameter is given for an application, it must be 'true' or 'false'");
+       this.debugMode = debug;
+
+       // Gets custom class loader
+       String classLoaderName = getApplicationOrSystemProperty("ClassLoader",
+               null);
+       ClassLoader classLoader;
+       if (classLoaderName == null)
+           classLoader = getClass().getClassLoader();
+       else {
+           try {
+               Class classLoaderClass = getClass().getClassLoader().loadClass(
+                       classLoaderName);
+               Constructor c = classLoaderClass
+                       .getConstructor(new Class[] { ClassLoader.class });
+               classLoader = (ClassLoader) c
+                       .newInstance(new Object[] { getClass().getClassLoader() });
+           } catch (Exception e) {
+               Log.error("Could not find specified class loader: "
+                       + classLoaderName);
+               throw new ServletException(e);
+           }
+       }
 
-               // Try lowercased system properties
-               val = System.getProperty(pkgName + "." + parameterName.toLowerCase());
-               if (val != null) {
-                       return val;
-               }
+       // Loads the application class using the same class loader
+       // as the servlet itself
+       try {
+           this.applicationClass = classLoader.loadClass(applicationClassName);
+       } catch (ClassNotFoundException e) {
+           throw new ServletException("Failed to load application class: "
+                   + applicationClassName);
+       }
 
-               return defaultValue;
+    }
+
+    /**
+     * Gets an application or system property value.
+     * 
+     * @param parameterName
+     *                the Name or the parameter.
+     * @param defaultValue
+     *                the Default to be used.
+     * @return String value or default if not found
+     */
+    private String getApplicationOrSystemProperty(String parameterName,
+           String defaultValue) {
+
+       // Try application properties
+       String val = this.applicationProperties.getProperty(parameterName);
+       if (val != null) {
+           return val;
        }
 
-       /**
-        * Receives standard HTTP requests from the public service method and
-        * dispatches them.
-        * 
-        * @param request
-        *            the object that contains the request the client made of the
-        *            servlet.
-        * @param response
-        *            the object that contains the response the servlet returns to
-        *            the client.
-        * @throws ServletException
-        *             if an input or output error occurs while the servlet is
-        *             handling the TRACE request.
-        * @throws IOException
-        *             if the request for the TRACE cannot be handled.
-        */
-       protected void service(HttpServletRequest request,
-                       HttpServletResponse response) throws ServletException, IOException {
-
-               Application application = null;
-               try {
-
-                       // Update browser details
-                       WebBrowser browser = WebApplicationContext.getApplicationContext(request.getSession()).getBrowser();
-                       browser.updateBrowserProperties(request);
-                       // TODO Add screen height and width to the GWT client
-                       
-                       // Gets the application
-                       application = getApplication(request);
-
-                       
-                       // Sets the last application request date
-                       synchronized (applicationToLastRequestDate) {
-                               applicationToLastRequestDate.put(application, new Date());
-                       }
+       // Try lowercased application properties for backward compability with
+       // 3.0.2 and earlier
+       val = this.applicationProperties.getProperty(parameterName
+               .toLowerCase());
+       if (val != null) {
+           return val;
+       }
 
-                       // Invokes context transaction listeners
-                       ((WebApplicationContext) application.getContext())
-                                       .startTransaction(application, request);
-
-                       // Is this a download request from application
-                       DownloadStream download = null;
-
-                       // The rest of the process is synchronized with the application
-                       // in order to guarantee that no parallel variable handling is
-                       // made
-                       synchronized (application) {
-
-                               // Handles AJAX UIDL requests
-                               String resourceId = request.getPathInfo();
-                               if (resourceId != null && resourceId.startsWith(AJAX_UIDL_URI)) {
-                                       getApplicationManager(application).handleUidlRequest(
-                                                       request, response);
-                                       return;
-                               }
-
-                               
-                               // Handles the URI if the application is still running
-                               if (application.isRunning())
-                                       download = handleURI(application, request, response);
-
-                               // If this is not a download request
-                               if (download == null) {
-
-                                       // TODO Clean this branch
-                                       
-                                       // Window renders are not cacheable
-                                       response.setHeader("Cache-Control", "no-cache");
-                                       response.setHeader("Pragma", "no-cache");
-                                       response.setDateHeader("Expires", 0);
-
-                                       // Finds the window within the application
-                                       Window window = null;
-                                       if (application.isRunning())
-                                               window = getApplicationWindow(request, application);
-
-                                       // Removes application if it has stopped
-                                       if (!application.isRunning()) {
-                                               endApplication(request, response, application);
-                                               return;
-                                       }
-
-                                       // Sets terminal type for the window, if not already set
-                                       if (window.getTerminal() == null) {
-                                               window.setTerminal(browser);
-                                       }
-
-                                       // Finds theme name
-                                       String themeName = window.getTheme();
-                                       if (request.getParameter("theme") != null) {
-                                               themeName = request.getParameter("theme");
-                                       }
-                                       
-                                       // Handles resource requests
-                                       if (handleResourceRequest(request, response, themeName))
-                                               return;
-
-                                               writeAjaxPage(request, response,
-                                                               window, themeName);
-                               }
-                       }
+       // Try system properties
+       String pkgName;
+       Package pkg = this.getClass().getPackage();
+       if (pkg != null) {
+           pkgName = pkg.getName();
+       } else {
+           String className = this.getClass().getName();
+           pkgName = new String(className.toCharArray(), 0, className
+                   .lastIndexOf('.'));
+       }
+       val = System.getProperty(pkgName + "." + parameterName);
+       if (val != null) {
+           return val;
+       }
 
-                       // For normal requests, transform the window
-                       if (download != null) 
+       // Try lowercased system properties
+       val = System.getProperty(pkgName + "." + parameterName.toLowerCase());
+       if (val != null) {
+           return val;
+       }
 
-                               handleDownload(download, request, response);
-               
+       return defaultValue;
+    }
+
+    /**
+     * Receives standard HTTP requests from the public service method and
+     * dispatches them.
+     * 
+     * @param request
+     *                the object that contains the request the client made of
+     *                the servlet.
+     * @param response
+     *                the object that contains the response the servlet returns
+     *                to the client.
+     * @throws ServletException
+     *                 if an input or output error occurs while the servlet is
+     *                 handling the TRACE request.
+     * @throws IOException
+     *                 if the request for the TRACE cannot be handled.
+     */
+    protected void service(HttpServletRequest request,
+           HttpServletResponse response) throws ServletException, IOException {
+
+       Application application = null;
+       try {
+
+           // Update browser details
+           WebBrowser browser = WebApplicationContext.getApplicationContext(
+                   request.getSession()).getBrowser();
+           browser.updateBrowserProperties(request);
+           // TODO Add screen height and width to the GWT client
+
+           // Gets the application
+           application = getApplication(request);
+
+           // Sets the last application request date
+           synchronized (applicationToLastRequestDate) {
+               applicationToLastRequestDate.put(application, new Date());
+           }
+
+           // Invokes context transaction listeners
+           ((WebApplicationContext) application.getContext())
+                   .startTransaction(application, request);
+
+           // Is this a download request from application
+           DownloadStream download = null;
+
+           // The rest of the process is synchronized with the application
+           // in order to guarantee that no parallel variable handling is
+           // made
+           synchronized (application) {
+
+               // Handles AJAX UIDL requests
+               String resourceId = request.getPathInfo();
+               if (resourceId != null && resourceId.startsWith(AJAX_UIDL_URI)) {
+                   getApplicationManager(application).handleUidlRequest(
+                           request, response);
+                   return;
+               }
 
+               // Handles the URI if the application is still running
+               if (application.isRunning())
+                   download = handleURI(application, request, response);
 
-               } catch (Throwable e) {
-                       // Print stacktrace
-                       e.printStackTrace();
-                       // Re-throw other exceptions
-                       throw new ServletException(e);
-               } finally {
+               // If this is not a download request
+               if (download == null) {
 
-                       // Notifies transaction end
-                       if (application != null)
-                               ((WebApplicationContext) application.getContext())
-                                               .endTransaction(application, request);
-               }
-       }
+                   // TODO Clean this branch
 
-       /**
-        * 
-        * @param request
-        *            the HTTP request.
-        * @param response
-        *            the HTTP response to write to.
-        * @param out
-        * @param unhandledParameters
-        * @param window
-        * @param terminalType
-        * @param theme
-        * @throws IOException
-        *             if the writing failed due to input/output error.
-        * @throws MalformedURLException
-        *             if the application is denied access the persistent data store
-        *             represented by the given URL.
-        */
-       private void writeAjaxPage(HttpServletRequest request,
-                       HttpServletResponse response, 
-                        Window window, String themeName) throws IOException, MalformedURLException {
-               response.setContentType("text/html");
-               BufferedWriter page = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
-               
-               String uri = request.getRequestURL().toString();
-               boolean hasSlash = (uri.charAt(uri.length()-1) == '/') ? true : false;
-               
-               String relative = "";
-               String t = request.getPathInfo().substring(1);
-               while (t.indexOf('/')>=0) {
-                       t = t.substring(t.indexOf('/')+1);
-                       relative += "../";
-               }
-               
-               
-               page
-                               .write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
-                                               + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
-               
-               page.write("<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\">\n<head>\n<title>IT Mill Toolkit 5</title>\n" +
-                               "<script type=\"text/javascript\">\n" +
-                               "       var itmtk = {\n" +
-                               "               appUri:'");
-               
-               String[] urlParts = getApplicationUrl(request).toString().split("\\/");
-               String appUrl = "";
-               // don't use server and port in uri. It may cause problems with some
-               // virtual server configurations which lose the server name
-               for (int i = 3; i < urlParts.length; i++)
-                       appUrl += "/" + urlParts[i];
-               if (appUrl.endsWith("/")) {
-                       appUrl = appUrl.substring(0, appUrl.length() - 1);
-               }
-               
-               
-               page.write(appUrl);
-               
-               page.write("', pathInfo: '"+request.getPathInfo()+"'\n};\n" +
-                               "</script>\n" +
-                               
-                               "<script src=\"http://maps.google.com/maps?file=api&amp;v=2\" type=\"text/javascript\"></script>"+
-                               
-                               "<script language='javascript' src='"+ (hasSlash ? "../" : "") + relative + "com.itmill.toolkit.demo.reservation.gwt.WidgetSet/com.itmill.toolkit.demo.reservation.gwt.WidgetSet.nocache.js'></script>" +
-
-                               "<link REL=\"stylesheet\" TYPE=\"text/css\" HREF=\""+request.getContextPath() + THEME_DIRECTORY_PATH+themeName+"/style.css\">" + 
-                               "</head>\n<body>\n" +
-                               "       <iframe id=\"__gwt_historyFrame\" style=\"width:0;height:0;border:0\"></iframe>\n" +
-                               "       <div id=\"itmtk-ajax-window\"></div>" +
-                               "       </body>\n" + 
-                               "</html>\n");
-       
-
-               page.close();
+                   // Window renders are not cacheable
+                   response.setHeader("Cache-Control", "no-cache");
+                   response.setHeader("Pragma", "no-cache");
+                   response.setDateHeader("Expires", 0);
 
-       }
+                   // Finds the window within the application
+                   Window window = null;
+                   if (application.isRunning())
+                       window = getApplicationWindow(request, application);
 
-       /**
-        * Handles the requested URI. An application can add handlers to do special
-        * processing, when a certain URI is requested. The handlers are invoked
-        * before any windows URIs are processed and if a DownloadStream is returned
-        * it is sent to the client.
-        * 
-        * @param application
-        *            the Application owning the URI.
-        * @param request
-        *            the HTTP request instance.
-        * @param response
-        *            the HTTP response to write to.
-        * @return boolean <code>true</code> if the request was handled and
-        *         further processing should be suppressed, <code>false</code>
-        *         otherwise.
-        * @see com.itmill.toolkit.terminal.URIHandler
-        */
-       private DownloadStream handleURI(Application application,
-                       HttpServletRequest request, HttpServletResponse response) {
+                   // Removes application if it has stopped
+                   if (!application.isRunning()) {
+                       endApplication(request, response, application);
+                       return;
+                   }
 
-               String uri = request.getPathInfo();
+                   // Sets terminal type for the window, if not already set
+                   if (window.getTerminal() == null) {
+                       window.setTerminal(browser);
+                   }
 
-               // If no URI is available
-               if (uri == null || uri.length() == 0 || uri.equals("/"))
-                       return null;
+                   // Finds theme name
+                   String themeName = window.getTheme();
+                   if (request.getParameter("theme") != null) {
+                       themeName = request.getParameter("theme");
+                   }
 
-               // Removes the leading /
-               while (uri.startsWith("/") && uri.length() > 0)
-                       uri = uri.substring(1);
+                   // Handles resource requests
+                   if (handleResourceRequest(request, response, themeName))
+                       return;
 
-               // Handles the uri
-               DownloadStream stream = null;
-               try {
-                       stream = application.handleURI(application.getURL(), uri);
-               } catch (Throwable t) {
-                       application.terminalError(new URIHandlerErrorImpl(application, t));
+                   writeAjaxPage(request, response, window, themeName);
                }
+           }
 
-               return stream;
-       }
+           // For normal requests, transform the window
+           if (download != null)
 
-       /**
-        * Handles the requested URI. An application can add handlers to do special
-        * processing, when a certain URI is requested. The handlers are invoked
-        * before any windows URIs are processed and if a DownloadStream is returned
-        * it is sent to the client.
-        * 
-        * @param stream
-        *            the download stream.
-        * 
-        * @param request
-        *            the HTTP request instance.
-        * @param response
-        *            the HTTP response to write to.
-        * 
-        * @see com.itmill.toolkit.terminal.URIHandler
-        */
-       private void handleDownload(DownloadStream stream,
-                       HttpServletRequest request, HttpServletResponse response) {
-
-               // Download from given stream
-               InputStream data = stream.getStream();
-               if (data != null) {
-
-                       // Sets content type
-                       response.setContentType(stream.getContentType());
-
-                       // Sets cache headers
-                       long cacheTime = stream.getCacheTime();
-                       if (cacheTime <= 0) {
-                               response.setHeader("Cache-Control", "no-cache");
-                               response.setHeader("Pragma", "no-cache");
-                               response.setDateHeader("Expires", 0);
-                       } else {
-                               response.setHeader("Cache-Control", "max-age=" + cacheTime
-                                               / 1000);
-                               response.setDateHeader("Expires", System.currentTimeMillis()
-                                               + cacheTime);
-                               response.setHeader("Pragma", "cache"); // Required to apply
-                               // caching in some
-                               // Tomcats
-                       }
+               handleDownload(download, request, response);
 
-                       // Copy download stream parameters directly
-                       // to HTTP headers.
-                       Iterator i = stream.getParameterNames();
-                       if (i != null) {
-                               while (i.hasNext()) {
-                                       String param = (String) i.next();
-                                       response.setHeader((String) param, stream
-                                                       .getParameter(param));
-                               }
-                       }
+       } catch (Throwable e) {
+           // Print stacktrace
+           e.printStackTrace();
+           // Re-throw other exceptions
+           throw new ServletException(e);
+       } finally {
 
-                       int bufferSize = stream.getBufferSize();
-                       if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE)
-                               bufferSize = DEFAULT_BUFFER_SIZE;
-                       byte[] buffer = new byte[bufferSize];
-                       int bytesRead = 0;
-
-                       try {
-                               OutputStream out = response.getOutputStream();
-
-                               while ((bytesRead = data.read(buffer)) > 0) {
-                                       out.write(buffer, 0, bytesRead);
-                                       out.flush();
-                               }
-                               out.close();
-                       } catch (IOException ignored) {
-                       }
+           // Notifies transaction end
+           if (application != null)
+               ((WebApplicationContext) application.getContext())
+                       .endTransaction(application, request);
+       }
+    }
+
+    /**
+     * 
+     * @param request
+     *                the HTTP request.
+     * @param response
+     *                the HTTP response to write to.
+     * @param out
+     * @param unhandledParameters
+     * @param window
+     * @param terminalType
+     * @param theme
+     * @throws IOException
+     *                 if the writing failed due to input/output error.
+     * @throws MalformedURLException
+     *                 if the application is denied access the persistent data
+     *                 store represented by the given URL.
+     */
+    private void writeAjaxPage(HttpServletRequest request,
+           HttpServletResponse response, Window window, String themeName)
+           throws IOException, MalformedURLException {
+       response.setContentType("text/html");
+       BufferedWriter page = new BufferedWriter(new OutputStreamWriter(
+               response.getOutputStream()));
+
+       String uri = request.getRequestURL().toString();
+       boolean hasSlash = (uri.charAt(uri.length() - 1) == '/') ? true : false;
+
+       String relative = "";
+       String t = request.getPathInfo().substring(1);
+       while (t.indexOf('/') >= 0) {
+           t = t.substring(t.indexOf('/') + 1);
+           relative += "../";
+       }
 
-               }
+       // TODO remove GoogleMaps namespace and script
+
+       page
+               .write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
+                       + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
+
+       page
+               .write("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<title>IT Mill Toolkit 5</title>\n"
+                       + "<script type=\"text/javascript\">\n"
+                       + "     var itmtk = {\n" + "            appUri:'");
+
+       String[] urlParts = getApplicationUrl(request).toString().split("\\/");
+       String appUrl = "";
+       // don't use server and port in uri. It may cause problems with some
+       // virtual server configurations which lose the server name
+       for (int i = 3; i < urlParts.length; i++)
+           appUrl += "/" + urlParts[i];
+       if (appUrl.endsWith("/")) {
+           appUrl = appUrl.substring(0, appUrl.length() - 1);
+       }
+
+       page.write(appUrl);
 
+       String widgetset = this.applicationProperties
+               .getProperty(PARAMETER_WIDGETSET);
+       if (widgetset == null) {
+           widgetset = DEFAULT_WIDGETSET;
        }
-       
-       /**
-        * Handles theme resource file requests. Resources supplied with the themes
-        * are provided by the WebAdapterServlet.
-        * 
-        * @param request
-        *            the HTTP request.
-        * @param response
-        *            the HTTP response.
-        * @return boolean <code>true</code> if the request was handled and
-        *         further processing should be suppressed, <code>false</code>
-        *         otherwise.
-        * @throws ServletException
-        *             if an exception has occurred that interferes with the
-        *             servlet's normal operation.
-        */
-       private boolean handleResourceRequest(HttpServletRequest request,
-                       HttpServletResponse response, String themeName) throws ServletException {
-
-               // If the resource path is unassigned, initialize it
-               if (resourcePath == null) {
-                       resourcePath = request.getContextPath() + request.getServletPath()
-                                       + RESOURCE_URI;
-                       // WebSphere Application Server related fix
-                       resourcePath = resourcePath.replaceAll("//", "/");
-               }
 
-               String resourceId = request.getPathInfo();
+       page
+               .write("', pathInfo: '"
+                       + request.getPathInfo()
+                       + "'\n};\n"
+                       + "</script>\n"
+                       + "<script language='javascript' src='"
+                       + (hasSlash ? "../" : "")
+                       + relative
+                       + widgetset
+                       + "/"
+                       + widgetset
+                       + ".nocache.js'></script>"
+                       + "<link REL=\"stylesheet\" TYPE=\"text/css\" HREF=\""
+                       + request.getContextPath()
+                       + THEME_DIRECTORY_PATH
+                       + themeName
+                       + "/styles.css\">"
+                       + "</head>\n<body>\n"
+                       + "     <iframe id=\"__gwt_historyFrame\" style=\"width:0;height:0;border:0\"></iframe>\n"
+                       + "     <div id=\"itmtk-ajax-window\"></div>"
+                       + "     </body>\n" + "</html>\n");
+
+       page.close();
+
+    }
+
+    /**
+     * Handles the requested URI. An application can add handlers to do special
+     * processing, when a certain URI is requested. The handlers are invoked
+     * before any windows URIs are processed and if a DownloadStream is returned
+     * it is sent to the client.
+     * 
+     * @param application
+     *                the Application owning the URI.
+     * @param request
+     *                the HTTP request instance.
+     * @param response
+     *                the HTTP response to write to.
+     * @return boolean <code>true</code> if the request was handled and
+     *         further processing should be suppressed, <code>false</code>
+     *         otherwise.
+     * @see com.itmill.toolkit.terminal.URIHandler
+     */
+    private DownloadStream handleURI(Application application,
+           HttpServletRequest request, HttpServletResponse response) {
+
+       String uri = request.getPathInfo();
+
+       // If no URI is available
+       if (uri == null || uri.length() == 0 || uri.equals("/"))
+           return null;
+
+       // Removes the leading /
+       while (uri.startsWith("/") && uri.length() > 0)
+           uri = uri.substring(1);
+
+       // Handles the uri
+       DownloadStream stream = null;
+       try {
+           stream = application.handleURI(application.getURL(), uri);
+       } catch (Throwable t) {
+           application.terminalError(new URIHandlerErrorImpl(application, t));
+       }
 
-               // Checks if this really is a resource request
-               if (resourceId == null || !resourceId.startsWith(RESOURCE_URI))
-                       return false;
-
-               // Checks the resource type
-               resourceId = resourceId.substring(RESOURCE_URI.length());
-               InputStream data = null;
-               
-               // Gets theme resources
-               try {
-                       data = getServletContext().getResourceAsStream(THEME_DIRECTORY_PATH + themeName + "/" + resourceId);
-               } catch (Exception e) {
-                       Log.info(e.getMessage());
-                       data = null;
+       return stream;
+    }
+
+    /**
+     * Handles the requested URI. An application can add handlers to do special
+     * processing, when a certain URI is requested. The handlers are invoked
+     * before any windows URIs are processed and if a DownloadStream is returned
+     * it is sent to the client.
+     * 
+     * @param stream
+     *                the download stream.
+     * 
+     * @param request
+     *                the HTTP request instance.
+     * @param response
+     *                the HTTP response to write to.
+     * 
+     * @see com.itmill.toolkit.terminal.URIHandler
+     */
+    private void handleDownload(DownloadStream stream,
+           HttpServletRequest request, HttpServletResponse response) {
+
+       // Download from given stream
+       InputStream data = stream.getStream();
+       if (data != null) {
+
+           // Sets content type
+           response.setContentType(stream.getContentType());
+
+           // Sets cache headers
+           long cacheTime = stream.getCacheTime();
+           if (cacheTime <= 0) {
+               response.setHeader("Cache-Control", "no-cache");
+               response.setHeader("Pragma", "no-cache");
+               response.setDateHeader("Expires", 0);
+           } else {
+               response.setHeader("Cache-Control", "max-age=" + cacheTime
+                       / 1000);
+               response.setDateHeader("Expires", System.currentTimeMillis()
+                       + cacheTime);
+               response.setHeader("Pragma", "cache"); // Required to apply
+               // caching in some
+               // Tomcats
+           }
+
+           // Copy download stream parameters directly
+           // to HTTP headers.
+           Iterator i = stream.getParameterNames();
+           if (i != null) {
+               while (i.hasNext()) {
+                   String param = (String) i.next();
+                   response.setHeader((String) param, stream
+                           .getParameter(param));
                }
+           }
 
-               // Writes the response
-               try {
-                       if (data != null) {
-                               response.setContentType(FileTypeResolver
-                                               .getMIMEType(resourceId));
-
-                               // Use default cache time for theme resources
-                                       response.setHeader("Cache-Control", "max-age="
-                                                       + DEFAULT_THEME_CACHETIME / 1000);
-                                       response.setDateHeader("Expires", System
-                                                       .currentTimeMillis()
-                                                       + DEFAULT_THEME_CACHETIME);
-                                       response.setHeader("Pragma", "cache"); // Required to apply
-                                       // caching in some
-                                       // Tomcats
-               
-                               // Writes the data to client
-                               byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
-                               int bytesRead = 0;
-                               OutputStream out = response.getOutputStream();
-                               while ((bytesRead = data.read(buffer)) > 0) {
-                                       out.write(buffer, 0, bytesRead);
-                               }
-                               out.close();
-                               data.close();
-                       } else {
-                               response.sendError(HttpServletResponse.SC_NOT_FOUND);
-                       }
+           int bufferSize = stream.getBufferSize();
+           if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE)
+               bufferSize = DEFAULT_BUFFER_SIZE;
+           byte[] buffer = new byte[bufferSize];
+           int bytesRead = 0;
+
+           try {
+               OutputStream out = response.getOutputStream();
 
-               } catch (java.io.IOException e) {
-                       Log.info("Resource transfer failed:  " + request.getRequestURI()
-                                       + ". (" + e.getMessage() + ")");
+               while ((bytesRead = data.read(buffer)) > 0) {
+                   out.write(buffer, 0, bytesRead);
+                   out.flush();
                }
+               out.close();
+           } catch (IOException ignored) {
+           }
 
-               return true;
        }
 
+    }
+
+    /**
+     * Handles theme resource file requests. Resources supplied with the themes
+     * are provided by the WebAdapterServlet.
+     * 
+     * @param request
+     *                the HTTP request.
+     * @param response
+     *                the HTTP response.
+     * @return boolean <code>true</code> if the request was handled and
+     *         further processing should be suppressed, <code>false</code>
+     *         otherwise.
+     * @throws ServletException
+     *                 if an exception has occurred that interferes with the
+     *                 servlet's normal operation.
+     */
+    private boolean handleResourceRequest(HttpServletRequest request,
+           HttpServletResponse response, String themeName)
+           throws ServletException {
+
+       // If the resource path is unassigned, initialize it
+       if (resourcePath == null) {
+           resourcePath = request.getContextPath() + request.getServletPath()
+                   + RESOURCE_URI;
+           // WebSphere Application Server related fix
+           resourcePath = resourcePath.replaceAll("//", "/");
+       }
 
-       /**
-        * Gets the current application URL from request.
-        * 
-        * @param request
-        *            the HTTP request.
-        * @throws MalformedURLException
-        *             if the application is denied access to the persistent data
-        *             store represented by the given URL.
-        */
-       private URL getApplicationUrl(HttpServletRequest request)
-                       throws MalformedURLException {
-
-               URL applicationUrl;
-               try {
-                       URL reqURL = new URL(
-                                       (request.isSecure() ? "https://" : "http://")
-                                                       + request.getServerName()
-                                                       + ((request.isSecure() && request.getServerPort() == 443)
-                                                                       || (!request.isSecure() && request
-                                                                                       .getServerPort() == 80) ? "" : ":"
-                                                                       + request.getServerPort())
-                                                       + request.getRequestURI());
-                       String servletPath = request.getContextPath()
-                                       + request.getServletPath();
-                       if (servletPath.length() == 0
-                                       || servletPath.charAt(servletPath.length() - 1) != '/')
-                               servletPath = servletPath + "/";
-                       applicationUrl = new URL(reqURL, servletPath);
-               } catch (MalformedURLException e) {
-                       Log.error("Error constructing application url "
-                                       + request.getRequestURI() + " (" + e + ")");
-                       throw e;
-               }
+       String resourceId = request.getPathInfo();
+
+       // Checks if this really is a resource request
+       if (resourceId == null || !resourceId.startsWith(RESOURCE_URI))
+           return false;
 
-               return applicationUrl;
+       // Checks the resource type
+       resourceId = resourceId.substring(RESOURCE_URI.length());
+       InputStream data = null;
+
+       // Gets theme resources
+       try {
+           data = getServletContext().getResourceAsStream(
+                   THEME_DIRECTORY_PATH + themeName + "/" + resourceId);
+       } catch (Exception e) {
+           Log.info(e.getMessage());
+           data = null;
        }
 
-       /**
-        * Gets the existing application for given request. Looks for application
-        * instance for given request based on the requested URL.
-        * 
-        * @param request
-        *            the HTTP request.
-        * @return Application instance, or null if the URL does not map to valid
-        *         application.
-        * @throws MalformedURLException
-        *             if the application is denied access to the persistent data
-        *             store represented by the given URL.
-        * @throws SAXException 
-        * @throws LicenseViolation 
-        * @throws InvalidLicenseFile 
-        * @throws LicenseSignatureIsInvalid 
-        * @throws LicenseFileHasNotBeenRead 
-        * @throws IllegalAccessException 
-        * @throws InstantiationException 
-        */
-       private Application getApplication(HttpServletRequest request)
-                       throws MalformedURLException, LicenseFileHasNotBeenRead,
-                       LicenseSignatureIsInvalid, InvalidLicenseFile, LicenseViolation,
-                       SAXException, IllegalAccessException, InstantiationException {
-
-               // Ensures that the session is still valid
-               HttpSession session = request.getSession(true);
-
-               // Gets application list for the session.
-               Collection applications = WebApplicationContext.getApplicationContext(session).getApplications();
-
-               // Search for the application (using the application URI) from the list
-               for (Iterator i = applications.iterator(); i.hasNext();) {
-                       Application a = (Application) i.next();
-                       String aPath = a.getURL().getPath();
-                       String servletPath = request.getContextPath()
-                                       + request.getServletPath();
-                       if (servletPath.length() < aPath.length())
-                               servletPath += "/";
-                       if (servletPath.equals(aPath)) {
-
-                               // Found a running application
-                               if (a.isRunning())
-                                       return a;
-                               
-                               // Application has stopped, so remove it before creating a new application
-                               WebApplicationContext.getApplicationContext(session).removeApplication(a);
-                               break;
-                       }
+       // Writes the response
+       try {
+           if (data != null) {
+               response.setContentType(FileTypeResolver
+                       .getMIMEType(resourceId));
+
+               // Use default cache time for theme resources
+               response.setHeader("Cache-Control", "max-age="
+                       + DEFAULT_THEME_CACHETIME / 1000);
+               response.setDateHeader("Expires", System.currentTimeMillis()
+                       + DEFAULT_THEME_CACHETIME);
+               response.setHeader("Pragma", "cache"); // Required to apply
+               // caching in some
+               // Tomcats
+
+               // Writes the data to client
+               byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+               int bytesRead = 0;
+               OutputStream out = response.getOutputStream();
+               while ((bytesRead = data.read(buffer)) > 0) {
+                   out.write(buffer, 0, bytesRead);
                }
-               
-               // Creates application, because a running one was not found
-                       WebApplicationContext context = WebApplicationContext.getApplicationContext(request.getSession());
-                       URL applicationUrl = getApplicationUrl(request);
-
-                       // Creates new application and start it
-                       try {
-                               Application application = (Application) this.applicationClass.newInstance();
-                               context.addApplication(application);
-
-                               // Sets initial locale from the request
-                               application.setLocale(request.getLocale());                             
-
-                               // Starts application and check license
-                               initializeLicense(application);
-                               application.start(applicationUrl, this.applicationProperties,
-                                               context);
-                               checkLicense(application);
-
-                               return application;
-
-                       } catch (IllegalAccessException e) {
-                               Log.error("Illegal access to application class "
-                                               + this.applicationClass.getName());
-                               throw e;
-                       } catch (InstantiationException e) {
-                               Log.error("Failed to instantiate application class: "
-                                               + this.applicationClass.getName());
-                               throw e;
-                       }       
+               out.close();
+               data.close();
+           } else {
+               response.sendError(HttpServletResponse.SC_NOT_FOUND);
+           }
+
+       } catch (java.io.IOException e) {
+           Log.info("Resource transfer failed:  " + request.getRequestURI()
+                   + ". (" + e.getMessage() + ")");
        }
 
+       return true;
+    }
+
+    /**
+     * Gets the current application URL from request.
+     * 
+     * @param request
+     *                the HTTP request.
+     * @throws MalformedURLException
+     *                 if the application is denied access to the persistent
+     *                 data store represented by the given URL.
+     */
+    private URL getApplicationUrl(HttpServletRequest request)
+           throws MalformedURLException {
+
+       URL applicationUrl;
+       try {
+           URL reqURL = new URL(
+                   (request.isSecure() ? "https://" : "http://")
+                           + request.getServerName()
+                           + ((request.isSecure() && request.getServerPort() == 443)
+                                   || (!request.isSecure() && request
+                                           .getServerPort() == 80) ? "" : ":"
+                                   + request.getServerPort())
+                           + request.getRequestURI());
+           String servletPath = request.getContextPath()
+                   + request.getServletPath();
+           if (servletPath.length() == 0
+                   || servletPath.charAt(servletPath.length() - 1) != '/')
+               servletPath = servletPath + "/";
+           applicationUrl = new URL(reqURL, servletPath);
+       } catch (MalformedURLException e) {
+           Log.error("Error constructing application url "
+                   + request.getRequestURI() + " (" + e + ")");
+           throw e;
+       }
 
-       /**
-        * 
-        * @param application
-        */
-       private void initializeLicense(Application application) {
-               License license;
-               synchronized (licenseForApplicationClass) {
-                       license = (License) licenseForApplicationClass.get(application
-                                       .getClass());
-                       if (license == null) {
-                               license = new License();
-                               licenseForApplicationClass.put(application.getClass(), license);
-                       }
-               }
-               application.setToolkitLicense(license);
+       return applicationUrl;
+    }
+
+    /**
+     * Gets the existing application for given request. Looks for application
+     * instance for given request based on the requested URL.
+     * 
+     * @param request
+     *                the HTTP request.
+     * @return Application instance, or null if the URL does not map to valid
+     *         application.
+     * @throws MalformedURLException
+     *                 if the application is denied access to the persistent
+     *                 data store represented by the given URL.
+     * @throws SAXException
+     * @throws LicenseViolation
+     * @throws InvalidLicenseFile
+     * @throws LicenseSignatureIsInvalid
+     * @throws LicenseFileHasNotBeenRead
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    private Application getApplication(HttpServletRequest request)
+           throws MalformedURLException, LicenseFileHasNotBeenRead,
+           LicenseSignatureIsInvalid, InvalidLicenseFile, LicenseViolation,
+           SAXException, IllegalAccessException, InstantiationException {
+
+       // Ensures that the session is still valid
+       HttpSession session = request.getSession(true);
+
+       // Gets application list for the session.
+       Collection applications = WebApplicationContext.getApplicationContext(
+               session).getApplications();
+
+       // Search for the application (using the application URI) from the list
+       for (Iterator i = applications.iterator(); i.hasNext();) {
+           Application a = (Application) i.next();
+           String aPath = a.getURL().getPath();
+           String servletPath = request.getContextPath()
+                   + request.getServletPath();
+           if (servletPath.length() < aPath.length())
+               servletPath += "/";
+           if (servletPath.equals(aPath)) {
+
+               // Found a running application
+               if (a.isRunning())
+                   return a;
+
+               // Application has stopped, so remove it before creating a new
+               // application
+               WebApplicationContext.getApplicationContext(session)
+                       .removeApplication(a);
+               break;
+           }
        }
 
-       /**
-        * 
-        * @param application
-        * @throws LicenseFileHasNotBeenRead
-        *             if the license file has not been read.
-        * @throws LicenseSignatureIsInvalid
-        *             if the license file has been changed or signature is
-        *             otherwise invalid.
-        * @throws InvalidLicenseFile
-        *             if the license file is not of correct XML format.
-        * @throws LicenseViolation
-        * 
-        * @throws SAXException
-        *             the Error parsing the license file.
-        */
-       private void checkLicense(Application application)
-                       throws LicenseFileHasNotBeenRead, LicenseSignatureIsInvalid,
-                       InvalidLicenseFile, LicenseViolation, SAXException {
-               License license = application.getToolkitLicense();
-
-               if (!license.hasBeenRead())
-                       // Lock threads that have not yet read license
-                       synchronized (license) {
-                               if (!license.hasBeenRead()) {
-                                       InputStream lis;
-                                       try {
-                                               URL url = getServletContext().getResource(
-                                                               "/WEB-INF/itmill-toolkit-license.xml");
-                                               if (url == null) {
-                                                       throw new RuntimeException(
-                                                                       "License file could not be read. "
-                                                                                       + "You can install it to "
-                                                                                       + "WEB-INF/itmill-toolkit-license.xml.");
-                                               }
-                                               lis = url.openStream();
-                                               license.readLicenseFile(lis);
-                                       } catch (MalformedURLException e) {
-                                               // This should not happen
-                                               throw new RuntimeException(e);
-                                       } catch (IOException e) {
-                                               // This should not happen
-                                               throw new RuntimeException(e);
-                                       }
-
-                                       // For each application class, print license description -
-                                       // once
-                                       if (!licensePrintedForApplicationClass
-                                                       .containsKey(applicationClass)) {
-                                               licensePrintedForApplicationClass.put(applicationClass,
-                                                               Boolean.TRUE);
-                                               if (license.shouldLimitsBePrintedOnInit()) {
-                                                       System.out.println(license
-                                                                       .getDescription(application.getClass()
-                                                                                       .toString()));
-                                               }
-                                       }
-
-                                       // Checks license validity
-                                       try {
-                                               license.check(applicationClass, VERSION_MAJOR,
-                                                               VERSION_MINOR, "IT Mill Toolkit", null);
-                                       } catch (LicenseFileHasNotBeenRead e) {
-                                               application.close();
-                                               throw e;
-                                       } catch (LicenseSignatureIsInvalid e) {
-                                               application.close();
-                                               throw e;
-                                       } catch (InvalidLicenseFile e) {
-                                               application.close();
-                                               throw e;
-                                       } catch (LicenseViolation e) {
-                                               application.close();
-                                               throw e;
-                                       }
-                               }
+       // Creates application, because a running one was not found
+       WebApplicationContext context = WebApplicationContext
+               .getApplicationContext(request.getSession());
+       URL applicationUrl = getApplicationUrl(request);
+
+       // Creates new application and start it
+       try {
+           Application application = (Application) this.applicationClass
+                   .newInstance();
+           context.addApplication(application);
+
+           // Sets initial locale from the request
+           application.setLocale(request.getLocale());
+
+           // Starts application and check license
+           initializeLicense(application);
+           application.start(applicationUrl, this.applicationProperties,
+                   context);
+           checkLicense(application);
+
+           return application;
+
+       } catch (IllegalAccessException e) {
+           Log.error("Illegal access to application class "
+                   + this.applicationClass.getName());
+           throw e;
+       } catch (InstantiationException e) {
+           Log.error("Failed to instantiate application class: "
+                   + this.applicationClass.getName());
+           throw e;
+       }
+    }
+
+    /**
+     * 
+     * @param application
+     */
+    private void initializeLicense(Application application) {
+       License license;
+       synchronized (licenseForApplicationClass) {
+           license = (License) licenseForApplicationClass.get(application
+                   .getClass());
+           if (license == null) {
+               license = new License();
+               licenseForApplicationClass.put(application.getClass(), license);
+           }
+       }
+       application.setToolkitLicense(license);
+    }
+
+    /**
+     * 
+     * @param application
+     * @throws LicenseFileHasNotBeenRead
+     *                 if the license file has not been read.
+     * @throws LicenseSignatureIsInvalid
+     *                 if the license file has been changed or signature is
+     *                 otherwise invalid.
+     * @throws InvalidLicenseFile
+     *                 if the license file is not of correct XML format.
+     * @throws LicenseViolation
+     * 
+     * @throws SAXException
+     *                 the Error parsing the license file.
+     */
+    private void checkLicense(Application application)
+           throws LicenseFileHasNotBeenRead, LicenseSignatureIsInvalid,
+           InvalidLicenseFile, LicenseViolation, SAXException {
+       License license = application.getToolkitLicense();
+
+       if (!license.hasBeenRead())
+           // Lock threads that have not yet read license
+           synchronized (license) {
+               if (!license.hasBeenRead()) {
+                   InputStream lis;
+                   try {
+                       URL url = getServletContext().getResource(
+                               "/WEB-INF/itmill-toolkit-license.xml");
+                       if (url == null) {
+                           throw new RuntimeException(
+                                   "License file could not be read. "
+                                           + "You can install it to "
+                                           + "WEB-INF/itmill-toolkit-license.xml.");
                        }
+                       lis = url.openStream();
+                       license.readLicenseFile(lis);
+                   } catch (MalformedURLException e) {
+                       // This should not happen
+                       throw new RuntimeException(e);
+                   } catch (IOException e) {
+                       // This should not happen
+                       throw new RuntimeException(e);
+                   }
+
+                   // For each application class, print license description -
+                   // once
+                   if (!licensePrintedForApplicationClass
+                           .containsKey(applicationClass)) {
+                       licensePrintedForApplicationClass.put(applicationClass,
+                               Boolean.TRUE);
+                       if (license.shouldLimitsBePrintedOnInit()) {
+                           System.out.println(license
+                                   .getDescription(application.getClass()
+                                           .toString()));
+                       }
+                   }
 
-               // Checks concurrent user limit
-               try {
-                       license.checkConcurrentUsers(getNumberOfActiveUsers() + 1);
-               } catch (LicenseViolation e) {
+                   // Checks license validity
+                   try {
+                       license.check(applicationClass, VERSION_MAJOR,
+                               VERSION_MINOR, "IT Mill Toolkit", null);
+                   } catch (LicenseFileHasNotBeenRead e) {
+                       application.close();
+                       throw e;
+                   } catch (LicenseSignatureIsInvalid e) {
+                       application.close();
+                       throw e;
+                   } catch (InvalidLicenseFile e) {
                        application.close();
                        throw e;
+                   } catch (LicenseViolation e) {
+                       application.close();
+                       throw e;
+                   }
                }
+           }
+
+       // Checks concurrent user limit
+       try {
+           license.checkConcurrentUsers(getNumberOfActiveUsers() + 1);
+       } catch (LicenseViolation e) {
+           application.close();
+           throw e;
        }
-
-       /**
-        * Gets the number of active application-user pairs.
-        * 
-        * This returns total number of all applications in the server that are
-        * considered to be active. For an application to be active, it must have
-        * been accessed less than ACTIVE_USER_REQUEST_INTERVAL ms.
-        * 
-        * @return the Number of active application instances in the server.
-        */
-       private int getNumberOfActiveUsers() {
-               int active = 0;
-
-               synchronized (applicationToLastRequestDate) {
-                       Set apps = applicationToLastRequestDate.keySet();
-                       long now = System.currentTimeMillis();
-                       for (Iterator i = apps.iterator(); i.hasNext();) {
-                               Date lastReq = (Date) applicationToLastRequestDate
-                                               .get(i.next());
-                               if (now - lastReq.getTime() < ACTIVE_USER_REQUEST_INTERVAL)
-                                       active++;
-                       }
-               }
-
-               return active;
+    }
+
+    /**
+     * Gets the number of active application-user pairs.
+     * 
+     * This returns total number of all applications in the server that are
+     * considered to be active. For an application to be active, it must have
+     * been accessed less than ACTIVE_USER_REQUEST_INTERVAL ms.
+     * 
+     * @return the Number of active application instances in the server.
+     */
+    private int getNumberOfActiveUsers() {
+       int active = 0;
+
+       synchronized (applicationToLastRequestDate) {
+           Set apps = applicationToLastRequestDate.keySet();
+           long now = System.currentTimeMillis();
+           for (Iterator i = apps.iterator(); i.hasNext();) {
+               Date lastReq = (Date) applicationToLastRequestDate
+                       .get(i.next());
+               if (now - lastReq.getTime() < ACTIVE_USER_REQUEST_INTERVAL)
+                   active++;
+           }
        }
 
-       /**
-        * Ends the application.
-        * 
-        * @param request
-        *            the HTTP request.
-        * @param response
-        *            the HTTP response to write to.
-        * @param application
-        *            the application to end.
-        * @throws IOException
-        *             if the writing failed due to input/output error.
-        */
-       private void endApplication(HttpServletRequest request,
-                       HttpServletResponse response, Application application)
-                       throws IOException {
-
-               String logoutUrl = application.getLogoutURL();
-               if (logoutUrl == null)
-                       logoutUrl = application.getURL().toString();
-
-               HttpSession session = request.getSession();
-               if (session != null) {
-                       WebApplicationContext.getApplicationContext(session).removeApplication(application);
-               }
+       return active;
+    }
+
+    /**
+     * Ends the application.
+     * 
+     * @param request
+     *                the HTTP request.
+     * @param response
+     *                the HTTP response to write to.
+     * @param application
+     *                the application to end.
+     * @throws IOException
+     *                 if the writing failed due to input/output error.
+     */
+    private void endApplication(HttpServletRequest request,
+           HttpServletResponse response, Application application)
+           throws IOException {
+
+       String logoutUrl = application.getLogoutURL();
+       if (logoutUrl == null)
+           logoutUrl = application.getURL().toString();
+
+       HttpSession session = request.getSession();
+       if (session != null) {
+           WebApplicationContext.getApplicationContext(session)
+                   .removeApplication(application);
+       }
 
-               response.sendRedirect(response.encodeRedirectURL(logoutUrl));
+       response.sendRedirect(response.encodeRedirectURL(logoutUrl));
+    }
+
+    /**
+     * Gets the existing application or create a new one. Get a window within an
+     * application based on the requested URI.
+     * 
+     * @param request
+     *                the HTTP Request.
+     * @param application
+     *                the Application to query for window.
+     * @return Window matching the given URI or null if not found.
+     * @throws ServletException
+     *                 if an exception has occurred that interferes with the
+     *                 servlet's normal operation.
+     */
+    private Window getApplicationWindow(HttpServletRequest request,
+           Application application) throws ServletException {
+
+       Window window = null;
+
+       // Finds the window where the request is handled
+       String path = request.getPathInfo();
+
+       // Main window as the URI is empty
+       if (path == null || path.length() == 0 || path.equals("/"))
+           window = application.getMainWindow();
+
+       // Try to search by window name
+       else {
+           String windowName = null;
+           if (path.charAt(0) == '/')
+               path = path.substring(1);
+           int index = path.indexOf('/');
+           if (index < 0) {
+               windowName = path;
+               path = "";
+           } else {
+               windowName = path.substring(0, index);
+               path = path.substring(index + 1);
+           }
+           window = application.getWindow(windowName);
+
+           if (window == null) {
+               // By default, we use main window
+               window = application.getMainWindow();
+           } else if (!window.isVisible()) {
+               // Implicitly painting without actually invoking paint()
+               window.requestRepaintRequests();
+
+               // If the window is invisible send a blank page
+               return null;
+           }
        }
 
-       /**
-        * Gets the existing application or create a new one. Get a window within an
-        * application based on the requested URI.
-        * 
-        * @param request
-        *            the HTTP Request.
-        * @param application
-        *            the Application to query for window.
-        * @return Window matching the given URI or null if not found.
-        * @throws ServletException
-        *             if an exception has occurred that interferes with the
-        *             servlet's normal operation.
-        */
-       private Window getApplicationWindow(HttpServletRequest request,
-                       Application application) throws ServletException {
-
-               Window window = null;
-
-               // Finds the window where the request is handled
-               String path = request.getPathInfo();
-
-               // Main window as the URI is empty
-               if (path == null || path.length() == 0 || path.equals("/"))
-                       window = application.getMainWindow();
-
-               // Try to search by window name
-               else {
-                       String windowName = null;
-                       if (path.charAt(0) == '/')
-                               path = path.substring(1);
-                       int index = path.indexOf('/');
-                       if (index < 0) {
-                               windowName = path;
-                               path = "";
-                       } else {
-                               windowName = path.substring(0, index);
-                               path = path.substring(index + 1);
-                       }
-                       window = application.getWindow(windowName);
+       return window;
+    }
+
+    /**
+     * Gets relative location of a theme resource.
+     * 
+     * @param theme
+     *                the Theme name.
+     * @param resource
+     *                the Theme resource.
+     * @return External URI specifying the resource
+     */
+    public String getResourceLocation(String theme, ThemeResource resource) {
+
+       if (resourcePath == null)
+           return resource.getResourceId();
+       return resourcePath + theme + "/" + resource.getResourceId();
+    }
+
+    /**
+     * Checks if web adapter is in debug mode. Extra output is generated to log
+     * when debug mode is enabled.
+     * 
+     * @param parameters
+     * @return <code>true</code> if the web adapter is in debug mode.
+     *         otherwise <code>false</code>.
+     */
+    public boolean isDebugMode(Map parameters) {
+       if (parameters != null) {
+           Object[] debug = (Object[]) parameters.get("debug");
+           if (debug != null && !"false".equals(debug[0].toString())
+                   && !"false".equals(debugMode))
+               return true;
+       }
+       return "true".equals(debugMode);
+    }
 
-                       if (window == null) {
-                               // By default, we use main window
-                               window = application.getMainWindow();
-                       } else if (!window.isVisible()) {
-                               // Implicitly painting without actually invoking paint()
-                               window.requestRepaintRequests();
+    /**
+     * Implementation of ParameterHandler.ErrorEvent interface.
+     */
+    public class ParameterHandlerErrorImpl implements
+           ParameterHandler.ErrorEvent {
 
-                               // If the window is invisible send a blank page
-                               return null;
-                       }
-               }
+       private ParameterHandler owner;
 
-               return window;
-       }
+       private Throwable throwable;
 
        /**
-        * Gets relative location of a theme resource.
+        * Gets the contained throwable.
         * 
-        * @param theme
-        *            the Theme name.
-        * @param resource
-        *            the Theme resource.
-        * @return External URI specifying the resource
+        * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
         */
-       public String getResourceLocation(String theme, ThemeResource resource) {
-
-               if (resourcePath == null)
-                       return resource.getResourceId();
-               return resourcePath + theme + "/" + resource.getResourceId();
+       public Throwable getThrowable() {
+           return this.throwable;
        }
 
        /**
-        * Checks if web adapter is in debug mode. Extra output is generated to log
-        * when debug mode is enabled.
+        * Gets the source ParameterHandler.
         * 
-        * @param parameters
-        * @return <code>true</code> if the web adapter is in debug mode.
-        *         otherwise <code>false</code>.
+        * @see com.itmill.toolkit.terminal.ParameterHandler.ErrorEvent#getParameterHandler()
         */
-       public boolean isDebugMode(Map parameters) {
-               if (parameters != null) {
-                       Object[] debug = (Object[]) parameters.get("debug");
-                       if (debug != null && !"false".equals(debug[0].toString())
-                                       && !"false".equals(debugMode))
-                               return true;
-               }
-               return "true".equals(debugMode);
+       public ParameterHandler getParameterHandler() {
+           return this.owner;
        }
 
+    }
 
-       /**
-        * Implementation of ParameterHandler.ErrorEvent interface.
-        */
-       public class ParameterHandlerErrorImpl implements
-                       ParameterHandler.ErrorEvent {
-
-               private ParameterHandler owner;
-
-               private Throwable throwable;
+    /**
+     * Implementation of URIHandler.ErrorEvent interface.
+     */
+    public class URIHandlerErrorImpl implements URIHandler.ErrorEvent {
 
+       private URIHandler owner;
 
-               /**
-                * Gets the contained throwable.
-                * 
-                * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
-                */
-               public Throwable getThrowable() {
-                       return this.throwable;
-               }
-
-               /**
-                * Gets the source ParameterHandler.
-                * 
-                * @see com.itmill.toolkit.terminal.ParameterHandler.ErrorEvent#getParameterHandler()
-                */
-               public ParameterHandler getParameterHandler() {
-                       return this.owner;
-               }
-
-       }
+       private Throwable throwable;
 
        /**
-        * Implementation of URIHandler.ErrorEvent interface.
+        * 
+        * @param owner
+        * @param throwable
         */
-       public class URIHandlerErrorImpl implements URIHandler.ErrorEvent {
-
-               private URIHandler owner;
-
-               private Throwable throwable;
-
-               /**
-                * 
-                * @param owner
-                * @param throwable
-                */
-               private URIHandlerErrorImpl(URIHandler owner, Throwable throwable) {
-                       this.owner = owner;
-                       this.throwable = throwable;
-               }
-
-               /**
-                * Gets the contained throwable.
-                * 
-                * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
-                */
-               public Throwable getThrowable() {
-                       return this.throwable;
-               }
-
-               /**
-                * Gets the source URIHandler.
-                * 
-                * @see com.itmill.toolkit.terminal.URIHandler.ErrorEvent#getURIHandler()
-                */
-               public URIHandler getURIHandler() {
-                       return this.owner;
-               }
+       private URIHandlerErrorImpl(URIHandler owner, Throwable throwable) {
+           this.owner = owner;
+           this.throwable = throwable;
        }
 
        /**
-        * Gets AJAX application manager for an application.
-        * 
-        * If this application has not been running in ajax mode before, new manager
-        * is created and web adapter stops listening to changes.
+        * Gets the contained throwable.
         * 
-        * @param application
-        * @return AJAX Application Manager
+        * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
         */
-       private CommunicationManager getApplicationManager(Application application) {
-               CommunicationManager mgr = (CommunicationManager) applicationToAjaxAppMgrMap
-                               .get(application);
-
-               // This application is going from Web to AJAX mode, create new manager
-               if (mgr == null) {
-                       // Creates new manager
-                       mgr = new CommunicationManager(application, this);
-                       applicationToAjaxAppMgrMap.put(application, mgr);
-
-                       // Manager takes control over the application
-                       mgr.takeControl();
-               }
-
-               return mgr;
+       public Throwable getThrowable() {
+           return this.throwable;
        }
 
        /**
-        * Gets resource path using different implementations. Required fo
-        * supporting different servlet container implementations (application
-        * servers).
+        * Gets the source URIHandler.
         * 
-        * @param servletContext
-        * @param path
-        *            the resource path.
-        * @return the resource path.
+        * @see com.itmill.toolkit.terminal.URIHandler.ErrorEvent#getURIHandler()
         */
-       protected static String getResourcePath(ServletContext servletContext,
-                       String path) {
-               String resultPath = null;
-               resultPath = servletContext.getRealPath(path);
-               if (resultPath != null) {
-                       return resultPath;
-               } else {
-                       try {
-                               URL url = servletContext.getResource(path);
-                               resultPath = url.getFile();
-                       } catch (Exception e) {
-                               // ignored
-                       }
-               }
-               return resultPath;
+       public URIHandler getURIHandler() {
+           return this.owner;
+       }
+    }
+
+    /**
+     * Gets AJAX application manager for an application.
+     * 
+     * If this application has not been running in ajax mode before, new manager
+     * is created and web adapter stops listening to changes.
+     * 
+     * @param application
+     * @return AJAX Application Manager
+     */
+    private CommunicationManager getApplicationManager(Application application) {
+       CommunicationManager mgr = (CommunicationManager) applicationToAjaxAppMgrMap
+               .get(application);
+
+       // This application is going from Web to AJAX mode, create new manager
+       if (mgr == null) {
+           // Creates new manager
+           mgr = new CommunicationManager(application, this);
+           applicationToAjaxAppMgrMap.put(application, mgr);
+
+           // Manager takes control over the application
+           mgr.takeControl();
+       }
+
+       return mgr;
+    }
+
+    /**
+     * Gets resource path using different implementations. Required fo
+     * supporting different servlet container implementations (application
+     * servers).
+     * 
+     * @param servletContext
+     * @param path
+     *                the resource path.
+     * @return the resource path.
+     */
+    protected static String getResourcePath(ServletContext servletContext,
+           String path) {
+       String resultPath = null;
+       resultPath = servletContext.getRealPath(path);
+       if (resultPath != null) {
+           return resultPath;
+       } else {
+           try {
+               URL url = servletContext.getResource(path);
+               resultPath = url.getFile();
+           } catch (Exception e) {
+               // ignored
+           }
        }
+       return resultPath;
+    }
 
 }
\ No newline at end of file