You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2019/12/13 05:38:54 UTC

[struts-examples] tag examples-1.1 created (now 0f4d596)

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a change to tag examples-1.1
in repository https://gitbox.apache.org/repos/asf/struts-examples.git.


      at 0f4d596  (commit)
This tag includes the following new commits:

     new 0f4d596  Drops mailreader example as deprecated and based on Struts 1

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[struts-examples] 01/01: Drops mailreader example as deprecated and based on Struts 1

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to tag examples-1.1
in repository https://gitbox.apache.org/repos/asf/struts-examples.git

commit 0f4d596b154908459460ed78d8e8ffa947645601
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Fri Dec 13 06:38:31 2019 +0100

    Drops mailreader example as deprecated and based on Struts 1
---
 mailreader/README.txt                              |   23 -
 mailreader/pom.xml                                 |   81 -
 .../main/java/mailreader2/ApplicationListener.java |  232 --
 .../mailreader2/AuthenticationInterceptor.java     |   50 -
 .../src/main/java/mailreader2/Constants.java       |  126 -
 .../src/main/java/mailreader2/Login-validation.xml |   14 -
 mailreader/src/main/java/mailreader2/Login.java    |   46 -
 mailreader/src/main/java/mailreader2/Logout.java   |   33 -
 .../main/java/mailreader2/MailreaderSupport.java   |  581 -----
 .../java/mailreader2/MailreaderSupport.properties  |   97 -
 .../mailreader2/MailreaderSupport_ja.properties    |   89 -
 .../mailreader2/MailreaderSupport_ru.properties    |   89 -
 .../Registration-Registration_save-validation.xml  |   28 -
 .../java/mailreader2/Registration-validation.xml   |   32 -
 .../src/main/java/mailreader2/Registration.java    |  120 -
 .../Subscription-Subscription_save-validation.xml  |   23 -
 .../java/mailreader2/Subscription-validation.xml   |   11 -
 .../src/main/java/mailreader2/Subscription.java    |  143 --
 mailreader/src/main/java/mailreader2/Welcome.java  |   47 -
 mailreader/src/main/resources/LICENSE.txt          |  174 --
 mailreader/src/main/resources/NOTICE.txt           |    5 -
 mailreader/src/main/resources/alternate.properties |    3 -
 .../src/main/resources/alternate_ja.properties     |    1 -
 mailreader/src/main/resources/log4j2.xml           |   16 -
 .../src/main/resources/mailreader-default.xml      |   47 -
 .../src/main/resources/mailreader-support.xml      |   63 -
 mailreader/src/main/resources/struts.xml           |   16 -
 mailreader/src/main/resources/velocity.properties  |    1 -
 mailreader/src/main/webapp/META-INF/context.xml    |    3 -
 mailreader/src/main/webapp/WEB-INF/database.xml    |    9 -
 .../src/main/webapp/WEB-INF/jsp/ChangePassword.jsp |   25 -
 mailreader/src/main/webapp/WEB-INF/jsp/Error.jsp   |   40 -
 mailreader/src/main/webapp/WEB-INF/jsp/Footer.jsp  |    6 -
 mailreader/src/main/webapp/WEB-INF/jsp/Login.jsp   |   30 -
 .../src/main/webapp/WEB-INF/jsp/MainMenu.jsp       |   25 -
 .../src/main/webapp/WEB-INF/jsp/Registration.jsp   |  115 -
 .../src/main/webapp/WEB-INF/jsp/Subscription.jsp   |   60 -
 mailreader/src/main/webapp/WEB-INF/jsp/Welcome.jsp |   55 -
 mailreader/src/main/webapp/WEB-INF/web.xml         |   45 -
 mailreader/src/main/webapp/css/mailreader.css      |   46 -
 mailreader/src/main/webapp/index.html              |   10 -
 mailreader/src/main/webapp/struts-power.gif        |  Bin 1798 -> 0 bytes
 mailreader/src/main/webapp/tour.html               | 2470 --------------------
 pom.xml                                            |    3 +-
 44 files changed, 1 insertion(+), 5132 deletions(-)

diff --git a/mailreader/README.txt b/mailreader/README.txt
deleted file mode 100644
index 1ce884b..0000000
--- a/mailreader/README.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-README.txt - mailreader 
-
-The MailReader demonstrates a localized application with a master/child 
-CRUD workflow. 
-
-This rendition also demonstrates using wildcards to "normalize" an 
-application. 
-
-See the Sandbox for other MailReader examples using other architectures. 
-
-* http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2/apps/
-
-For more about the MailReader applicaton genneraly, visit Struts University.
-
-* http://www.StrutsUniversity.org/
-
-I18N:
-=====
-Please note that this project was created with the assumption that it will be run
-in an environment where the default locale is set to English. This means that
-the default messages defined in package.properties are in English. If the default
-locale for your server is different, then rename package.properties to package_en.properties
-and create a new package.properties with proper values for your default locale.
diff --git a/mailreader/pom.xml b/mailreader/pom.xml
deleted file mode 100644
index 7b52560..0000000
--- a/mailreader/pom.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.struts</groupId>
-        <artifactId>struts-examples</artifactId>
-        <version>1.0.0</version>
-    </parent>
-
-    <artifactId>mailreader</artifactId>
-    <packaging>war</packaging>
-    <name>Struts 2 Mail Reader Webapp</name>
-
-    <dependencies>
-
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-            <version>3.1.0</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.struts</groupId>
-            <artifactId>struts-mailreader-dao</artifactId>
-            <version>1.3.5</version>
-        </dependency>
-
-    </dependencies>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>src/main/java</directory>
-                <includes>
-                    <include>**/*.xml</include>
-                    <include>**/*.properties</include>
-                </includes>
-            </resource>
-        </resources>
-        <plugins>
-            <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
-                <version>${jetty-plugin.version}</version>
-                <configuration>
-                    <webApp>
-                        <contextPath>/${project.artifactId}</contextPath>
-                    </webApp>
-                    <stopKey>CTRL+C</stopKey>
-                    <stopPort>8999</stopPort>
-                    <scanIntervalSeconds>10</scanIntervalSeconds>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
-</project>
diff --git a/mailreader/src/main/java/mailreader2/ApplicationListener.java b/mailreader/src/main/java/mailreader2/ApplicationListener.java
deleted file mode 100644
index fe347ba..0000000
--- a/mailreader/src/main/java/mailreader2/ApplicationListener.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUserDatabase;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-import java.io.*;
-
-/**
- * <p><code>ServletContextListener</code> that initializes and finalizes the
- * persistent storage of User and Subscription information for the Struts
- * Demonstration Application, using an in-memory database backed by an XML
- * file.</p>
- * <p/>
- * <p><strong>IMPLEMENTATION WARNING</strong> - If this web application is run
- * from a WAR file, or in another environment where reading and writing of the
- * web application resource is impossible, the initial contents will be copied
- * to a file in the web application temporary directory provided by the
- * container.  This is for demonstration purposes only - you should
- * <strong>NOT</strong> assume that files written here will survive a restart
- * of your servlet container.</p>
- * <p/>
- * <p>This class was borrowed from the Shale Mailreader. Changes were:</p>
- * <p/>
- * <ul>
- * <p/>
- * <li>Path to database.xml (under classes here). </li>
- * <p/>
- * <li>Class to store protocol list (an array here). </li>
- * <p/>
- * </ul>
- * <p>
- * DEVELOPMENT NOTE - Another approach would be to instantiate the database via Spring.
- * </p>
- */
-
-public final class ApplicationListener implements ServletContextListener {
-
-    // ------------------------------------------------------ Manifest Constants
-
-
-    /**
-     * <p>Appication scope attribute key under which the in-memory version of
-     * our database is stored.</p>
-     */
-    public static final String DATABASE_KEY = "database";
-
-
-    /**
-     * <p>Application scope attribute key under which the valid selection
-     * items for the protocol property is stored.</p>
-     */
-    public static final String PROTOCOLS_KEY = "protocols";
-
-    // ------------------------------------------------------ Instance Variables
-
-
-    /**
-     * <p>The <code>ServletContext</code> for this web application.</p>
-     */
-    private ServletContext context = null;
-
-
-    /**
-     * The {@link MemoryUserDatabase} object we construct and make available.
-     */
-    private MemoryUserDatabase database = null;
-
-
-    /**
-     * <p>Logging output for this plug in instance.</p>
-     */
-    private Logger log = LogManager.getLogger(this.getClass());
-
-    // ------------------------------------------------------------- Properties
-
-
-    /**
-     * <p>The web application resource path of our persistent database storage
-     * file.</p>
-     */
-    private String pathname = "/WEB-INF/database.xml";
-
-    /**
-     * <p>Return the application resource path to the database.</p>
-     *
-     * @return application resource path path to the database
-     */
-    public String getPathname() {
-        return (this.pathname);
-    }
-
-    /**
-     * <p>Set the application resource path to the database.</p>
-     *
-     * @param pathname to the database
-     */
-    public void setPathname(String pathname) {
-        this.pathname = pathname;
-    }
-
-    // ------------------------------------------ ServletContextListener Methods
-
-
-    /**
-     * <p>Gracefully shut down this database, releasing any resources that
-     * were allocated at initialization.</p>
-     *
-     * @param event ServletContextEvent to process
-     */
-    public void contextDestroyed(ServletContextEvent event) {
-
-        log.info("Finalizing memory database plug in");
-
-        if (database != null) {
-            try {
-                database.close();
-            } catch (Exception e) {
-                log.error("Closing memory database", e);
-            }
-        }
-
-        context.removeAttribute(DATABASE_KEY);
-        context.removeAttribute(PROTOCOLS_KEY);
-        database = null;
-        context = null;
-
-    }
-
-
-    /**
-     * <p>Initialize and load our initial database from persistent
-     * storage.</p>
-     *
-     * @param event The context initialization event
-     */
-    public void contextInitialized(ServletContextEvent event) {
-
-        log.info("Initializing memory database plug in from '" +
-                pathname + "'");
-
-        // Remember our associated ServletContext
-        this.context = event.getServletContext();
-
-        // Construct a new database and make it available
-        database = new MemoryUserDatabase();
-        try {
-            String path = calculatePath();
-            if (log.isDebugEnabled()) {
-                log.debug(" Loading database from '" + path + "'");
-            }
-            database.setPathname(path);
-            database.open();
-        } catch (Exception e) {
-            log.error("Opening memory database", e);
-            throw new IllegalStateException("Cannot load database from '" +
-                    pathname + "': " + e);
-        }
-        context.setAttribute(DATABASE_KEY, database);
-
-    }
-
-    // -------------------------------------------------------- Private Methods
-
-
-    /**
-     * <p>Calculate and return an absolute pathname to the XML file to contain
-     * our persistent storage information.</p>
-     *
-     * @throws Exception if an input/output error occurs
-     */
-    private String calculatePath() throws Exception {
-
-        // Can we access the database via file I/O?
-        String path = context.getRealPath(pathname);
-        if (path != null) {
-            return (path);
-        }
-
-        // Does a copy of this file already exist in our temporary directory
-        File dir = (File)
-                context.getAttribute("javax.servlet.context.tempdir");
-        File file = new File(dir, "struts-example-database.xml");
-        if (file.exists()) {
-            return (file.getAbsolutePath());
-        }
-
-        // Copy the static resource to a temporary file and return its path
-        InputStream is =
-                context.getResourceAsStream(pathname);
-        BufferedInputStream bis = new BufferedInputStream(is, 1024);
-        FileOutputStream os =
-                new FileOutputStream(file);
-        BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
-        byte buffer[] = new byte[1024];
-        while (true) {
-            int n = bis.read(buffer);
-            if (n <= 0) {
-                break;
-            }
-            bos.write(buffer, 0, n);
-        }
-        bos.close();
-        bis.close();
-        return (file.getAbsolutePath());
-
-    }
-
-
-}
diff --git a/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java b/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java
deleted file mode 100644
index 0984a2e..0000000
--- a/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package mailreader2;
-
-import com.opensymphony.xwork2.Action;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.interceptor.Interceptor;
-import org.apache.struts.apps.mailreader.dao.User;
-
-import java.util.Map;
-
-public class AuthenticationInterceptor implements Interceptor  {
-
-    public void destroy () {}
-
-    public void init() {}
-
-    public String intercept(ActionInvocation actionInvocation) throws Exception {
-
-        Map session = actionInvocation.getInvocationContext().getSession();
-
-        User user = (User) session.get(Constants.USER_KEY);
-
-        boolean isAuthenticated = (null!=user) && (null!=user.getDatabase());
-
-        if (!isAuthenticated) {
-            return Action.LOGIN;            
-        }
-        else {
-            return actionInvocation.invoke();
-        }
-
-    }
-}
diff --git a/mailreader/src/main/java/mailreader2/Constants.java b/mailreader/src/main/java/mailreader2/Constants.java
deleted file mode 100644
index 98ff538..0000000
--- a/mailreader/src/main/java/mailreader2/Constants.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-/**
- * <p> Manifest constants for the MailReader application. </p>
- */
-public final class Constants {
-
-    // --- Tokens ----
-
-    /**
-     * <p> The token representing a "cancel" request. </p>
-     */
-    public static final String CANCEL = "cancel";
-
-    /**
-     * <p> The token representing a "create" task. </p>
-     */
-    public static final String CREATE = "Create";
-
-    /**
-     * <p> The application scope attribute under which our user database is
-     * stored. </p>
-     */
-    public static final String DATABASE_KEY = "database";
-
-    /**
-     * <p> The token representing a "edit" task. </p>
-     */
-    public static final String DELETE = "Delete";
-
-    /**
-     * <p> The token representing a "edit" task. </p>
-     */
-    public static final String EDIT = "Edit";
-
-    /**
-     * <p> The package name for this application. </p>
-     */
-    public static final String PACKAGE = "org.apache.struts.apps.mailreader";
-
-    /**
-     * <p> The session scope attribute under which the Subscription object
-     * currently selected by our logged-in User is stored. </p>
-     */
-    public static final String SUBSCRIPTION_KEY = "subscription";
-
-    /**
-     * <p> The session scope attribute under which the User object for the
-     * currently logged in user is stored. </p>
-     */
-    public static final String USER_KEY = "user";
-
-    /**
-     * <p>The token representing the "Host" property.
-     */
-    public static final String HOST = "host";
-
-
-    // ---- Error Messages ----
-
-    /**
-     * <p>
-     * A static message in case message resource is not loaded.
-     * </p>
-     */
-    public static final String ERROR_MESSAGES_NOT_LOADED =
-            "ERROR:  Message resources not loaded -- check servlet container logs for error messages.";
-
-    /**
-     * <p>
-     * A static message in case database resource is not loaded.
-     * <p>
-     */
-    public static final String ERROR_DATABASE_NOT_LOADED =
-            "ERROR:  User database not loaded -- check servlet container logs for error messages.";
-
-    /**
-     * <p>
-     * A standard key from the message resources file, to test if it is available.
-     * <p>
-     */
-    public static final String ERROR_DATABASE_MISSING = "error.database.missing";
-
-    /**
-     * <P>
-     * A "magic" username to trigger an ExpiredPasswordException for testing.
-     *</p>
-     */
-    public static final String EXPIRED_PASSWORD_EXCEPTION = "ExpiredPasswordException";
-
-    /**
-     * <p>
-     * Name of field to associate with authentification errors.
-     * <p>
-     */
-    public static final String PASSWORD_MISMATCH_FIELD = "password";
-
-    // ---- Log Messages ----
-
-    /**
-     * <p> Message to log if saving a user fails. </p>
-     */
-    public static final String LOG_DATABASE_SAVE_ERROR =
-            " Unexpected error when saving User: ";
-
-
-}
diff --git a/mailreader/src/main/java/mailreader2/Login-validation.xml b/mailreader/src/main/java/mailreader2/Login-validation.xml
deleted file mode 100644
index 1a65930..0000000
--- a/mailreader/src/main/java/mailreader2/Login-validation.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
-
-<validators>
-    <field name="username">
-        <field-validator type="requiredstring">
-            <message key="error.username.required"/>
-        </field-validator>
-    </field>
-    <field name="password">
-        <field-validator type="requiredstring">
-            <message key="error.password.required"/>
-        </field-validator>
-    </field>
-</validators>
diff --git a/mailreader/src/main/java/mailreader2/Login.java b/mailreader/src/main/java/mailreader2/Login.java
deleted file mode 100644
index 14e24fd..0000000
--- a/mailreader/src/main/java/mailreader2/Login.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
-import org.apache.struts.apps.mailreader.dao.User;
-
-/**
- * <p> Validate a user login. </p>
- */
-public final class Login extends MailreaderSupport {
-
-    public String execute() throws ExpiredPasswordException  {
-
-        User user = findUser(getUsername(), getPassword());
-
-        if (user != null) {
-            setUser(user);
-        }
-
-        if (hasErrors()) {
-            return INPUT;
-        }
-
-       return SUCCESS;
-
-    }
-
-}
diff --git a/mailreader/src/main/java/mailreader2/Logout.java b/mailreader/src/main/java/mailreader2/Logout.java
deleted file mode 100644
index 564a031..0000000
--- a/mailreader/src/main/java/mailreader2/Logout.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-/**
- * <p> Log user out of the current session. </p>
- */
-public class Logout extends MailreaderSupport {
-
-    public String execute() {
-
-        setUser(null);
-
-        return SUCCESS;
-    }
-}
diff --git a/mailreader/src/main/java/mailreader2/MailreaderSupport.java b/mailreader/src/main/java/mailreader2/MailreaderSupport.java
deleted file mode 100644
index 5b91694..0000000
--- a/mailreader/src/main/java/mailreader2/MailreaderSupport.java
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-import com.opensymphony.xwork2.ActionSupport;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
-import org.apache.struts.apps.mailreader.dao.Subscription;
-import org.apache.struts.apps.mailreader.dao.User;
-import org.apache.struts.apps.mailreader.dao.UserDatabase;
-import org.apache.struts.apps.mailreader.dao.impl.memory.MemorySubscription;
-import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUser;
-import org.apache.struts2.interceptor.ApplicationAware;
-import org.apache.struts2.interceptor.SessionAware;
-
-import java.util.Map;
-
-/**
- * <p> Base Action for MailreaderSupport application. </p>
- * <p/>
- * <p> Note that this class does NOT implement model driven because of the way
- * the pre-existing model is designed. The MailReader DAO includes immutable
- * fields that can only be set on construction, and some objects do not have a
- * default construction. One approach would be to mirror all the DAO
- * properties on the Actions. As an alternative, this implementations uses the
- * DAO properties where possible, and uses local Action properties only as
- * needed. To create new objects, a blank temporary object is constructed, and
- * the page uses a mix of local Action properties and DAO properties. When the
- * new object is to be saved, the local Action properties are used to create
- * the object using the DAO factory methods, the input values are copied from
- * the temporary object, and the new object is saved. It's kludge, but it
- * avoids creating unnecessary local properties. Pick your poison.</p>
- */
-public class MailreaderSupport extends ActionSupport
-        implements SessionAware, ApplicationAware {
-
-    /**
-     * Return CANCEL so apropriate result can be selected.
-     * @return "cancel" so apropriate result can be selected.
-     */
-    public String cancel() {
-        return Constants.CANCEL;
-    }
-
-    /**
-     * Convenience method to copy User properties.
-     **/
-    protected void copyUser(User source, User target) {
-      if ((source==null) || (target==null)) return;
-      target.setFromAddress(source.getFromAddress());
-      target.setFullName(source.getFullName());
-      target.setPassword(source.getPassword());
-      target.setReplyToAddress(source.getReplyToAddress());
-    }
-
-    /**
-     * Convenience method to copy Subscription properties.
-     **/
-    protected void copySubscription(Subscription source, Subscription target) {
-      if ((source==null) || (target==null)) return;
-      target.setAutoConnect(source.getAutoConnect());
-      target.setPassword(source.getPassword());
-      target.setType(source.getType());
-      target.setUsername(source.getUsername());
-    }
-
-
-    // ---- ApplicationAware ----
-
-    /**
-     * <p>Field to store application context or its proxy.</p>
-     * <p/>
-     * <p>The application context lasts for the life of the application. A
-     * reference to the database is stored in the application context at
-     * startup.</p>
-     */
-    private Map application;
-
-    /**
-     * <p>Store a new application context.</p>
-     *
-     * @param value A Map representing application state
-     */
-    public void setApplication(Map value) {
-        application = value;
-    }
-
-    /**
-     * <p>Provide application context.</p>
-     */
-    public Map getApplication() {
-        return application;
-    }
-
-    // ---- SessionAware ----
-
-    /**
-     * <p>Field to store session context, or its proxy.</p>
-     */
-    private Map session;
-
-    /**
-     * <p>Store a new session context.</p>
-     *
-     * @param value A Map representing session state
-     */
-    public void setSession(Map value) {
-        session = value;
-    }
-
-    /**
-     * <p>Provide session context.</p>
-     *
-     * @return session context
-     */
-    public Map getSession() {
-        return session;
-    }
-
-    // ---- Task property (utilized by UI) ----
-
-    /**
-     * <p>Field to store workflow task.</p>
-     * <p/>
-     * <p>The Task is used to track the state of the CRUD workflows. It can be
-     * set to Constant.CREATE, Constant.EDIT, or Constant.DELETE as
-     * needed.</p>
-     */
-    private String task = null;
-
-
-    /**
-     * <p>Provide worklow task.</p>
-     *
-     * @return Returns the task.
-     */
-    public String getTask() {
-        return task;
-    }
-
-    /**
-     * <p>Store new workflow task.</p>
-     *
-     * @param value The task to set.
-     */
-    public void setTask(String value) {
-        task =  value;
-    }
-
-    // ---- Token property (utilized by UI) ----
-
-    /**
-     * <p>Field to store double-submit guard.</p>
-     */
-    private String token = null;
-
-
-    /**
-     * <p>Provide Token.</p>
-     *
-     * @return Returns the token.
-     */
-    public String getToken() {
-        return token;
-    }
-
-    /**
-     * <p>Store new Token.</p>
-     *
-     * @param value The token to set.
-     */
-    public void setToken(String value) {
-        token =  value;
-    }
-
-
-    // ---- Host property ----
-
-    /**
-     * <p>Field to store Subscription host.</p>
-     * <p/>
-     * <p> The host is an immutable property of the Subscrtion DAP object, so
-     * we need to store it locally until we are ready to create the
-     * Subscription. </p>
-     */
-    private String host;
-
-    /**
-     * <p>Provide tSubscription host.</p>
-     *
-     * @return host property
-     */
-    public String getHost() {
-        return host;
-    }
-
-    /**
-     * <p>Store new Subscription host.</p>
-     *
-     * @param value
-     */
-    public void setHost(String value) {
-        host = value;
-    }
-
-    // ---- Password property ----
-
-    /**
-     * <p>Field to store User password property.</p>
-     * <p/>
-     * <p>The User DAO object password proerty is immutable, so we store it
-     * locally until we are ready to create the object.</p>
-     */
-    private String password = null;
-
-
-    /**
-     * <p>Provide User password</p>
-     *
-     * @return Returns the password.
-     */
-    public String getPassword() {
-        return password;
-    }
-
-    /**
-     * <p>Store new User Password</p>
-     *
-     * @param value The password to set.
-     */
-    public void setPassword(String value) {
-        password = value;
-    }
-
-    // ---- Password2 property (confirmation) ----
-
-    /**
-     * <p>Field to store the User password confirmation.</p>
-     * <p/>
-     * <p>When a User object is created, we ask the client to enter the
-     * password twice, to help ensure the password is being typed
-     * correctly.</p>
-     */
-    private String password2 = null;
-
-
-    /**
-     * <p>Provide the User password confirmation.</p>
-     *
-     * @return Returns the confirmationpassword.
-     */
-    public String getPassword2() {
-        return password2;
-    }
-
-    /**
-     * <p>Store a new User password confirmation.</p>
-     *
-     * @param value The confirmation password to set.
-     */
-    public void setPassword2(String value) {
-        password2 = value;
-    }
-
-    // ---- Username property ----
-
-    /**
-     * <p>Field to store User username.</p>
-     * <p/>
-     * <p>The User DAO object password proerty is immutable, so we store it
-     * locally until we are ready to create the object.</p>
-     */
-    private String username = null;
-
-
-    /**
-     * <p>Provide User username.</p>
-     *
-     * @return Returns the User username.
-     */
-    public String getUsername() {
-        return username;
-    }
-
-    /**
-     * <p>Store new User username</p>
-     *
-     * @param value The username to set.
-     */
-    public void setUsername(String value) {
-        username = value;
-    }
-
-    // ---- Database property ----
-
-    /**
-     * <p>Provide reference to UserDatabase, or null if the database is not
-     * available. </p>
-     *
-     * @return a reference to the UserDatabase or null if the database is not
-     *         available
-     */
-    public UserDatabase getDatabase() {
-        Object db = getApplication().get(Constants.DATABASE_KEY);
-        if (db == null) {
-            this.addActionError(getText("error.database.missing"));
-        }
-        return (UserDatabase) db;
-    }
-
-    /**
-     * <p>Store a new reference to UserDatabase</p>
-     *
-     * @param database
-     */
-    public void setDatabase(UserDatabase database) {
-        getApplication().put(Constants.DATABASE_KEY, database);
-    }
-
-    // ---- User property ----
-
-    /**
-     * <p>Provide reference to User object for authenticated user.</p>
-     *
-     * @return User object for authenticated user.
-     */
-    public User getUser() {
-        return (User) getSession().get(Constants.USER_KEY);
-    }
-
-    /**
-     * <p>Store new reference to User Object.</p>
-     *
-     * @param user User object for authenticated user
-     */
-    public void setUser(User user) {
-        getSession().put(Constants.USER_KEY, user);
-    }
-
-    /**
-     * <p>Obtain User object from database, or return null if the credentials
-     * are not found or invalid.</p>
-     *
-     * @param username User username
-     * @param password User password
-     * @return User object or null if not found
-     * @throws ExpiredPasswordException
-     */
-    public User findUser(String username, String password)
-            throws ExpiredPasswordException {
-        // FIXME: Stupid testing hack to compensate for inadequate DAO layer
-        if (Constants.EXPIRED_PASSWORD_EXCEPTION.equals(username)) {
-            throw new ExpiredPasswordException(Constants.EXPIRED_PASSWORD_EXCEPTION);
-        }
-
-        User user = getDatabase().findUser(username);
-        if ((user != null) && !user.getPassword().equals(password)) {
-            user = null;
-        }
-        if (user == null) {
-            this.addFieldError(Constants.PASSWORD_MISMATCH_FIELD,
-                    getText("error.password.mismatch"));
-        }
-        return user;
-    }
-
-    /**
-     * <p><code>Log</code> instance for this application. </p>
-     */
-    protected Logger log = LogManager.getLogger(Constants.PACKAGE);
-
-    /**
-     * <p> Persist the User object, including subscriptions, to the database.
-     * </p>
-     *
-     * @throws java.lang.Exception on database error
-     */
-    public void saveUser() throws Exception {
-        try {
-            getDatabase().save();
-        } catch (Exception e) {
-            String message = Constants.LOG_DATABASE_SAVE_ERROR + getUser()
-                    .getUsername();
-            log.error(message, e);
-            throw new Exception(message, e);
-        }
-    }
-
-    public void createInputUser() {
-        User user = new MemoryUser(null, null);
-        setUser(user);
-    }
-
-    /**
-     * <p> Verify input for creating a new user, create the user, and process
-     * the login. </p>
-     *
-     * @return A new User and empty Errors if create succeeds, or null and
-     *         Errors if create fails
-     */
-    public User createUser(String username, String password) {
-
-        UserDatabase database = getDatabase();
-        User user;
-
-        try {
-            user = database.findUser(username);
-         }
-
-        catch (ExpiredPasswordException e) {
-            user = getUser(); // Just so that it is not null
-        }
-
-        if (user != null) {
-            this.addFieldError("username", "error.username.unique");
-            return null;
-        }
-
-        return database.createUser(username);
-    }
-
-    // Since user.username is immutable, we have to use some local properties
-
-    /**
-     * <p>Use the current User object to create a new User object, and make
-     * the new User object the authenticated user.</p>
-     * <p/>
-     * <p>The "current" User object is usually a temporary object being used
-     * to capture input.</p>
-     *
-     * @param _username User username
-     * @param _password User password
-     */
-    public void copyUser(String _username, String _password) {
-        User input = getUser();
-        input.setPassword(_password);
-        User user = createUser(_username, _password);
-        if (null != user) {
-            copyUser(input,user);
-            setUser(user);
-        }
-    }
-
-    // ---- Subscription property ----
-
-    /**
-     * <p>Obtain the cached Subscription object, if any. </p>
-     *
-     * @return Cached Subscription object or null
-     */
-    public Subscription getSubscription() {
-        return (Subscription) getSession().get(Constants.SUBSCRIPTION_KEY);
-    }
-
-    /**
-     * <p>Store new User Subscription.</p>
-     *
-     * @param subscription
-     */
-    public void setSubscription(Subscription subscription) {
-        getSession().put(Constants.SUBSCRIPTION_KEY, subscription);
-    }
-
-    /**
-     * <p> Obtain User Subscription object for the given host, or return null
-     * if not found. </p>
-     *
-     * <p>It would be possible for this code to throw a NullPointerException,
-     * but the ExceptionHandler in the xwork.xml will catch that for us.</p>
-     *
-     * @return The matching Subscription or null
-     */
-    public Subscription findSubscription(String host) {
-        Subscription subscription;
-        subscription = getUser().findSubscription(host);
-        return subscription;
-    }
-
-    /**
-     * <p>Obtain uSER Subscription for the local Host property.</p>
-     * <p/>
-     * <p>Usually, the host property will be set from the client request,
-     * because it was embedded in a link to the Subcription action.
-     *
-     * @return Subscription or null if not found
-     */
-    public Subscription findSubscription() {
-        return findSubscription(getHost());
-    }
-
-    /**
-     * <p>Provide a "temporary" User Subscription object that can be used to
-     * capture input values.</p>
-     */
-    public void createInputSubscription() {
-        Subscription sub = new MemorySubscription(getUser(), null);
-        setSubscription(sub);
-        setHost(sub.getHost());
-    }
-
-    /**
-     * <p>Provide new User Subscription object for the given host, or null if
-     * the host is not unique.</p>
-     *
-     * @param host
-     * @return New User Subscription object or null
-     */
-    public Subscription createSubscription(String host) {
-
-        Subscription sub;
-
-        sub = findSubscription(host);
-
-        if (null != sub) {
-            // FIXME - localization - "error.host.unique")
-            addFieldError(Constants.HOST,"That hostname is already defined");
-            return null;
-        }
-
-        return getUser().createSubscription(host);
-    }
-
-    /**
-     * <p>Create a new Subscription from the current Subscription object,
-     * making the new Subscription the current Subscription. </p>
-     * <p/>
-     * <p>Usually, the "current" Subscription is a temporary object being used
-     * to capture input values.</p>
-     *
-     * @param host
-     */
-    public void copySubscription(String host) {
-        Subscription input = getSubscription();
-        Subscription sub = createSubscription(host);
-        if (null != sub) {
-            copySubscription(input, sub);
-            setSubscription(sub);
-            setHost(sub.getHost());
-        }
-    }
-
-    /**
-     * <p>Delete the current Subscription object from the database.</p>
-     */
-    public void removeSubscription()  {
-        getUser().removeSubscription(getSubscription());
-        getSession().remove(Constants.SUBSCRIPTION_KEY);
-    }
-
-    /**
-     * <p>Provide MailServer Host for current User Subscription.</p>
-     *
-     * @return MailServer Host for current User Subscription
-     */
-    public String getSubscriptionHost() {
-        Subscription sub = getSubscription();
-        if (null == sub) {
-            return null;
-        }
-        return sub.getHost();
-    }
-
-}
diff --git a/mailreader/src/main/java/mailreader2/MailreaderSupport.properties b/mailreader/src/main/java/mailreader2/MailreaderSupport.properties
deleted file mode 100644
index 4e79b02..0000000
--- a/mailreader/src/main/java/mailreader2/MailreaderSupport.properties
+++ /dev/null
@@ -1,97 +0,0 @@
-button.cancel=Cancel
-button.confirm=Confirm
-button.doSubmit=DO_SUBMIT
-button.doReset=DO_RESULT
-button.doCancel=org.apache.struts.taglib.html.CANCEL
-button.reset=Reset
-button.save=Save
-button.logon=Log on
-change.message=Your password has expired.  Please ask the system administrator to change it.
-change.try=Try Again
-change.title=Password Has Expired
-database.load=Cannot load database from {0}
-error.database.missing=User database is missing, cannot validate login credentials
-error.fromAddress.format=Invalid format for From Address
-error.fromAddress.required=From Address is required
-error.fullName.required=Full Name is required
-error.host.required=Mail Server is required
-error.noSubscription=No Subscription bean in user session
-error.password.expired=Your password has expired for username {0}
-error.password.required=Password is required
-error.password2.required=Confirmation password is required
-error.password.match=Password and confirmation password must match
-error.password.mismatch=Invalid username and/or password, please try again
-error.replyToAddress.format=Invalid format for Reply To Address
-struts.messages.invalid.token=Cannot submit this form out of order
-error.type.invalid=Server Type must be 'imap' or 'pop3'
-error.type.required=Server Type is required
-error.username.required=Username is required
-error.username.unique=That username is already in use - please select another
-errors.footer=</ul><hr>
-errors.header=<h3><font color="red">Validation Error</font></h3><p>You must correct the following error(s) before proceeding:</p><ul>
-errors.prefix=<li>
-errors.suffix=</li>
-errors.ioException=I/O exception rendering error messages: {0}
-expired.password=User Password has expired for {0}
-heading.autoConnect=Auto
-heading.subscriptions=Current Subscriptions
-heading.host=Host Name
-heading.user=User Name
-heading.type=Server Type
-heading.action=Action
-index.heading=MailReader Demonstration Application Options
-index.login=Log on to the MailReader Demonstration Application
-index.registration=Register with the MailReader Demonstration Application
-index.title=MailReader Demonstration Application
-index.tour=A Walking Tour of the MailReader Demonstration Application
-linkSubscription.io=I/O Error: {0}
-linkSubscription.noSubscription=No subscription under attribute {0}
-linkUser.io=I/O Error: {0}
-linkUser.noUser=No user under attribute {0}
-login.title=MailReader Demonstration Application - Login
-mainMenu.heading=Main Menu Options for 
-mainMenu.logout=Log off MailReader Demonstration Application
-mainMenu.registration=Edit your user registration profile
-mainMenu.title=MailReader Demonstration Application - Main Menu
-option.imap=IMAP Protocol
-option.pop3=POP3 Protocol
-# prompt.
-host=Mail Server
-password=Password
-password2=(Repeat) Password
-username=Username
-
-registration.addSubscription=Add
-registration.deleteSubscription=Delete
-registration.editSubscription=Edit
-registration.title.create=Register for the MailReader Demonstration Application
-registration.title.edit=Edit Registration for the MailReader Demonstration Application
-
-subscription.autoConnect=Auto Connect
-subscription.password=Mail Password
-subscription.type=Server Type
-subscription.username=Mail Username
-subscription.title.create=Create New Mail Subscription
-subscription.title.delete=Delete Existing Mail Subscription
-subscription.title.edit=Edit Existing Mail Subscription
-
-user.fromAddress=From Address
-user.fullName=Full Name
-user.replyToAddress=Reply To Address
-
-# Standard error messages for validator framework checks
-errors.required=${getText(fieldName)} is required.
-errors.minlength=${getText(fieldName)} cannot be less than {1} characters.
-errors.maxlength=${getText(fieldName)} cannot be greater than {1} characters.
-errors.invalid=${getText(fieldName)} is invalid.
-errors.byte=${getText(fieldName)} must be an byte.
-errors.short=${getText(fieldName)} must be an short.
-errors.integer=${getText(fieldName)} must be an integer.
-errors.long=${getText(fieldName)} must be an long.
-errors.float=${getText(fieldName)} must be an float.
-errors.double=${getText(fieldName)} must be an double.
-errors.date=${getText(fieldName)} is not a date.
-errors.range=${getText(fieldName)} is not in the range ${minLength} through ${maxLength}.
-errors.creditcard=${getText(fieldName)} is not a valid credit card number.
-errors.email=${getText(fieldName)} is an invalid e-mail address.
-errors.literal=${getText(fieldName)}
diff --git a/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties b/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties
deleted file mode 100644
index 2b9d2e4..0000000
--- a/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties
+++ /dev/null
@@ -1,89 +0,0 @@
-button.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
-button.confirm=\u78ba\u8a8d
-button.reset=\u30ea\u30bb\u30c3\u30c8
-button.save=\u4fdd\u5b58
-change.message=\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F\u3002\u30B7\u30B9\u30C6\u30E0\u7BA1\u7406\u8005\u306B\u304A\u554F\u3044\u5408\u308F\u305B\u4E0B\u3055\u3044
-change.try=\u518D\u8A66\u884C
-change.title=\u30d1\u30b9\u30ef\u30fc\u30c9\u671f\u9650\u5207\u308c
-database.load= {0} \u304B\u3089\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30ED\u30FC\u30C9\u3067\u304D\u307E\u305B\u3093
-error.database.missing=\u30E6\u30FC\u30B6\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u30ED\u30B0\u30AA\u30F3\u306E\u8A8D\u8A3C\u304C\u51FA\u6765\u307E\u305B\u3093
-error.fromAddress.format=From\u30A2\u30C9\u30EC\u30B9\u306E\u66F8\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093
-error.fromAddress.required=From\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
-error.fullName.required=\u30D5\u30EB\u30CD\u30FC\u30E0\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
-error.host.required=\u30E1\u30FC\u30EB\u30B5\u30FC\u30D0\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
-error.noSubscription=Subscription bean \u304c\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u4e2d\u306b\u3042\u308a\u307e\u305b\u3093
-error.password.expired=\u30E6\u30FC\u30B6 {0} \u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F
-error.password.required=\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u5FC5\u8981\u3067\u3059
-error.password2.required=\u30D1\u30B9\u30EF\u30FC\u30C9(\u78BA\u8A8D\u7528)\u304C\u5FC5\u8981\u3067\u3059
-error.password.match=\u30D1\u30B9\u30EF\u30FC\u30C9\u3068\u78BA\u8A8D\u7528\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u4E00\u81F4\u3057\u3066\u3044\u307E\u305B\u3093
-error.password.mismatch=\u30E6\u30FC\u30B6\u540D\u307E\u305F\u306F\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u4E0D\u6B63\u3067\u3059\u3002\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
-error.replyToAddress.format=\u8FD4\u4FE1\u30A2\u30C9\u30EC\u30B9\u306E\u66F8\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093
-struts.messages.invalid.token=\u3053\u306E\u30D5\u30A9\u30FC\u30E0\u306E\u5185\u5BB9\u304C\u6B63\u3057\u304F\u306A\u3044\u305F\u3081\u9001\u4FE1\u3059\u308B\u3053\u3068\u304C\u51FA\u6765\u307E\u305B\u3093
-error.type.invalid=\u30B5\u30FC\u30D0\u30BF\u30A4\u30D7\u306F 'imap' \u304B 'pop3'\u306E\u3069\u3061\u3089\u304B\u3067\u306A\u3051\u308C\u3070\u306A\u308A\u307E\u305B\u3093
-error.type.required=\u30B5\u30FC\u30D0\u30BF\u30A4\u30D7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
-error.username.required=\u30E6\u30FC\u30B6\u540D\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
-error.username.unique=\u305D\u306E\u30E6\u30FC\u30B6\u540D\u306F\u65E2\u306B\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059\u3002 \u5225\u306E\u30E6\u30FC\u30B6\u540D\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044
-errors.footer=</ul><hr>
-errors.header=<h3><font color="red">\u5165\u529b\u30c1\u30a7\u30c3\u30af\u30a8\u30e9\u30fc</font></h3><p>\u4ee5\u4e0b\u306e\u30a8\u30e9\u30fc\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044:</p><ul>
-errors.prefix=<li>
-errors.suffix=</li>
-errors.ioException=I/O\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f: {0}
-expired.password=\u30E6\u30FC\u30B6 {0} \u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F
-heading.autoConnect=\u81ea\u52d5\u63a5\u7d9a
-heading.subscriptions=\u73fe\u5728\u306e\u8cfc\u8aad\u60c5\u5831
-heading.host=\u30db\u30b9\u30c8\u540d
-heading.user=\u30e6\u30fc\u30b6\u540d
-heading.type=\u30b5\u30fc\u30d0\u30bf\u30a4\u30d7
-heading.action=\u64cd\u4f5c
-index.heading=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 \u30aa\u30d7\u30b7\u30e7\u30f3
-index.login=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30ed\u30b0\u30aa\u30f3
-index.registration=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e6\u30fc\u30b6\u767b\u9332
-index.title=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3(Struts 1.1-dev)
-index.tour=\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u6563\u7b56\u3059\u308b
-linkSubscription.io=I/O\u30a8\u30e9\u30fc: {0}
-linkSubscription.noSubscription=\u5c5e\u6027 {0} \u306b\u8cfc\u8aad\u60c5\u5831\u304c\u5b58\u5728\u3057\u307e\u305b\u3093  
-linkUser.io=I/O\u30a8\u30e9\u30fc: {0}
-linkUser.noUser=\u5c5e\u6027 {0} \u306b\u30e6\u30fc\u30b6\u60c5\u5831\u304c\u5b58\u5728\u3057\u307e\u305b\u3093
-login.title=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30ed\u30b0\u30aa\u30f3
-mainMenu.heading=\u30e1\u30a4\u30f3\u30e1\u30cb\u30e5\u30fc
-mainMenu.logout=MailReader \u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ed\u30b0\u30aa\u30d5
-mainMenu.registration=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u7de8\u96c6
-mainMenu.title=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e1\u30a4\u30f3\u30e1\u30cb\u30e5\u30fc
-option.imap=IMAP \u30d7\u30ed\u30c8\u30b3\u30eb
-option.pop3=POP3 \u30d7\u30ed\u30c8\u30b3\u30eb
-# prompt.
-autoConnect=\u81ea\u52d5\u63a5\u7d9a
-fromAddress=From\u30a2\u30c9\u30ec\u30b9
-fullName=\u30d5\u30eb\u30cd\u30fc\u30e0
-mailHostname=\u30e1\u30fc\u30eb\u30b5\u30fc\u30d0
-mailPassword=\u30e1\u30fc\u30eb\u30d1\u30b9\u30ef\u30fc\u30c9
-mailServerType=\u30b5\u30fc\u30d0\u30bf\u30a4\u30d7
-mailUsername=\u30e1\u30fc\u30eb\u30e6\u30fc\u30b6\u540d
-.password=\u30d1\u30b9\u30ef\u30fc\u30c9
-password2=\u30d1\u30b9\u30ef\u30fc\u30c9(\u78ba\u8a8d\u7528)
-replyToAddress=\u8fd4\u4fe1\u30a2\u30c9\u30ec\u30b9
-username=\u30e6\u30fc\u30b6\u540d
-registration.addSubscription=\u65b0\u898f\u4f5c\u6210
-registration.deleteSubscription=\u524a\u9664
-registration.editSubscription=\u7de8\u96c6
-registration.title.create=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e6\u30fc\u30b6\u767b\u9332
-registration.title.edit=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6
-subscription.title.create=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u65b0\u898f\u4f5c\u6210
-subscription.title.delete=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u524a\u9664
-subscription.title.edit=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u7de8\u96c6
-
-# Standard error messages for validator framework checks
-errors.required=${getText(fieldName)} \u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
-errors.minlength=${getText(fieldName)} \u306f {1} \u6587\u5b57\u4ee5\u4e0a\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.maxlength=${getText(fieldName)} \u306f {2} \u6587\u5b57\u4ee5\u4e0b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.invalid=${getText(fieldName)} \u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
-errors.byte=${getText(fieldName)} \u306fbyte\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.short=${getText(fieldName)} \u306fshort\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.integer=${getText(fieldName)} \u306finteger\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.long=${getText(fieldName)} \u306flong\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.float=${getText(fieldName)} \u306ffloat\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.double=${getText(fieldName)} \u306fdouble\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.date=${getText(fieldName)} \u306f\u65e5\u4ed8\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
-errors.range=${getText(fieldName)} \u306f {1} \u304b\u3089 {2} \u306e\u9593\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
-errors.creditcard=${getText(fieldName)} \u306f\u6b63\u3057\u3044\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u756a\u53f7\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
-errors.email=${getText(fieldName)} \u306f\u6b63\u3057\u3044\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
diff --git a/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties b/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties
deleted file mode 100644
index 6c7a88b..0000000
--- a/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties
+++ /dev/null
@@ -1,89 +0,0 @@
-button.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
-button.confirm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c
-button.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
-button.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
-change.message=Your password has expired.  Please ask the system administrator to change it.
-change.try=Try Again
-change.title=Password Has Expired
-database.load=\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430 \u0438\u0437 {0}
-error.database.missing=\u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f - \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.
-error.fromAddress.format=\u0412 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:' \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435.
-error.fromAddress.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:'.
-error.fullName.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f.
-error.host.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440.
-error.noSubscription=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0432 \u0441\u0435\u0441\u0441\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
-error.password.expired=Your password has expired for username {0}
-error.password.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c.
-error.password2.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f.
-error.password.match=\u041f\u0430\u0440\u043e\u043b\u044c \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442.
-error.password.mismatch=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u044f \u0438/\u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c - \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043d\u043e\u0432\u0430.
-error.replyToAddress.format=\u0412 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430:' \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435.
-struts.messages.invalid.token=\u042d\u0442\u0430 \u0444\u043e\u0440\u043c\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 - \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.
-error.type.invalid=\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043b\u0438\u0448\u044c 'imap' \u0438\u043b\u0438 'pop3'
-error.type.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430
-error.username.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
-error.username.unique=\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f - \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f.
-errors.footer=</ul><hr>
-errors.header=<h3><font color="red">\u041e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445</font></h3><p>\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043d\u0438\u0436\u0435 \u043e\u0448\u0438\u0431\u043a\u0438:</p><ul>
-errors.prefix=<li>
-errors.suffix=</li>
-errors.ioException=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445: {0}
-expired.password=User Password has expired for {0}
-heading.autoConnect=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
-heading.subscriptions=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-heading.host=\u0421\u0435\u0440\u0432\u0435\u0440
-heading.user=\u0418\u043c\u044f
-heading.type=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430
-heading.action=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435
-index.heading=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b'
-index.login=\u0412\u043e\u0439\u0442\u0438 \u043a\u0430\u043a \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c
-index.registration=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
-index.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' (Struts 1.1-dev)
-index.tour=\u041e\u0431\u0437\u043e\u0440 \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b'
-linkSubscription.io=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 (\u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438): {0}
-linkSubscription.noSubscription=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.
-linkUser.io=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 (\u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f): {0}
-linkUser.noUser=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.
-login.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b - \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u043c\u0435\u043d\u0438 \u0438 \u043f\u0430\u0440\u043e\u043b\u044f.
-mainMenu.heading=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044e \u0434\u043b\u044f
-mainMenu.logout=\u0412\u044b\u0439\u0442\u0438
-mainMenu.registration=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
-mainMenu.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' - \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e
-option.imap=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b IMAP 
-option.pop3=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b POP3 
-# prompt.
-autoConnect=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435:
-fromAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:
-fullName=\u041f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f:
-mailHostname=\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440:
-mailPassword=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
-mailServerType=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
-mailUsername=\u0418\u043c\u044f \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
-password=\u041f\u0430\u0440\u043e\u043b\u044c:
-password2=(\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) \u041f\u0430\u0440\u043e\u043b\u044c:
-replyToAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430:
-username=\u0418\u043c\u044f:
-registration.addSubscription=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
-registration.deleteSubscription=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-registration.editSubscription=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-registration.title.create=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
-registration.title.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438
-subscription.title.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
-subscription.title.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
-subscription.title.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
-
-# Standard error messages for validator framework checks
-errors.required=${getText(fieldName)} is required.
-errors.minlength=${getText(fieldName)} cannot be less than {1} characters.
-errors.maxlength=${getText(fieldName)} cannot be greater than {2} characters.
-errors.invalid=${getText(fieldName)} is invalid.
-errors.byte=${getText(fieldName)} must be an byte.
-errors.short=${getText(fieldName)} must be an short.
-errors.integer=${getText(fieldName)} must be an integer.
-errors.long=${getText(fieldName)} must be an long.
-errors.float=${getText(fieldName)} must be an float.
-errors.double=${getText(fieldName)} must be an double.
-errors.date=${getText(fieldName)} is not a date.
-errors.range=${getText(fieldName)} is not in the range {1} through {2}.
-errors.creditcard=${getText(fieldName)} is not a valid credit card number.
-errors.email=${getText(fieldName)} is an invalid e-mail address.
diff --git a/mailreader/src/main/java/mailreader2/Registration-Registration_save-validation.xml b/mailreader/src/main/java/mailreader2/Registration-Registration_save-validation.xml
deleted file mode 100644
index 509ca5f..0000000
--- a/mailreader/src/main/java/mailreader2/Registration-Registration_save-validation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
-
-<validators>
-
-    <field name="password">
-        <field-validator type="requiredstring">
-            <message key="error.password.required"/>
-        </field-validator>
-        <field-validator type="stringlength">
-            <param name="trim">true</param>
-            <param name="minLength">4</param>
-            <param name="maxLength">10</param>
-            <message key="errors.range"/>
-        </field-validator>
-    </field>
-
-    <field name="password2">
-        <field-validator type="requiredstring">
-            <message key="error.password2.required"/>
-        </field-validator>
-    </field>
-
-    <validator type="expression">
-        <param name="expression">password eq password2</param>
-        <message key="error.password.match"/>
-    </validator>
-
-</validators>
diff --git a/mailreader/src/main/java/mailreader2/Registration-validation.xml b/mailreader/src/main/java/mailreader2/Registration-validation.xml
deleted file mode 100644
index a123125..0000000
--- a/mailreader/src/main/java/mailreader2/Registration-validation.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
-
-<validators>
-
-    <field name="username">
-        <field-validator type="requiredstring">
-            <message key="error.username.required"/>
-        </field-validator>
-    </field>
-
-    <field name="user.fullName">
-        <field-validator type="requiredstring">
-            <message key="error.fullName.required"/>
-        </field-validator>
-    </field>
-
-    <field name="user.fromAddress">
-        <field-validator type="requiredstring">
-            <message key="error.fromAddress.required"/>
-        </field-validator>
-        <field-validator type="email">
-            <message key="errors.email"/>
-        </field-validator>
-    </field>
-
-    <field name="user.replyToAddress">
-        <field-validator type="email">
-            <message key="errors.email"/>
-        </field-validator>
-    </field>
-
-</validators>
diff --git a/mailreader/src/main/java/mailreader2/Registration.java b/mailreader/src/main/java/mailreader2/Registration.java
deleted file mode 100644
index 41e985b..0000000
--- a/mailreader/src/main/java/mailreader2/Registration.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-import org.apache.struts.apps.mailreader.dao.User;
-
-
-/**
- * <p>Insert or update a User object to the persistent store. </p>
- */
-public class Registration extends MailreaderSupport {
-
-    /**
-     * <p>Double check that there is not a valid User login. </p>
-     *
-     * @return True if there is not a valid User login
-     */
-    private boolean isCreating() {
-        User user = getUser();
-        return (null == user) || (null == user.getDatabase());
-    }
-
-    /**
-     * <p> Retrieve User object to edit or null if User does not exist. </p>
-     *
-     * @return The "Success" result for this mapping
-     * @throws Exception on any error
-     */
-    public String input() throws Exception {
-
-        if (isCreating()) {
-            createInputUser();
-            setTask(Constants.CREATE);
-        } else {
-            setTask(Constants.EDIT);
-            setUsername(getUser().getUsername());
-            setPassword(getUser().getPassword());
-            setPassword2(getUser().getPassword());
-        }
-
-        return INPUT;
-    }
-
-    /**
-     * <p>Insert or update a Registration.</p>
-     *
-     * @return The "outcome" result code
-     * @throws Exception on any error
-     */
-    public String save() throws Exception {
-        return execute();
-    }
-
-    /**
-     * <p> Insert or update a User object to the persistent store. </p>
-     * <p/>
-     * <p> If a User is not logged in, then a new User is created and
-     * automatically logged in. Otherwise, the existing User is updated. </p>
-     *
-     * @return The "outcome" result code
-     * @throws Exception on any error
-     */
-    public String execute()
-            throws Exception {
-
-        boolean creating = Constants.CREATE.equals(getTask());
-        creating = creating && isCreating(); // trust but verify
-
-        if (creating) {
-
-            User user = findUser(getUsername(), getPassword());
-            boolean haveUser = (user != null);
-
-            if (haveUser) {
-                addActionError(getText("error.username.unique"));
-                return INPUT;
-            }
-
-            copyUser(getUsername(), getPassword());
-
-        } else {
-
-            // FIXME: Any way to call the RegisrationSave validators from here?
-            String newPassword = getPassword();
-            if (newPassword != null) {
-                String confirmPassword = getPassword2();
-                boolean matches = ((null != confirmPassword)
-                        && (confirmPassword.equals(newPassword)));
-                if (matches) {
-                    getUser().setPassword(newPassword);
-                } else {
-                    addActionError(getText("error.password.match"));
-                    return INPUT;
-                }
-            }
-        }
-
-        saveUser();
-
-        return SUCCESS;
-    }
-
-}
diff --git a/mailreader/src/main/java/mailreader2/Subscription-Subscription_save-validation.xml b/mailreader/src/main/java/mailreader2/Subscription-Subscription_save-validation.xml
deleted file mode 100644
index 177bf6c..0000000
--- a/mailreader/src/main/java/mailreader2/Subscription-Subscription_save-validation.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
-
-<validators>
-
-    <field name="subscription.username">
-        <field-validator type="requiredstring">
-            <message key="error.username.required"/>
-        </field-validator>
-    </field>
-
-    <field name="subscription.password">
-        <field-validator type="requiredstring">
-            <message key="error.password.required"/>
-        </field-validator>
-    </field>
-
-    <field name="subscription.type">
-        <field-validator type="requiredstring">
-            <message key="error.type.invalid"/>
-        </field-validator>
-    </field>
-
-</validators>
diff --git a/mailreader/src/main/java/mailreader2/Subscription-validation.xml b/mailreader/src/main/java/mailreader2/Subscription-validation.xml
deleted file mode 100644
index 917ef2a..0000000
--- a/mailreader/src/main/java/mailreader2/Subscription-validation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
-
-<validators>
-
-    <field name="host">
-        <field-validator type="requiredstring">
-            <message key="error.host.required"/>
-        </field-validator>
-    </field>
-
-</validators>
diff --git a/mailreader/src/main/java/mailreader2/Subscription.java b/mailreader/src/main/java/mailreader2/Subscription.java
deleted file mode 100644
index df12d52..0000000
--- a/mailreader/src/main/java/mailreader2/Subscription.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-import com.opensymphony.xwork2.Preparable;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * <p> Provide an Edit method for retrieving an existing subscription, and a
- * Save method for updating or inserting a subscription. </p>
- */
-public class Subscription extends MailreaderSupport
-        implements Preparable {
-
-    /**
-     * <p>Field to store list of MailServer types</p>
-     */
-    private Map types = null;
-
-    /**
-     * <p>Provide the list of MailServer types.</p>
-     *
-     * @return List of MailServer types
-     */
-    public Map getTypes() {
-        return types;
-    }
-
-    /**
-     * <p>Setup the MailerServer types and set the local Host property from
-     * the User Subscription (if any). </p>
-     */
-    public void prepare() {
-
-        Map m = new LinkedHashMap();
-        m.put("imap", "IMAP Protocol");
-        m.put("pop3", "POP3 Protocol");
-        types = m;
-
-        setHost(getSubscriptionHost());
-    }
-
-    /**
-     * <p>Setup a temporary User Subscription object to capture input
-     * values.</p>
-     *
-     * @return INPUT
-     */
-    public String input() {
-        createInputSubscription();
-        setTask(Constants.CREATE);
-        return INPUT;
-    }
-
-    /**
-     * <p>Load User Subscription for the local Host property.</p>
-     * <p/>
-     * <p>Usually, the Host is being set from the request by a link to an Edit
-     * or Delete task.</p>
-     *
-     * @return INPUT or Error, if Subscription is not found
-     */
-    public String find() {
-
-        org.apache.struts.apps.mailreader.dao.Subscription
-                sub = findSubscription();
-
-        if (sub == null) {
-            return ERROR;
-        }
-
-        setSubscription(sub);
-
-        return INPUT;
-
-    }
-
-    /**
-     * <p>Prepare to present a confirmation page before removing
-     * Subscription.</p>
-     *
-     * @return INPUT or Error, if Subscription is not found
-     */
-    public String delete() {
-
-        setTask(Constants.DELETE);
-        return find();
-    }
-
-    /**
-     * <p>Prepare to edit User Subscription.</p>
-     *
-     * @return INPUT or Error, if Subscription is not found
-     */
-    public String edit() {
-
-        setTask(Constants.EDIT);
-        return find();
-    }
-
-    /**
-     * <p> Examine the Task property and DELETE, CREATE, or save the User
-     * Subscription, as appropriate. </p>
-     *
-     * @return SUCCESS
-     * @throws Exception on a database error
-     */
-    public String save() throws Exception {
-
-        if (Constants.DELETE.equals(getTask())) {
-            removeSubscription();
-        }
-
-        if (Constants.CREATE.equals(getTask())) {
-            copySubscription(getHost());
-        }
-
-        if (hasErrors()) return INPUT;
-
-        saveUser();
-        return SUCCESS;
-    }
-
-}
diff --git a/mailreader/src/main/java/mailreader2/Welcome.java b/mailreader/src/main/java/mailreader2/Welcome.java
deleted file mode 100644
index 428ca51..0000000
--- a/mailreader/src/main/java/mailreader2/Welcome.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package mailreader2;
-
-/**
- * Verify that essential resources are available.
- */
-public class Welcome extends MailreaderSupport {
-
-    public String execute() {
-
-        // Confirm message resources loaded
-        String message = getText(Constants.ERROR_DATABASE_MISSING);
-        if (Constants.ERROR_DATABASE_MISSING.equals(message)) {
-            addActionError(Constants.ERROR_MESSAGES_NOT_LOADED);
-        }
-
-        // Confirm database loaded
-        if (null==getDatabase()) {
-             addActionError(Constants.ERROR_DATABASE_NOT_LOADED);
-        }
-
-        if (hasErrors()) {
-            return ERROR;
-        }
-        else {
-            return SUCCESS;
-        }
-    }
-}
diff --git a/mailreader/src/main/resources/LICENSE.txt b/mailreader/src/main/resources/LICENSE.txt
deleted file mode 100644
index dd5b3a5..0000000
--- a/mailreader/src/main/resources/LICENSE.txt
+++ /dev/null
@@ -1,174 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
diff --git a/mailreader/src/main/resources/NOTICE.txt b/mailreader/src/main/resources/NOTICE.txt
deleted file mode 100644
index c9bc884..0000000
--- a/mailreader/src/main/resources/NOTICE.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Apache Struts
-Copyright 2000-2015 The Apache Software Foundation
-
-This product includes software developed by
-The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/mailreader/src/main/resources/alternate.properties b/mailreader/src/main/resources/alternate.properties
deleted file mode 100644
index 03dbf27..0000000
--- a/mailreader/src/main/resources/alternate.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-password=Enter your Password here ==>
-struts.logo.path=struts-power.gif
-struts.logo.alt=Powered by Struts
diff --git a/mailreader/src/main/resources/alternate_ja.properties b/mailreader/src/main/resources/alternate_ja.properties
deleted file mode 100644
index 981adc8..0000000
--- a/mailreader/src/main/resources/alternate_ja.properties
+++ /dev/null
@@ -1 +0,0 @@
-.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b==>
diff --git a/mailreader/src/main/resources/log4j2.xml b/mailreader/src/main/resources/log4j2.xml
deleted file mode 100644
index 913b299..0000000
--- a/mailreader/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration>
-    <Appenders>
-        <Console name="STDOUT" target="SYSTEM_OUT">
-            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
-        </Console>
-    </Appenders>
-    <Loggers>
-        <Logger name="com.opensymphony.xwork2" level="info"/>
-        <Logger name="org.apache.struts2" level="info"/>
-        <Logger name="org.springframework" level="info"/>
-        <Root level="info">
-            <AppenderRef ref="STDOUT"/>
-        </Root>
-    </Loggers>
-</Configuration>
\ No newline at end of file
diff --git a/mailreader/src/main/resources/mailreader-default.xml b/mailreader/src/main/resources/mailreader-default.xml
deleted file mode 100644
index ba42b62..0000000
--- a/mailreader/src/main/resources/mailreader-default.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "http://struts.apache.org/dtds/struts-2.5.dtd">
-
-<struts>
-
-    <package name="mailreader-default" namespace="/" extends="struts-default">
-
-        <interceptors>
-
-            <interceptor name="authentication"
-                         class="mailreader2.AuthenticationInterceptor"/>
-
-            <interceptor-stack name="user" >
-                <interceptor-ref name="authentication" />
-                <interceptor-ref name="defaultStack"/>
-            </interceptor-stack>
-
-            <interceptor-stack name="user-submit" >
-                <interceptor-ref name="tokenSession" />
-                <interceptor-ref name="user"/>
-            </interceptor-stack>
-
-            <interceptor-stack name="guest" >
-                <interceptor-ref name="defaultStack"/>
-            </interceptor-stack>
-
-        </interceptors>
-
-        <default-interceptor-ref name="user"/>
-
-        <global-results>
-            <result name="error">/pages/Error.jsp</result>
-            <result name="invalid.token">/pages/Error.jsp</result>
-            <result name="login" type="redirectAction">Login_input</result>
-        </global-results>
-
-        <global-exception-mappings>
-            <exception-mapping
-                    result="error"
-                    exception="java.lang.Throwable"/>
-        </global-exception-mappings>
-
-    </package>
-
-</struts>
diff --git a/mailreader/src/main/resources/mailreader-support.xml b/mailreader/src/main/resources/mailreader-support.xml
deleted file mode 100644
index cdbc405..0000000
--- a/mailreader/src/main/resources/mailreader-support.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "http://struts.apache.org/dtds/struts-2.5.dtd">
-
-<struts>
-    <package name="mailreader-support" namespace="/" extends="mailreader-default">
-
-        <action name="Tour">
-            <result>/tour.html</result>
-            <interceptor-ref name="guest"/>
-        </action>
-
-        <action name="Welcome" class="mailreader2.Welcome">
-            <result>WEB-INF/jsp/Welcome.jsp</result>
-            <interceptor-ref name="guest"/>
-        </action>
-
-        <action name="Logout" class="mailreader2.Logout">
-            <result type="redirectAction">Welcome</result>
-        </action>
-
-        <action name="Login_*"  method="{1}" class="mailreader2.Login">
-            <result name="input">/WEB-INF/jsp/Login.jsp</result>
-            <result name="cancel" type="redirectAction">Welcome</result>
-            <result type="redirectAction">MainMenu</result>
-            <result name="expired" type="chain">ChangePassword</result>
-            <exception-mapping
-                    exception="org.apache.struts.apps.mailreader.dao.ExpiredPasswordException"
-                    result="expired"/>
-            <interceptor-ref name="guest"/>
-        </action>
-
-        <action name="Registration_*" method="{1}" class="mailreader2.Registration">
-            <result name="input">/WEB-INF/jsp/Registration.jsp</result>
-            <result type="redirectAction">MainMenu</result>
-            <interceptor-ref name="guest"/>
-        </action>
-    </package>
-
-    <package name="subscription" namespace="/" extends="mailreader-support">
-
-        <global-results>
-            <result name="input">/WEB-INF/jsp/Subscription.jsp</result>
-            <result type="redirectAction">Registration_input</result>
-        </global-results>
-
-        <action name="Subscription_save" method="save" class="mailreader2.Subscription">
-            <interceptor-ref name="user-submit" />
-        </action>
-
-        <action name="Subscription_*" method="{1}" class="mailreader2.Subscription" />
-
-    </package>
-
-    <package name="wildcard" namespace="/" extends="mailreader-support">
-
-        <action name="*" class="mailreader2.MailreaderSupport">
-            <result>/WEB-INF/jsp/{1}.jsp</result>
-        </action>
-        
-    </package>
-</struts>
diff --git a/mailreader/src/main/resources/struts.xml b/mailreader/src/main/resources/struts.xml
deleted file mode 100644
index 37182fe..0000000
--- a/mailreader/src/main/resources/struts.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "http://struts.apache.org/dtds/struts-2.5.dtd">
-
-<struts>
-
-    <constant name="struts.action.extension" value="do" />
-    <constant name="struts.devMode" value="true" />
-    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
-
-    <include file="mailreader-default.xml"/>
-
-    <include file="mailreader-support.xml"/>
-
-</struts>
\ No newline at end of file
diff --git a/mailreader/src/main/resources/velocity.properties b/mailreader/src/main/resources/velocity.properties
deleted file mode 100644
index 6299831..0000000
--- a/mailreader/src/main/resources/velocity.properties
+++ /dev/null
@@ -1 +0,0 @@
-runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogChute
diff --git a/mailreader/src/main/webapp/META-INF/context.xml b/mailreader/src/main/webapp/META-INF/context.xml
deleted file mode 100644
index 9b0b5d0..0000000
--- a/mailreader/src/main/webapp/META-INF/context.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Context path="/">
-</Context>
diff --git a/mailreader/src/main/webapp/WEB-INF/database.xml b/mailreader/src/main/webapp/WEB-INF/database.xml
deleted file mode 100644
index e54d9c5..0000000
--- a/mailreader/src/main/webapp/WEB-INF/database.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version='1.0'?>
-<database>
-  <user username="user" fromAddress="John.User@somewhere.com" fullName="John Q. User" password="pass">
-    <subscription host="mail.yahoo.com" autoConnect="false" password="foo" type="imap" username="jquser">
-    </subscription>
-    <subscription host="mail.hotmail.com" autoConnect="false" password="bar" type="pop3" username="user1234">
-    </subscription>
-  </user>
-</database>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/ChangePassword.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/ChangePassword.jsp
deleted file mode 100644
index ce543d7..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/ChangePassword.jsp
+++ /dev/null
@@ -1,25 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <title><s:text name="change.title"/></title>
-    <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
-          type="text/css"/>
-</head>
-
-<body>
-
-<p>
-    <s:text name="change.message"/>
-</p>
-
-<p>
-    <a href="<s:url action="Login_input"/>">
-        <s:text name="change.try"/>
-    </a>
-</p>
-
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/Error.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/Error.jsp
deleted file mode 100644
index 05ab5e0..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/Error.jsp
+++ /dev/null
@@ -1,40 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <title>Unexpected Error</title>
-</head>
-
-<body>
-<h2>An unexpected error has occured</h2>
-
-<p>
-    Please report this error to your system administrator
-    or appropriate technical support personnel.
-    Thank you for your cooperation.
-</p>
-
-<hr/>
-
-<h3>Error Message</h3>
-
-<s:actionerror />
-
-<p>
-    <s:property value="%{exception.message}"/>
-</p>
-
-<hr/>
-
-<h3>Technical Details</h3>
-
-<p>
-    <s:property value="%{exceptionStack}"/>
-</p>
-
-<jsp:include page="Footer.jsp"/>
-
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/Footer.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/Footer.jsp
deleted file mode 100644
index 56d80bb..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/Footer.jsp
+++ /dev/null
@@ -1,6 +0,0 @@
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<hr/>
-
-<p>
-    <a href="<s:url action="Welcome"  includeParams="none"/>"><s:text name="index.title"/></a>
-</p>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/Login.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/Login.jsp
deleted file mode 100644
index 2994793..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/Login.jsp
+++ /dev/null
@@ -1,30 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <title><s:text name="login.title"/></title>
-    <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
-          type="text/css"/>
-</head>
-
-<body onLoad="self.focus();document.Login.username.focus()">
-
-<s:actionerror />
-<s:form action="Login" validate="true">
-    <s:textfield key="username" />
-
-    <s:password key="password" showPassword="true"/>
-
-    <s:submit key="button.logon"/>
-
-    <s:reset key="button.reset"/>
-
-    <s:submit action="Login_cancel" key="button.cancel"
-                onclick="form.onsubmit=null"/>
-</s:form>
-
-<jsp:include page="Footer.jsp"/>
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/MainMenu.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/MainMenu.jsp
deleted file mode 100644
index bf2f044..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/MainMenu.jsp
+++ /dev/null
@@ -1,25 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <title><s:text name="mainMenu.title"/></title>
-    <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
-          type="text/css"/>
-</head>
-
-<body>
-<h3><s:text name="mainMenu.heading"/> <s:property
-        value="user.fullName"/></h3>
-<ul>
-    <li><a href="<s:url action="Registration_input" />">
-        <s:text name="mainMenu.registration"/>
-    </a>
-    </li>
-    <li><a href="<s:url action="Logout"/>">
-        <s:text name="mainMenu.logout"/>
-    </a>
-</ul>
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/Registration.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/Registration.jsp
deleted file mode 100644
index 1d3cf8d..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/Registration.jsp
+++ /dev/null
@@ -1,115 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <s:if test="task=='Create'">
-        <title><s:text name="registration.title.create"/></title>
-    </s:if>
-    <s:if test="task=='Edit'">
-        <title><s:text name="registration.title.edit"/></title>
-    </s:if>
-    <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
-          type="text/css"/>
-</head>
-
-<body onLoad="self.focus();document.Registration_save_username.focus()">
-
-<s:actionerror/>
-<s:form action="Registration_save" validate="false">
-    <s:token />
-    <s:hidden name="task"/>
-    <s:if test="task == 'Create'">
-        <s:textfield key="username"/>
-    </s:if>
-    <s:else>
-        <s:label key="username"/>
-        <s:hidden name="username"/>
-    </s:else>
-
-    <s:password key="password" showPassword="true"/>
-    <s:password key="password2"/>
-    <s:textfield key="user.fullName"/>
-    <s:textfield key="user.fromAddress"/>
-    <s:textfield key="user.replyToAddress"/>
-
-    <s:if test="task == 'Create'">
-        <s:submit key="button.save" action="Registration_save"/>
-        <s:reset key="button.reset"/>
-        <s:submit action="Welcome" key="button.cancel"
-                    onclick="form.onsubmit=null"/>
-    </s:if>
-    <s:else>
-        <s:submit key="button.save" action="Registration"/>
-        <s:reset key="button.reset"/>
-        <s:submit action="MainMenu" key="button.cancel"
-                    onclick="form.onsubmit=null"/>
-    </s:else>
-
-</s:form>
-
-<s:if test="task == 'Edit'">
-    <div align="center">
-        <h3><s:text name="heading.subscriptions"/></h3>
-    </div>
-
-    <table border="1" width="100%">
-
-        <tr>
-            <th align="center" width="30%">
-                <s:text name="heading.host"/>
-            </th>
-            <th align="center" width="25%">
-                <s:text name="heading.user"/>
-            </th>
-            <th align="center" width="10%">
-                <s:text name="heading.type"/>
-            </th>
-            <th align="center" width="10%">
-                <s:text name="heading.autoConnect"/>
-            </th>
-            <th align="center" width="15%">
-                <s:text name="heading.action"/>
-            </th>
-        </tr>
-
-        <s:iterator value="user.subscriptions">
-            <tr>
-                <td align="left">
-                    <s:property value="host"/>
-                </td>
-                <td align="left">
-                    <s:property value="username"/>
-                </td>
-                <td align="center">
-                    <s:property value="type"/>
-                </td>
-                <td align="center">
-                    <s:property value="autoConnect"/>
-                </td>
-                <td align="center">
-
-                    <a href="<s:url action="Subscription_delete"><s:param name="host" value="host"/></s:url>">
-                        <s:text name="registration.deleteSubscription"/>
-                    </a>
-                    &nbsp;
-                    <a href="<s:url action="Subscription_edit"><s:param name="host" value="host"/></s:url>">
-                        <s:text name="registration.editSubscription"/>
-                    </a>
-
-                </td>
-            </tr>
-        </s:iterator>
-
-    </table>
-
-    <a href="<s:url action="Subscription_input"/>"><s:text
-            name="registration.addSubscription"/></a>
-
-</s:if>
-
-<jsp:include page="Footer.jsp"/>
-
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/Subscription.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/Subscription.jsp
deleted file mode 100644
index 60cda4a..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/Subscription.jsp
+++ /dev/null
@@ -1,60 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <s:if test="task=='Create'">
-        <title><s:text name="subscription.title.create"/></title>
-    </s:if>
-    <s:if test="task=='Edit'">
-        <title><s:text name="subscription.title.edit"/></title>
-    </s:if>
-    <s:if test="task=='Delete'">
-        <title><s:text name="subscription.title.delete"/></title>
-    </s:if>
-    <link href="<s:url value="/css/mailreader.css" includeParams="none"/>" rel="stylesheet"
-          type="text/css"/>
-</head>
-
-<body onLoad="self.focus();document.Subscription.username.focus()">
-
-<s:actionerror/>
-<s:form action="Subscription_save" validate="true">
-    <s:token />
-    <s:hidden name="task"/>
-    <s:label key="username" name="user.username"/>
-
-    <s:if test="task == 'Create'">
-        <s:textfield key="host"/>
-    </s:if>
-    <s:else>
-        <s:label key="host"/>
-        <s:hidden name="host"/>
-    </s:else>
-
-    <s:if test="task == 'Delete'">
-        <s:label key="subscription.username"/>
-        <s:label key="subscription.password"/>
-        <s:label key="subscription.type"/>
-        <s:label key="subscription.autoConnect"/>
-        <s:submit key="button.confirm"/>
-    </s:if>
-    <s:else>
-        <s:textfield key="subscription.username"/>
-        <s:textfield key="subscription.password"/>
-        <s:select key="subscription.type" list="types"/>
-        <s:checkbox key="subscription.autoConnect"/>
-        <s:submit key="button.save"/>
-        <s:reset key="button.reset"/>
-    </s:else>
-
-    <s:submit action="Registration_input"
-                key="button.cancel"
-                onclick="form.onsubmit=null"/>
-</s:form>
-
-<jsp:include page="Footer.jsp"/>
-
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/WEB-INF/jsp/Welcome.jsp b/mailreader/src/main/webapp/WEB-INF/jsp/Welcome.jsp
deleted file mode 100644
index 0ce3e54..0000000
--- a/mailreader/src/main/webapp/WEB-INF/jsp/Welcome.jsp
+++ /dev/null
@@ -1,55 +0,0 @@
-<%@ page contentType="text/html; charset=UTF-8" %>
-<%@ taglib uri="/struts-tags" prefix="s" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-    <title><s:text name="index.title"/></title>
-    <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
-          type="text/css"/>
-</head>
-
-<body>
-<h3><s:text name="index.heading"/></h3>
-
-<ul>
-    <li><a href="<s:url action="Registration_input"/>"><s:text
-            name="index.registration"/></a></li>
-    <li><a href="<s:url action="Login_input"/>"><s:text
-            name="index.login"/></a></li>
-</ul>
-
-<h3>Language Options</h3>
-<ul>
-    <li>
-        <s:url id="en" action="Welcome">
-            <s:param name="request_locale">en</s:param>
-        </s:url>
-        <s:a href="%{en}">English</s:a>
-    </li>
-    <li>
-        <s:url id="ja" action="Welcome">
-            <s:param name="request_locale">ja</s:param>
-        </s:url>
-        <s:a href="%{ja}">Japanese</s:a>
-    </li>
-    <li>
-        <s:url id="ru" action="Welcome">
-            <s:param name="request_locale">ru</s:param>
-        </s:url>
-        <s:a href="%{ru}">Russian</s:a>
-    </li>
-</ul>
-
-<hr/>
-
-<p><s:i18n name="alternate"><a href="http://struts.apache.org/">
-    <img src="<s:text name="struts.logo.path"/>"
-         alt="<s:text name="struts.logo.alt"/>" border="0px"/>
-</a>
-</s:i18n></p>
-
-</body>
-</html>
-
diff --git a/mailreader/src/main/webapp/WEB-INF/web.xml b/mailreader/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 26cc371..0000000
--- a/mailreader/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
-<web-app>
-
-    <display-name>Struts 2 Mailreader</display-name>
-
-    <filter>
-        <filter-name>struts2</filter-name>
-        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
-    </filter>
-
-    <filter-mapping>
-        <filter-name>struts2</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-
-    <!-- Application Listener for Mailreader database -->
-    <listener>
-        <listener-class>
-            mailreader2.ApplicationListener
-        </listener-class>
-    </listener>
-
-    <welcome-file-list>
-        <welcome-file>index.html</welcome-file>
-    </welcome-file-list>
-
-    <!-- Restricts access to pure JSP files - access available only via Struts action -->
-    <security-constraint>
-        <display-name>No direct JSP access</display-name>
-        <web-resource-collection>
-            <web-resource-name>No-JSP</web-resource-name>
-            <url-pattern>*.jsp</url-pattern>
-        </web-resource-collection>
-        <auth-constraint>
-            <role-name>no-users</role-name>
-        </auth-constraint>
-    </security-constraint>
-
-    <security-role>
-        <description>Don't assign users to this role</description>
-        <role-name>no-users</role-name>
-    </security-role>
-
-</web-app>
diff --git a/mailreader/src/main/webapp/css/mailreader.css b/mailreader/src/main/webapp/css/mailreader.css
deleted file mode 100644
index bfc7648..0000000
--- a/mailreader/src/main/webapp/css/mailreader.css
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
-* Mailreader stylesheet
-*/
-
-body {
-    background-color: #FFFFFF;
-    color: #000000;
-    link: 000066;
-    visited: #660066;
-    active: #33CCCC;
-}
-
-A:hover {
-    color: #FF0000;
-}
-
-h1 {
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-h2 {
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-h3 {
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-h4 {
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-h5 {
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-h6 {
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-font.hint {
-    font-style: italic;
-    font-size: 80%;
-    font-family: Arial, Helvetica, sans-serif;
-    text-align: left;
-}
\ No newline at end of file
diff --git a/mailreader/src/main/webapp/index.html b/mailreader/src/main/webapp/index.html
deleted file mode 100644
index 1b01b3f..0000000
--- a/mailreader/src/main/webapp/index.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-    <META HTTP-EQUIV="Refresh" CONTENT="0;URL=Welcome.do">
-</head>
-
-<body>
-<p>Loading ...</p>
-</body>
-</html>
diff --git a/mailreader/src/main/webapp/struts-power.gif b/mailreader/src/main/webapp/struts-power.gif
deleted file mode 100644
index 5f4e9d4..0000000
Binary files a/mailreader/src/main/webapp/struts-power.gif and /dev/null differ
diff --git a/mailreader/src/main/webapp/tour.html b/mailreader/src/main/webapp/tour.html
deleted file mode 100644
index 7dc29f0..0000000
--- a/mailreader/src/main/webapp/tour.html
+++ /dev/null
@@ -1,2470 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"/>
-    <link rel="stylesheet" type="text/css" href="../css/mailreader.css"/>
-
-    <title>A Walking Tour of the Struts 2 MailReader Application</title>
-</head>
-
-<body>
-<blockquote>
-<h2>A Walking Tour of the Struts 2 MailReader Application</h2>
-
-<p>
-    <i>
-        This article is meant to introduce a new user to Apache Struts 2 by
-        "walking through" a simple, but functional, application.
-        The article includes code snippets, but for the best result, you might
-        want to install the MailReader application on your own development
-        workstation and follow along.
-        Of course, the full source code to the MailReader is included in the
-        distribution.
-    </i>
-</p>
-
-<p>
-    <i>
-        The tour assumes the reader has a basic understanding of the Java
-        language, JavaBeans, web applications, and JavaServer Pages. For
-        background on these technologies, see the
-        <a href="http://struts.apache.org/primer.html">
-            Key Technologies Primer</a>.
-    </i>
-</p>
-
-<hr/>
-
-<ul>
-    <li>
-        <a href="#Welcome">Welcome</a>
-
-        <ul>
-            <li><a href="#web.xml">web.xml and resources.properties</a></li>
-
-            <li><a href="#Welcome.do">Welcome.do</a></li>
-
-            <li><a href="#Welcome.java">Welcome Action</a></li>
-
-            <li><a href="#global-results">Global Results</a></li>
-
-            <li><a href="#ApplicationListener.java">ApplicationListener.java</a></li>
-
-            <li><a href="#resources.properties">Message Resources</a></li>
-
-            <li><a href="#Welcome.jsp">Welcome Page</a></li>
-
-        </ul>
-    </li>
-</ul>
-
-<ul>
-    <li>
-        <a href="#Login">Login</a>
-        <ul>
-
-            <li><a href="#Login.jsp">Login Page</a></li>
-
-            <li><a href="#Login-validation.xml">Login-validation.xml</a></li>
-
-            <li><a href="#Login.java">Login.java</a></li>
-
-            <li><a href="#MailreaderSupport.java">MailreaderSupport.java</a></li>
-
-            <li><a href="#Login.xml">Login Configuration</a></li>
-
-        </ul>
-    </li>
-</ul>
-
-<ul>
-    <li>
-        <a href="#MainMenu">MainMenu</a>
-    </li>
-</ul>
-
-<ul>
-    <li>
-        <a href="#Registration.jsp">Registration page</a>
-        <ul>
-            <li><a href="#iterator">iterator</a></li>
-        </ul>
-    </li>
-</ul>
-
-<ul>
-    <li>
-        <a href="#Subscription">Subscription</a>
-
-        <ul>
-            <li><a href="#Subscription.java">Subscription.java</a>
-            </li>
-        </ul>
-    </li>
-</ul>
-<hr/>
-
-<p>
-    The premise of the MailReader is that it is the first iteration of a
-    portal application.
-    This version allows users to register and maintain a set of
-    accounts with various mail servers.
-    If completed, the application would let users read mail from their
-    accounts.
-</p>
-
-<p>
-    The MailReader application demonstrates registering with an application,
-    logging into an application, maintaining a master record, and maintaining
-    child records.
-    This article overviews the constructs needed to do these things,
-    including the server pages, Java classes, and configuration elements.
-</p>
-
-<p>
-    For more about the MailReader, including alternate implementations and a
-    set of formal Use Cases,
-    please visit the <a href="http://www.StrutsUniversity.org/MailReader">
-    Struts University MailReader site</a>.
-</p>
-
-<hr/>
-<blockquote>
-    <p><font class="hint">
-        <strong>JAAS</strong> -
-        Note that for compatibility and ease of deployment, the MailReader
-        uses "application-based" authorization.
-        However, use of the standard Java Authentication and Authorization
-        Service (JAAS) is recommended for most applications.
-        (See the <a
-            href="http://struts.apache.org/primer.html">
-        Key Technologies Primer</a> for more about
-        authentication technologies.)
-    </font></p>
-</blockquote>
-<hr/>
-
-<p>
-    The tour starts with how the initial welcome page is displayed, and
-    then steps through logging into the application and editing a subscription.
-    Please note that this not a quick peek at a "Hello World" application.
-    The tour is a rich trek into a realistic, best practices application.
-    You may need to adjust your chair and get a fresh cup of coffee.
-    Printed, the article is 29 pages long (US).
-</p>
-
-<h3><a name="Welcome" id="Welcome">Welcome Page</a></h3>
-
-<p>
-    A web application, like any other web site, can specify a list of welcome pages.
-    When you open a web application without specifying a particular page, a
-    default "welcome page" is served as the response.
-</p>
-
-<h4><a name="web.xml" id="web.xml">web.xml</a></h4>
-
-<p>
-    When a web application loads,
-    the container reads and parses the "Web Application Deployment
-    Descriptor", or "web.xml" file.
-    The framework plugs into a web application via a servlet filter.
-    Like any filter, the "struts2" filter is deployed via the "web.xml".
-</p>
-
-<hr/>
-<h5>web.xml - The Web Application Deployment Descriptor</h5>
-<pre><code>&lt;?xml version="1.0" encoding="ISO-8859-1"?>
-&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
-  "http://java.sun.com/dtd/web-app_2_3.dtd">
-&lt;web-app>
-
-  &lt;display-name>Struts 2 MailReader&lt;/display-name>
-
-  <strong>&lt;filter>
-    &lt;filter-name>struts2&lt;/filter-name>
-    &lt;filter-class>
-      org.apache.struts2.dispatcher.FilterDispatcher
-    &lt;/filter-class>
-   &lt;/filter></strong>
-
-  &lt;filter-mapping>
-    &lt;filter-name><strong>struts2</strong>&lt;/filter-name>
-    &lt;url-pattern>/*&lt;/url-pattern>
-  &lt;/filter-mapping>
-
-  &lt;listener>
-    &lt;listener-class>
-      org.springframework.web.context.ContextLoaderListener
-    &lt;/listener-class>
-  &lt;/listener>
-
-  &lt;!-- Application Listener for MailReader database -->
-  &lt;listener>
-    &lt;listener-class>
-      mailreader2.ApplicationListener
-    &lt;/listener-class>
-  &lt;/listener>
-
-  &lt;welcome-file-list>
-    &lt;welcome-file>index.html&lt;/welcome-file>
-  &lt;/welcome-file-list>
-
-  &lt;/web-app></code></pre>
-<hr/>
-
-<p>
-    You might note that the web.xml configuration does not specify which file extension
-    to use with actions.
-    The default extension for Struts 2 is ".action",
-    but the extension can be changed in the struts.properties file.
-    For compatability with prior releases, the MailReader uses a .do extension for actions.
-</p>
-
-<hr/>
-<h5>struts.properties</h5>
-<pre><code>struts.action.extension = <strong>do</strong></code></pre>
-<hr/>
-
-<p>
-    The web.xml does specify a "Welcome File List" for the application.
-    When a web address refers to a directory rather than an individual file,
-    the container consults the Welcome File List for the name of a page to
-    open by default.
-</p>
-
-<p>
-    However, most Struts applications do not refer to physical pages,
-    but to "virtual resources" called <i>actions</i>.
-    Actions specify code that we want to be run before a page
-    or other resource renders the response.
-    An accepted practice is to never link directly to server pages,
-    but only to logical action mappings.
-    By linking to actions, developers can often "rewire" an application
-    without editing the server pages.
-</p>
-
-<hr/>
-<h5>Best Practice:</h5>
-<blockquote>
-    <p><font class="hint">"Link actions not pages."</font></p>
-</blockquote>
-<hr/>
-
-<p>
-    The actions are listed in one or more XML configuration files,
-    the default configuration file being named "struts.xml".
-    When the application loads, the struts.xml, and any other files
-    it includes, are parsed, and the framework creates a set of
-    configuration objects.
-    Among other things, the configuration maps a request for a certain
-    page to a certain action mapping.
-</p>
-
-
-<p>
-    Sites can list zero or more "Welcome" pages in the web.xml.
-    <a href="http://forum.java.sun.com/thread.jspa?threadID=721445">
-        Unless you are using Java 1.5,</a>
-    actions cannot be specified as a Welcome page.
-    So, in the case of a Welcome page,
-    how do we follow the best practice of navigating through actions
-    rather than pages?
-</p>
-
-<p>
-    One solution is to use a page to "bootstrap" one of our actions.
-    We can register the usual "index.html" as the Welcome page and have it
-    redirect to a "Welcome" action.
-</p>
-
-<hr/>
-<h5>MailReader's index.html</h5>
-<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-&lt;html>&lt;head>
-  &lt;META HTTP-EQUIV="Refresh" CONTENT="0;<strong>URL=Welcome.do</strong>">
-  &lt;/head>
-  &lt;body>
-    &lt;p>Loading ...&lt;/p>
-&lt;/body>&lt;/html></code></pre>
-<hr/>
-
-<p>
-    As an alternative,
-    we could also have used a JSP page that issued the redirect with a Struts tag,
-    but a plain HTML solution works as well.
-</p>
-
-<h4><a name="Welcome.do" id="Welcome.do">Welcome.do</a></h4>
-
-<p>
-    When the client requests "Welcome.do", the request is passed to the "struts2"
-    FilterDispatcher (that we registered in the web.xml file).
-    The FilterDispatcher retrieves the appropriate action mapping from the
-    configuration.
-    If we just wanted to forward to the Welcome page, we could use a simple
-    configuration element.
-</p>
-<hr/>
-<h5>A simple "forward thru" action element</h5>
-<pre><code>&lt;action name="<strong>Welcome</strong>">
-  &lt;result><strong>/pages/Welcome.jsp</strong>&lt;/result>
-&lt;/action></code></pre>
-<hr/>
-
-<p>
-    If a client asks for the Welcome action ("Welcome.do"), the "/page/Welcome.jsp"
-    page would be returned in response.
-    The client does not know, or need to know, that the physical resource is located at
-    "/pages/Welcome.jsp".
-    All the client knows is that it requested the resource "Welcome.do".
-</p>
-
-<p>
-    But if we peek at the configuration file for the MailReader,
-    we find a slightly more complicated XML element for the Welcome action.
-</p>
-
-<hr/>
-<h5>The Welcome action element</h5>
-<pre><code>&lt;action name="Welcome" <b>class="mailreader2.Welcome"</b>>
-    &lt;result>/pages/Welcome.jsp&lt;/result>
-    <strong>&lt;interceptor-ref name="guest"/></strong>
-    &lt;/action></code></pre>
-<hr/>
-
-<p>
-    Here, the <strong>Welcome</strong> Java class executes whenever
-    someone asks for the Welcome action.
-    As it completes, the Action class can select which "result" is displayed.
-    The default result name is "success".
-    Another available result, defined at a global scope, is "error".
-</p>
-
-<hr/>
-<h5>Key concept:</h5>
-<blockquote>
-    <p>
-        The Action class doesn't need to know what result type is needed
-        for "success" or "error".
-        The Action can just return the logical name for a result,
-        without knowing how the result is implemented.
-    </p>
-</blockquote>
-<hr/>
-
-<p>
-    The net effect is that all of the result details,
-    including the paths to server pages,
-    all can be declared <em>once</em> in the configuration.
-    Tightly coupled implementation details are not scattered all over
-    the application.
-</p>
-
-<hr/>
-<h5>Key concept:</h5>
-<blockquote>
-    <p>
-        The Struts configuration lets us separate concerns and "say it once".
-        The configuration helps us "normalize" an application,
-        in much the same way we normalize a database schema.
-    </p>
-</blockquote>
-<hr/>
-
-
-<p>
-    OK ... but why would a Welcome Action want to choose between "success" and
-    "error"?
-</p>
-
-<h4><a name="Welcome.java" id="Welcome.java">Welcome Action</a></h4>
-
-<p>
-    The MailReader application retains a list of users along with their email
-    accounts.
-    The application stores this information in a database.
-    If the application can't connect to the database, the application can't do
-    its job.
-    So before displaying the Welcome <strong>page</strong>, the Welcome
-    <strong>class</strong> checks to see if the database is available.
-</p>
-
-<p>
-    The MailReader is also an internationalized application.
-    So, the Welcome Action class checks to see if the message resources are
-    available too.
-    If both resources are available, the class passes back the "success" token.
-    Otherwise, the class passes back the "error" token,
-    so that the appropriate messages can be displayed.
-</p>
-
-<hr/>
-<h5>The Welcome Action class</h5>
-<pre><code>package mailreader2;
-public class Welcome extends MailreaderSupport {
-
-  public String execute() {
-
-    // Confirm message resources loaded
-    String message = getText(Constants.ERROR_DATABASE_MISSING);
-    if (Constants.ERROR_DATABASE_MISSING.equals(message)) {
-      <strong>addActionError(Constants.ERROR_MESSAGES_NOT_LOADED);</strong>
-    }
-
-    // Confirm database loaded
-    if (null==getDatabase()) {
-      <strong>addActionError(Constants.ERROR_DATABASE_NOT_LOADED);</strong>
-    }
-
-    if (hasErrors()) {
-      <strong>return ERROR;</strong>
-    }
-    else {
-      <strong>return SUCCESS;</strong>
-    }
-  }
-}</code></pre>
-<hr/>
-
-<p>
-    Several common result names are predefined,
-    including ERROR, SUCCESS, LOGIN, NONE, and INPUT,
-    so that these tokens can be used consistently across Struts 2 applications.
-</p>
-
-
-<h4><a name="global-results" id="global-results">Global Results</a></h4>
-
-<p>
-    As mentioned, "error" is defined in a global scope.
-    Other actions may have trouble connecting to the database later,
-    or other unexpected errors may occur.
-    The MailReader defines the "error" result as a Global Result,
-    so that any action can use it.
-</p>
-
-<hr/>
-<h5>MailReader's global-result element</h5>
-<pre><code> &lt;global-results>
-  &lt;result name=<strong>"error"</strong>><strong>/pages/Error.jsp</strong>&lt;/result>
-  &lt;result name="invalid.token">/pages/Error.jsp&lt;/result>
-  &lt;result name="login" type="redirect-action">Login_input&lt;/result>
-&lt;/global-results></code></pre>
-<hr/>
-
-<p>
-    Of course, if an individual action mapping defines its own "error" result type,
-    the local result would be used instead.
-</p>
-
-<h4><a name="ApplicationListener.java" id="ApplicationListener.java">ApplicationListener.java</a>
-</h4>
-
-<p>
-    The database is exposed as an object stored in application scope.
-    The database object is based on an interface.
-    Different implementations of the database could be loaded without changing
-    the rest of the application.
-    But how is the database object loaded in the first place?
-</p>
-
-<p>
-    The database is created by a custom Listener that we configured in the "web.xml".
-</p>
-
-<hr/>
-<h5>mailreader2.ApplicationListener</h5>
-<pre><code> &lt;listener>
-  &lt;listener-class>
-    <strong>mailreader2.ApplicationListener</strong>
-  &lt;/listener-class>
-&lt;/listener></code></pre>
-<hr/>
-
-<p>
-    By default, our ApplicationListener loads a <strong>MemoryDatabase</strong>
-    implementation of the UserDatabase.
-    MemoryDatabase stores the database content as a XML document,
-    which is parsed and loaded as a set of nested hashtables.
-    The outer table is the list of user objects, each of which has its own
-    inner hashtable of subscriptions.
-    When you register, a user object is stored in this hashtable.
-    When you login, the user object is stored within the session context.
-</p>
-
-<p>
-    The database comes seeded with a sample user.
-    If you check the "database.xml" file under "/src/main/resources",
-    you'll see the sample user described in XML.
-</p>
-
-<hr/>
-<h5>The "seed" user element from the MailReader database.xml</h5>
-<pre><code>&lt;user username="<strong>user</strong>" fromAddress="John.User@somewhere.com"
-  fullName="<strong>John Q. User</strong>" password="<strong>pass</strong>">
-    &lt;subscription host="<strong>mail.hotmail.com"</strong> autoConnect="false"
-      password="bar" type="pop3" username="user1234">
-    &lt;/subscription>
-    &lt;subscription host="<strong>mail.yahoo.com</strong>" autoConnect="false" password="foo"
-      type="imap" username="jquser">
-    &lt;/subscription>
-&lt;/user></code></pre>
-<hr/>
-
-<p>
-    The "seed" user element creates a registration record for "John Q. User",
-    with the subscription detail for his hotmail and yahoo accounts.
-</p>
-
-<h4><a name="resources.properties" id="resources.properties">Message Resources</a>
-</h4>
-
-<p>
-    As mentioned, MailReader is an internationalized application.
-    In Struts 2, message resources are associated with the Action class being processed.
-    If we check the source, we find a language resource bundle named
-    <em>MailreaderSupport.</em>
-    MailreaderSupport is our base class for all the MailReader Actions.
-    Since all of our Actions extend MailreaderSupport,
-    all of our Actions can use the same resource bundle.
-</p>
-
-<hr/>
-<h5>Message Resource entries used by the Welcome page</h5>
-<pre><code><strong>index.heading=</strong>MailReader Application Options
-<strong>index.login=</strong>Log on to the MailReader Application
-<strong>index.registration=</strong>Register with the MailReader Application
-<strong>index.title=</strong>MailReader Demonstration Application
-<strong>index.tour=</strong>A Walking Tour of the MailReader Demonstration Application</code></pre>
-<hr/>
-
-<p>
-    If you change a message in the resource, and then rebuild and reload the
-    application, the change will appear throughout the application.
-    If you provide message resources for additional locales, you can
-    localize your application.
-    The MailReader provides resources for English, Russian, and Japanese.
-</p>
-
-<h4><a name="Welcome.jsp" id="Welcome.jsp">Welcome Page</a></h4>
-
-<p>
-    After confirming that the necessary resources exist, the Welcome action
-    forwards to the Welcome page.
-</p>
-<hr/>
-<h5>Welcome.jsp</h5>
-<pre><code>&lt;%@ page contentType="text/html; charset=UTF-8" %>
-<strong>&lt;%@ taglib prefix="s" uri="http://struts.apache.org/tags" %></strong>
-  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-    &lt;head>
-      &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-      &lt;title><strong>&lt;s:text name="index.title"/></strong>&lt;/title>
-      &lt;link href="<strong>&lt;s:url value="/css/mailreader.css"/></strong>" rel="stylesheet"
-      type="text/css"/>
-    &lt;/head>
-
-    &lt;body>
-      &lt;h3>&lt;s:text name="index.heading"/>&lt;/h3>
-
-      &lt;ul>
-        &lt;li>&lt;a href="&lt;s:url action="Registration_input"/>">&lt;s:text
-          name="index.registration"/>&lt;/a>&lt;/li>
-        &lt;li>&lt;a href="&lt;s:url action="Login_input"/>">&lt;s:text
-          name="index.login"/>&lt;/a>&lt;/li>
-      &lt;/ul>
-
-      &lt;h3>Language Options&lt;/h3>
-      &lt;ul>
-          &lt;li>
-              &lt;s:url id="en" action="Welcome">
-                  &lt;s:param name="request_locale">en&lt;/s:param>
-              &lt;/s:url>
-               &lt;s:a href="%{en}">English&lt;/s:a>
-           &lt;/li>
-          &lt;li>
-              &lt;s:url id="ja" action="Welcome">
-                &lt;s:param name="request_locale">ja&lt;/s:param>
-              &lt;/s:url>
-              &lt;s:a href="%{ja}">Japanese&lt;/s:a>
-          &lt;/li>
-          &lt;li>
-              &lt;s:url id="ru" action="Welcome">
-              &lt;s:param name="request_locale">ru&lt;/s:param>
-              &lt;/s:url>
-              &lt;s:a href="%{ru}">Russian&lt;/s:a>
-          &lt;/li>
-      &lt;/ul>
-
-    &lt;hr />
-
-    &lt;p><strong>&lt;s:i18n name="alternate"></strong>
-    &lt;img src="&lt;s:text name="struts.logo.path"/>"
-      alt="&lt;s:text name="struts.logo.alt"/>"/>
-    <strong>&lt;/s:i18n></strong>&lt;/p>
-
-    &lt;p>&lt;a href="&lt;s:url action="Tour" />">&lt;s:text name="index.tour"/>&lt;/a>&lt;/p>
-
-  &lt;/body>
-&lt;/html></code></pre>
-<hr/>
-
-<p>
-    At the top of the Welcome page, there are several directives that load the
-    Struts 2 tag libraries.
-    These are just the usual red tape that goes with any JSP file.
-    The rest of the page utilizes three Struts JSP tags:
-    "text", "url", and "i18n".
-</p>
-
-<p>
-    (We use the tag prefix "s:" in the Struts 2 MailReader application,
-    but you can use whatever prefix you like in your applications.)
-</p>
-
-<p>
-    The <strong>text</strong> tag inserts a message from an
-    application's default resource bundle.
-    If the framework's locale setting is changed for a user,
-    the text tag will render messages from the new locale's resource
-    bundle instead.
-</p>
-
-<p>
-    The <strong>url</strong> tag can render a reference to an
-    action or any other web resource,
-    applying "URL encoding" to the hyperlinks as needed.
-    Java's URL encoding feature lets your application maintain client state
-    without requiring cookies.
-</p>
-
-<hr/>
-<h5>Tip:</h5>
-<blockquote>
-    <p><font class="hint">
-        <strong>Cookies</strong> -
-        If you turn cookies off in your browser, and then reload your browser
-        and this page,
-        you will see the links with the Java session id information attached.
-        (If you are using Internet Explorer and try this,
-        be sure you reset cookies for the appropriate security zone,
-        and that you disallow "per-session" cookies.)
-    </font></p>
-</blockquote>
-<hr/>
-
-<p>
-    The <strong>i18n</strong> tag provides access to multiple resource bundles.
-    The MailReader application uses a second set of message resources for
-    non-text elements.
-    When these are needed, we use the "i18n" tag to specify a different bundle.
-</p>
-
-<p>
-    The <strong>alternate</strong> bundle is stored in the {{/src/main/resources}} folder,
-    so that it ends up under "classes", which is on the application's class path.
-</p>
-
-<p>
-    In the span of a single request for the Welcome page, the framework has done
-    quite a bit already:
-</p>
-
-<ul>
-    <li>
-        Confirmed that required resources were loaded during initialization.
-    </li>
-
-    <li>
-        Written all the page headings and labels from internationalized
-        message resources.
-    </li>
-
-    <li>
-        Automatically URL-encoded paths as needed.
-    </li>
-</ul>
-
-<p>
-    When rendered, the Welcome page lists two menu options:
-    one to register with the application and one to log on (if you have
-    already registered).
-    Let's follow the Login link first.
-</p>
-
-<h3><a name="Login" id="Login">Login</a></h3>
-
-<p>
-    If you choose the Login link, and all goes well, the Login action forwards
-    control to the Login page.
-</p>
-
-<h4><a name="Login.jsp" id="Login.jsp">Login Page</a></h4>
-
-<p>
-    The Login page displays a form that accepts a username and password.
-    You can use the default username and password to login
-    (<strong>user</strong> and <strong>pass</strong>), if
-    you like. Try omitting or misspelling the username and password in
-    various combinations to see how the application reacts.
-    Note that both the username and password are case sensitive.
-</p>
-
-<hr/>
-<h5>Login.jsp</h5>
-<pre><code>&lt;%@ page contentType="text/html; charset=UTF-8" %>
-  &lt;%@ taglib prefix="s" uri="http://struts.apache.org/tags"  %>
-  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  &lt;head>
-    &lt;title>&lt;s:text name="login.title"/>&lt;/title>
-      &lt;link href="&lt;s:url value="/css/mailreader.css"/>" rel="stylesheet"
-        type="text/css"/>
-  &lt;/head>
-  &lt;body onLoad="self.focus();document.Login.username.focus()">
-    <strong>&lt;s:actionerror/></strong>
-    <strong>&lt;s:form action="Login" validate="true"></strong>
-      <strong>&lt;s:textfield key="username"/></strong>
-      <strong>&lt;s:password key="password"/></strong>
-      <strong>&lt;s:submit key="button.save"/></strong>
-      <strong>&lt;s:reset key="button.reset"/></strong>
-      &lt;s:submit <strong>action="Login_cancel" onclick="form.onsubmit=null"</strong>
-        key="button.cancel"/>
-    &lt;/s:form>
-    &lt;jsp:include page="Footer.jsp"/>
-  &lt;/body>
-&lt;/html></code></pre>
-<hr/>
-
-<p>
-    We already saw some of the tags used by the Login page on the Welcome page.
-    Let's focus on the new tags.
-</p>
-
-<p>
-    The first new tag on the Login page is <strong>actionerrors</strong>.
-    Most of the possible validation errors are related to a single field.
-    If you don't enter a username,
-    the framework can place an error message near the tag prompting you to
-    enter a username.
-    But some messages are not related to a single field.
-    For example, the database might be down.
-    If the action returns an "Action Error", as opposed to a "Field Error",
-    the messages are rendered in place of the "actionerror" tag.
-    The text for the validation errors, whether they are Action Errors or
-    Field Errors, can be specified in the resource bundle,
-    making the messages easy to manage and localize.
-</p>
-
-<p>
-    The second new tag is <strong>form</strong>.
-    This tag renders a HTML form tag.
-    The "validate=true" setting enables client-side validation,
-    so that the form can be validated with JavaScript before being sent
-    back to the server.
-    The framework will still validate the form again, just to be sure, but the
-    client-side validation can save a few round-trips to the server.
-</p>
-
-<p>
-    Within the form tag,
-    we see four more new tags: "textfield", "password", "submit",
-    and "reset". We also see a second usage of "submit" that utilizes an
-    "action" attribute.
-</p>
-
-<p>
-    When we place a control on a form, we usually need to code a set of
-    HTML tags to do everything we want to do.
-    Most often, we do not just want a plain "input type=text" tag.
-    We want the input field to have a label too, and maybe even
-    a tooltip. And, of course, a place to print a message
-    should invalid data be entered.
-</p>
-
-<p>
-    The Struts Tags support templates and themes so that a set of HTML tags can be
-    rendered from a single Struts Tag. For example, the single tag
-</p>
-
-<pre><code>
-    &lt;s:<strong>textfield</strong> key="username"/>
-</code></pre>
-
-<p>
-    generates a wad of HTML markup.
-</p>
-
-<hr/>
-<pre><code>&lt;tr>
-  &lt;td class="tdLabel">
-    &lt;label for="Login_username" class="label">Username:&lt;/label>
-  &lt;/td>
-  &lt;td>
-    &lt;input type="text" name="username" value="" id="Login_username"/>
-  &lt;/td>
-&lt;/tr></code></pre>
-<hr/>
-
-<p>
-    If for some reason you don't like the markup generated by a Struts Tag,
-    it's each to change.
-    Each tag is driven by a template that can be updated on a tag-by-tag basis.
-    For example,
-    here is the default template that generates the markup for the ActionErrors tag:
-</p>
-
-<hr/>
-<pre><code>&lt;#if (actionErrors?exists &amp;&amp; actionErrors?size > 0)>
-  &lt;ul>
-    &lt;#list actionErrors as error>
-      &lt;li>&lt;span class="errorMessage">${error}&lt;/span>&lt;/li>
-    &lt;/#list>
-  &lt;/ul>
-&lt;/#if></code></pre>
-<hr/>
-
-<p>
-    If you wanted ActionErrors displayed in a table instead of a list,
-    you could edit a copy of this file, save it as a file named
-    "template/simple/actionerror.ftl",
-    and place this one file at the base of your application's classpath.
-</p>
-
-<hr/>
-<pre><code>&lt;#if (actionErrors?exists &amp;&amp; actionErrors?size > 0)>
-  <strong>&lt;table></strong>
-    &lt;#list actionErrors as error>
-      <strong>&lt;tr>&lt;td></strong>&lt;span class="errorMessage">${error}&lt;/span><strong>&lt;/td>&lt;/tr></strong>
-    &lt;/#list>
-  <strong>&lt;/table></strong>
-&lt;/#if></code></pre>
-<hr/>
-
-<p>
-    Under the covers, the framework uses
-    <a href="http://freemarker.sourceforge.net/">Freemarker</a>
-    for its standard templating language.
-    FreeMarker is similar to
-    <a href="http://jakarta.apache.org/velocity/">Velocity</a>,
-    but it offers better error reporting and some additional features.
-    If you prefer, Velocity and JSP templates can also be used to create your own tags.
-</p>
-
-<p>
-    The <strong>password</strong> tag renders a "input type=password"
-    tag, along with the usual template/theme markup.
-    By default, the password tag will not retain input if the submit fails.
-    If the username is wrong,
-    the client will have to enter the password again too.
-    (If you did want to retain the password when validation fails,
-    you can set the tag's "showPassword" property to true.)
-</p>
-
-<p>
-    Unsurprisingly, the <strong>submit</strong> and <strong>reset</strong> tags
-    render buttons of the corresponding types.
-</p>
-
-<p>
-    The second submit button is more interesting.
-</p>
-
-<pre><code>  &lt;s:submit <strong>action="Login_cancel" onclick="form.onsubmit=null"</strong>
-    key="button.cancel"/>
-</code></pre>
-
-<p>
-    Here we are creating the Cancel button for the form.
-    The button's attribute <em>action="Login<strong>_</strong>cancel"</em>
-    tells the framework to submit to the Login's "cancel" method
-    instead of the usual "execute" method.
-    The <em>onclick="form.onsubmit=null"</em> script defeats client-side validation.
-    On the server side, "cancel" is on a special list of methods that bypass validation,
-    so the request will go directly to the Action's <strong>cancel</strong> method.
-    Another entry on the special-case list is the "input" method.
-</p>
-
-<hr/>
-<h5>Tip:</h5>
-<blockquote>
-    <p><font class="hint">
-        The Struts Tags have options and capabilities beyond what we have shown here.
-        For more see, the <a href="http://cwiki.apache.org/WW/tag-developers-guide.html">
-            Struts Tag documentation.</a>
-    </font></p>
-</blockquote>
-<hr/>
-
-<p>
-    OK, but how do the tags know that both of these fields are required?
-    How do they know what message to display when the fields are empty?
-</p>
-
-<p>
-    For the answers, we need to look at another flavor of configuration file:
-    the "validation" file.
-</p>
-
-<h4><a name="Login-validation.xml" id="Login-validation.xml">Login-validation.xml</a>
-</h4>
-
-<p>
-    While it is not hard to code data-entry validation into an Action class,
-    the framework provides an even easier way to validate input.
-</p>
-
-<p>
-    The validation framework is configured through another XML document, the <strong>
-    Login-validation.xml</strong>.
-</p>
-
-<hr/>
-<h5>Validation file for Login Action</h5>
-<pre><code>&lt;!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
-  "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-&lt;validators>
-  &lt;field name="<strong>username</strong>">
-    &lt;field-validator type="<strong>requiredstring</strong>">
-    &lt;message key="<strong>error.username.required</strong>"/>
-  &lt;/field-validator>
-  &lt;/field>
-  &lt;field name="<strong>password</strong>">
-    &lt;field-validator type="<strong>requiredstring</strong>">
-    &lt;message key="<strong>error.password.required</strong>"/>
-    &lt;/field-validator>
-  &lt;/field>
-&lt;/validators>
-</code></pre>
-<hr/>
-
-<p>
-   You may note that the DTD refers to "XWork".
-   <a href="http://www.opensymphony.com/xwork/">
-     Open Symphony XWork
-   </a> is a generic command-pattern framework that can be used outside of a
-   web environment. Essentially, Struts 2 is a web-based extension of the
-   XWork framework.
-</p>
-
-<p>
-    The field elements correspond to the ActionForm properties.
-    The <strong>username</strong> and <strong>password</strong> field elements
-    say that each field depends on the "requiredstring" validator.
-    If the username is blank or absent, validation will fail and an error
-    message is generated.
-    The messages would be based on the "error.username.required" or
-    "error.password.required" message templates from the resource bundle.
-</p>
-
-<!--
-<p>
-    The <strong>password</strong> field (or property) is also required.
-    In addition, it must also pass the "maxlength" and "minlength"
-    validations.
-    Here, the minimum length is three characters and the maximum length is
-    sixteen.
-    If the length of the password doesn't meet these criteria, a corresponding
-    error message is generated.
-    Of course, the messages are generated from the MessageResource bundles and
-    are easy to localize.
-</p>
--->
-
-<h4><a name="Login.java" id="Login.java">Login Action</a></h4>
-
-<p>
-    If validation passes, the framework invokes the "execute" method of the Login Action.
-    The actual Login Action is brief, since most of the functionality derives
-    from the base class, <strong>MailreaderSupport</strong>.
-</p>
-
-<hr/>
-<h5>Login.java</h5>
-<pre><code>package mailreader2;
-import org.apache.struts.apps.mailreader.dao.User;
-public final class <strong>Login</strong> extends MailreaderSupport {
-public String <strong>execute()</strong> throws ExpiredPasswordException {
-  User user = <strong>findUser(getUsername(), getPassword());</strong>
-  if (user != null) {
-    <strong>setUser(user);</strong>
-  }
-  if (<strong>hasErrors()</strong>) {
-    return INPUT;
-  }
-    return SUCCESS;
-  }
-}</code></pre>
-<hr/>
-
-<p>
-    Login lays out what we do to authenticate a user.
-    We try to find the user using the credentials provided.
-    If the user is found, we cache a reference.
-    If the user is not found, we return "input" so the client can try again.
-    Otherwise, we return "success", so that the client can access the rest of the application.
-</p>
-
-<h4><a name="MailreaderSupport.java" id="MailreaderSupport.java">MailreaderSupport.java</a></h4>
-
-<p>
-    Let's look at the relevant properties and methods from MailreaderSupport
-    and another base class, <strong>ActionSupport</strong>, namely
-    "getUsername", "getPassword", "findUser", "setUser", and "hasErrors".
-</p>
-
-<p>
-    The framework lets you define
-    <a href="http://struts.apache.org/primer.html#javabeans">JavaBean properties</a>
-    directly on the Action.
-    Any JavaBean property can be used, including rich objects.
-    When a request comes in,
-    any public properties on the Action class are matched with the request parameters.
-    When the names match, the request parameter value is set to the JavaBean property.
-    The framework will make its best effort to convert the data,
-    and, if necessary, it will report any conversion errors.
-</p>
-
-<p>
-    The <strong>Username</strong> and <strong>Password</strong> properties are nothing fancy,
-    just standard JavaBean properties.
-</p>
-
-<hr/>
-<h5>MailreaderSupport.getUsername() and getPassword()</h5>
-<pre><code>private String username = null;
-public String <strong>getUsername()</strong> {
-  return this.username;
-}
-public void setUsername(String username) {
-  this.username = username;
-}
-
-private String password = null;
-public String <strong>getPassword()</strong> {
-  return this.password;
-}
-public void setPassword(String password) {
-  this.password = password;
-}</code></pre>
-<hr/>
-
-<p>
-    We use these properties to capture the client's credentials,
-    and pass them to the more interesting <strong>findUser</strong> method.
-</p>
-
-<hr/>
-<h5>MailreaderSupport.findUser</h5>
-<pre><code>public User <strong>findUser</strong>(String username, String password)
-  throws <strong>ExpiredPasswordException</strong> {
-  User user = <strong>getDatabase().findUser(username)</strong>;
-  if ((user != null) &amp;&amp; !user.getPassword().equals(password)) {
-    user = null;
-  }
-  if (user == null) {
-    this.<strong>addFieldError</strong>("password", getText("error.password.mismatch"));
-  }
-  return user;
-}</code></pre>
-<hr/>
-
-<p>
-    The "findUser" method dips into the MailReader Data Access Object layer,
-    which is represented by the <strong>Database</strong> property.
-    The code for the DAO layer is maintained as a separate component.
-    The MailReader application imports the DAO JAR,
-    but it is not responsible for maintaining any of the DAO source.
-    Keeping the data access layer at "arms-length" is a very good habit.
-    It encourages a style of development where the data access layer
-    can be tested and developed independently of a specific end-user application.
-    In fact, there are several renditions of the MailReader application,
-    all which share the same MailReader DAO JAR!
-</p>
-
-<hr/>
-<h5>Best Practice:</h5>
-<blockquote>
-    <p>
-        <font class="hint">"Strongly separate data access and business logic from the rest of
-            the application."</font>
-    </p>
-</blockquote>
-<hr/>
-
-<p>
-    When "findUser" returns,
-    the Login Action looks to see if a valid (non-null) User object is returned.
-    A valid User is passed to the <strong>User property</strong>.
-    Although it is still a JavaBean property,
-    the User property is not implemented in quite the same way as Username and Password.
-</p>
-
-<hr/>
-<h5>MailreaderSupport.setUser</h5>
-<pre><code>public User getUser() {
-  return (User) <strong>getSession().get(Constants.USER_KEY)</strong>;
-}
-public void setUser(User user) {
-  getSession().put(Constants.USER_KEY, user);
-}</code></pre>
-<hr/>
-
-<p>
-    Instead of using a field to store the property value,
-    "setUser" passes it to a <strong>Session</strong> property.
-</p>
-
-<hr />
-<h5>MailreaderSupport.getSession() and setSession()</h5>
-<pre><code>private Map session;
-public Map <strong>getSession()</strong> {
-  return session;
-
-public void <strong>setSession(Map value)</strong> {
-  session = value;
-}</code></pre>
-<hr />
-
-<p>
-    To look at the MailreaderSupport class,
-    you would think the Session property is a plain-old Map.
-    In fact,
-    the Session property is an adapter that is backed by the servlet session object at runtime.
-    The MailreaderSupport class doesn't need to know that though.
-    It can treat Session like any other Map.
-    We can also test the MailreaderSupport class by passing it some other implementation of
-    Map, running the test,
-    and then looking to see what changes MailreaderSupport made to our "mock" Session object.
-</p>
-
-<p>
-    But, when MailreaderSupport is running inside a web application,
-    how does it acquire a reference to the servlet session?
-</p>
-
-<p>
-    Good question. If you were to look at just the MailreaderSupport class,
-    you would not see a single line of code that sets the session property.
-    But, yet, when we run the class, the session property is not null.
-    Hmmm.
-</p>
-
-<p>
-    The magic that provides the Session property a runtime value is called
-    "dependency injection".
-    The MailreaderSupport class implements a interface called <strong>SessionAware</strong>.
-    SessionAware is bundled with the framework,
-    and it defines a setter for the Session property.
-</p>
-
-<p>
-    <code>public void <strong>setSession</strong>(Map session);</code>
-</p>
-
-<p>
-    Also bundled with the framework is an object called the
-    <strong>ServletConfigInterceptor</strong>.
-    If the ServletConfigInterceptor sees that an Action implements the SessionAware interface,
-    it automatically set the session property.
-</p>
-
-<pre><code>if (action instanceof <code>SessionAware</code>) {
-  ((SessionAware) action).<code>setSession</code>(context.getSession());
-}</code></pre>
-
-<p>
-    The framework uses these "Interceptor" classes to create a <strong>front controller</strong>
-    for each action an application defines.
-    Each Interceptor can peek at the request before an Action class is invoked,
-    and then again after the Action class is invoked.
-    (If you have worked with Servlet
-    <a href="http://struts.apache.org/primer.html#filters">Filters</a>,
-    you will recognize this pattern.
-    But, unlike Filters, Interceptors are not tied to HTTP.
-    Interceptors can be tested and developed outside of a web application.)
-</p>
-
-<p>
-    You can use the same set of Interceptors for all your actions,
-    or define a special set of Interceptors for any given action,
-    or define different sets of Interceptors to use with different types of actions.
-    The framework comes with a default set of Interceptors,
-    that it will use when another set is not specified,
-    but you can designate your own default Interceptor set (or "stack")
-    in the Struts configuration.
-</p>
-
-<p>
-    Many Interceptors provide a utility or helper functions,
-    like setting the session property.
-    Others, like the <strong>ValidationInterceptor</strong>,
-    can change the workflow of an action.
-    Interceptors are key feature of the framework,
-    and we will see a few more on the tour.
-</p>
-
-<p>
-    If a valid User is not found, or the password doesn't match,
-    the "findUser" method invokes the <strong>addFieldError</strong> method to note the
-    problem.
-    When "findUser" returns, the Login Action checks for errors,
-    and then it returns either INPUT or SUCCESS.
-</p>
-
-<p>
-    The "addFieldError" method is provided by the ActionSupport class,
-    which is bundled with the framework.
-    The constants for INPUT and SUCCESS are also provided by ActionSupport.
-    While the ActionSupport class provides many useful utilities,
-    you are not required to use it as a base class.
-    Any Java class can be used as an Action, if you like.
-</p>
-
-<p>
-    It is a good practice to provide a base class with utilities
-    that can be shared by an application's Action classes.
-    The framework does this with ActionSupport,
-    and the MailReader application does the same with the MailreaderSupport class.
-</p>
-
-<hr/>
-<h5>Best Practice:</h5>
-<blockquote>
-  <p><font class="hint">"Use a base class to define common functionality."</font></p>
-</blockquote>
-<hr/>
-
-<p>
-    But, what happens if Login returns INPUT instead of SUCCESS.
-    How does the framework know what to do next?
-</p>
-
-<p>
-    To answer that question,
-    we need to turn back to the Struts configuration
-    and look at how Login is declared.
-</p>
-
-
-<h4><a name="Login.xml" id="Login.xml">Login Configuration</a></h4>
-
-<p>
-    The Login action element outlines how the Login workflow operates,
-    including what to do when the Action returns "input",
-    or the default result name "success".
-</p>
-
-<hr/>
-<h5>mailreader-support.xml Login</h5>
-<pre><code>&lt;action name="<strong>Login_*</strong>" method="{1}" class="mailreader2.Login">
-  &lt;result name="<strong>input</strong>">/pages/Login.jsp&lt;/result>
-  &lt;result name="<strong>cancel</strong>" type="redirect-action">Welcome&lt;/result>
-  &lt;result type="redirect-action">MainMenu&lt;/result>
-  &lt;result name="<strong>expired</strong>" type="chain">ChangePassword&lt;/result>
-  &lt;<strong>exception-mapping</strong>
-    exception="org.apache.struts.apps.mailreader.dao.ExpiredPasswordException"
-  result="<strong>expired</strong>"/>
-  &lt;interceptor-ref name="<strong>guest</strong>"/>
-&lt;/action></code></pre>
-<hr/>
-
-<p>
-    You might notice that the name of the Login action element is not "Login"
-    but "Login<strong>_*</strong>".
-    The asterisk is a special "wildcard" notation that tells the framework to match any series
-    of character at this point.
-    In the method attribute,
-    the "{1}" notation indicates that framework should substitute whatever characters match
-    the asterisk at runtime.
-    When we cite actions like "Login_cancel" or "Login_input",
-    the framework matches "cancel" or "input" with the wildcard and fills in the blanks.
-</p>
-
-<p>
-    The "trailing bang" notation was hardwired into WebWork 2.
-    To provide backward compatibility,
-    the notation is supported by Struts 2.0.
-    If you prefer to use wildcards to emulate the same notation,
-    as the Mailreader does,
-    you should disable the old notation in the Struts properties file.
-</p>
-
-<hr/>
-<h5>struts.properties</h5>
-<pre><code>struts.enable.DynamicMethodInvocation = false</code></pre>
-<hr/>
-
-<p>
-    Using wildcards with a exclamation point (or "bang") is not the only way we can use
-    wilcards to invoke methods.
-    If we wanted to use actions like "inputLogin",
-    we could move the asterisk and use an action name like "*Login".
-</p>
-
-<p>
-    Within the Login action element, the first result element is named "input".
-    If validation or authentification fail,
-    the Action class will return "input" and the framework will transfer control to the
-    "Login.jsp" page.
-</p>
-
-<p>
-    The second result element is named <strong>cancel</strong>.
-    If someone presses the cancel button on the Login page,
-    the Action class will return "cancel", this result will be selected,
-    and the framework will issue a redirect to the Welcome action.
-</p>
-
-<p>
-    The third result has no name,
-    so it will be called if the default <strong>success</strong> token is returned.
-    So, if the Login succeeds,
-    control will transfer to the MainMenu action.
-</p>
-
-<p>
-    The MailReader DAO exposes a "ExpiredPasswordException".
-    If the DAO throws this exception when the User logs in,
-    the framework will process the exception-mapping
-    and transfer control to the "ChangePassword" action.
-</p>
-
-<p>
-    Just in case any other Exceptions are thrown,
-    the MailReader application also defines a global handler.
-</p>
-
-<hr/>
-<h5>mailreader-default.xml exception-mapping</h5>
-<pre><code>&lt;global-exception-mappings>
-  &lt;exception-mapping
-    result="error"
-    exception="java.lang.Exception"/>
-&lt;/global-exception-mappings></code></pre>
-<hr/>
-
-<p>
-    If an unexpected Exception is thrown,
-    the exception-mapping will transfer control to the action's "error" result,
-    or to a global "error" result.
-    The MailReader defines a global "error" result
-    which transfers control to an "Error.jsp" page
-    that can display the error message.
-</p>
-
-<hr/>
-<h5>Error.jsp</h5>
-<pre><code>&lt;%@ page contentType="text/html; charset=UTF-8" %>
-&lt;%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
-  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  &lt;head>
-    &lt;title>Unexpected Error&lt;/title>
-  &lt;/head>
-  &lt;body>
-    &lt;h2>An unexpected error has occured&lt;/h2>
-    &lt;p>
-      Please report this error to your system administrator
-      or appropriate technical support personnel.
-      Thank you for your cooperation.
-    &lt;/p>
-    &lt;hr />
-    &lt;h3>Error Message&lt;/h3>
-    <strong>&lt;s:actionerror /></strong>
-    &lt;p>
-      <strong>&lt;s:property value="%{exception.message}"/></strong>
-    &lt;/p>
-    &lt;hr />
-    &lt;h3>Technical Details&lt;/h3>
-    &lt;p>
-      <strong>&lt;s:property value="%{exceptionStack}"/></strong>
-    &lt;/p>
-    &lt;jsp:include page="Footer.jsp"/>
-  &lt;/body>
-&lt;/html></code></pre>
-<hr/>
-
-<p>
-    The Error page uses <strong>property</strong> tags to expose
-    the Exception message and the Exception stack.
-</p>
-
-<p>
-    Finally, the Login action specifies an <strong>InterceptorStack</strong>
-    named <strong>defaultStack.</strong>
-    If you've worked with Struts 2 or WebWork 2 before, that might seem strange,
-    since "defaultStack" is the factory default.
-</p>
-
-<p>
-    In the MailReader application, most of the actions are only available
-    to authenticated users.
-    The exceptions are the Welcome, Login, and Register actions
-    which are available to everyone.
-    To authenticate clients,
-    the MailReader uses a custom Interceptor and a custom Interceptor stack.
-</p>
-
-<hr/>
-<h5>mailreader2.AuthenticationInterceptor</h5>
-<pre><code>package mailreader2;
-import com.opensymphony.xwork2.interceptor.Interceptor;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.Action;
-import java.util.Map;
-import org.apache.struts.apps.mailreader.dao.User;
-
-public class <strong>AuthenticationInterceptor</strong> implements Interceptor {
-  public void destroy () {}
-  public void init() {}
-  public String <strong>intercept</strong>(ActionInvocation actionInvocation) throws Exception {
-    Map session = actionInvocation.getInvocationContext().getSession();
-    User user = (User) session.get(Constants.USER_KEY);
-    boolean isAuthenticated = (null!=user) &amp;&amp; (null!=user.getDatabase());
-    if (<strong>isAuthenticated</strong>) {
-      return actionInvocation.invoke();
-    }
-    else {
-      return Action.LOGIN;
-    }
-  }
-}</code></pre>
-<hr/>
-
-<p>
-    The <strong>AuthenticationInterceptor</strong> looks to see if a User object
-    has been stored in the client's session state.
-    If so, it returns normally, and the next Interceptor in the set would be invoked.
-    If the User object is missing, the Interceptors returns "login".
-    The framework would match "login" to the global result,
-    and transfer control to the Login action.
-</p>
-
-<p>
-    The MailReader defines three custom Interceptor stacks: "user", "user-submit",
-    and "guest".
-</p>
-
-<hr/>
-<h5>mailreader-default.xml interceptors</h5>
-<pre><code>&lt;interceptors>
-  &lt;interceptor name="<strong>authentication</strong>"
-               class="mailreader2.AuthenticationInterceptor"/>
-  &lt;interceptor-stack name="<strong>user</strong>" >
-      &lt;interceptor-ref name="authentication" />
-      &lt;interceptor-ref name="defaultStack"/>
-  &lt;/interceptor-stack>
-  &lt;interceptor-stack name="<strong>user-submit</strong>" >
-      &lt;interceptor-ref name="tokenSession" />
-      &lt;interceptor-ref name="user"/>
-  &lt;/interceptor-stack>
-  &lt;interceptor-stack name="<strong>guest</strong>" >
-      &lt;interceptor-ref name="defaultStack"/>
-  &lt;/interceptor-stack>
-&lt;/interceptors>
-&lt;<strong>default-interceptor-ref</strong> name="user"/></code></pre>
-<hr/>
-
-<p>
-    The <strong>user</strong> stacks require that the client be authenticated.
-    In other words, that a User object is present in the session.
-    The actions using a <strong>guest</strong> stack can be accessed by any client.
-    The <strong>-submit</strong> versions of each can be used with actions
-    with forms, to guard against double submits.
-</p>
-
-<h5>Double Submits</h5>
-
-<p>
-    A common problem with designing web applications is that users are impatient
-    and response times can vary.
-    Sometimes, people will press a submit button a second time.
-    When this happens, the browser submits the request again,
-    so that we now have two requests for the same thing.
-    In the case of registering a user, if someone does press the submit button
-    again, and their timing is bad,
-    it could result in the system reporting that the username has already been
-    used.
-    (The first time the button was pressed.)
-    In practice, this would probably never happen, but for a longer running
-    process, like checking out a shopping cart,
-    it's easier for a double submit to occur.
-</p>
-
-<p>
-    To forestall double submits, and "back button" resubmits,
-    the framework can generate a token that is embedded in the form
-    and also kept in the session.
-    If the value of the tokens do not compare,
-    then we know that there has been a problem,
-    and that a form has been submitted twice or out of sequence.
-</p>
-
-<p>
-    The Token Session Interceptor will also attempt to provide intelligent
-    fail-over in the event of multiple requests using the same session.
-    That is, it will block subsequent requests until the first request is complete,
-    and then instead of returning the "invalid.token" code,
-    it will attempt to display the same response that the
-    original, valid action invocation would have displayed
-</p>
-
-<p>
-    Because the default interceptor stack will now authenticate the client,
-    we need to specify the standard "defaultStack" for the three
-    "guest actions", Welcome, Login, and Register.
-    Requiring authentification by default is the better practice, since it
-    means that we won't forget to enable it when creating new actions.
-    Meanwhile, those pesky users will ensure that we don't forget to disable
-    authentification for "guest" services.
-</p>
-
-<h3><a name="MainMenu" id="MainMenu">MainMenu</a></h3>
-
-<p>
-    On a successful login, the Main Menu page displays.
-    If you logged in using the demo account,
-    the page title should be "Main Menu Options for John Q. User".
-    Below this legend should be two links:
-</p>
-
-<ul>
-    <li>
-        Edit your user registration profile
-    </li>
-    <li>
-        Log off MailReader Demonstration Application
-    </li>
-</ul>
-
-<p>
-    Let's review the source for the "MainMenu" action mapping,
-    and the "MainMenu.jsp".
-</p>
-
-<hr/>
-<h5>Action mapping element for MainMenu</h5>
-<pre><code>&lt;action name="MainMenu" class="mailreader2.MailreaderSupport">
-    &lt;result>/pages/MainMenu.jsp&lt;/result>
-    &lt;/action></code></pre>
-
-<h5>MainMenu.jsp</h5>
-<pre><code>&lt;%@ page contentType="text/html; charset=UTF-8" %>
-&lt;%@ taglib prefix="s" uri="http://struts.apache.org/tags"  %>
-&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  &lt;head>
-    &lt;title>&lt;s:text name="mainMenu.title"/>&lt;/title>
-      &lt;link href="&lt;s:url value="/css/mailreader.css"/>" rel="stylesheet"
-      type="text/css"/>
-  &lt;/head>
-
-  &lt;body>
-  &lt;h3>&lt;s:text name="mainMenu.heading"/> <strong>&lt;s:property
-    value="user.fullName"/></strong>&lt;/h3>
-  &lt;ul>
-    &lt;li>&lt;a href="&lt;s:url <strong>action="Registration_input"</strong> />">
-        &lt;s:text name="mainMenu.registration"/>
-      &lt;/a>
-    &lt;/li>
-    &lt;li>&lt;a href="&lt;s:url <strong>action="Logout"</strong> />">
-      &lt;s:text name="mainMenu.logout"/>
-      &lt;/a>
-    &lt;/ul>
-  &lt;/body>
-&lt;/html></code></pre>
-<hr/>
-
-<p>
-    The source for "MainMenu.jsp" also contains a new tag, <strong>
-    property</strong>, which we use to customize the page with the
-    "fullName" property of the authenticated user.
-</p>
-
-<p>
-    Displaying the user's full name is the reason the MainMenu action
-    references the MailreaderSupport class.
-    The MailreaderSupport class has a User property that the text tag
-    can access.
-    If we did not utilize MailreaderSupport,
-    the property tag would not be able to find the User object to print
-    the full name.
-</p>
-
-<p>
-    The customized MainMenu page offers two standard links.
-    One is to "Edit your user registration profile".
-    The other is to "Logout the MailReader Demonstration Application".
-</p>
-
-<h3><a name="Registration.jsp" id="Registration.jsp">Registration page</a>
-</h3>
-
-<p>
-    If you follow the "Edit your user registration profile" link from the Main
-    Menu page,
-    we will finally reach the heart of the MailReader application: the
-    Registration, or "Profile", page.
-    This page displays everything MailReader knows about you
-    (or at least your login),
-    while utilizing several interesting techniques.
-</p>
-
-<p>
-    To do double duty as the "Create" Registration page and the "Edit"
-    Registration page,
-    the "Registration.jsp" makes extensive use of the test tags,
-    to make it appears as though there are two distinct pages.
-</p>
-
-<hr />
-<h5>Registration.jsp - head element</h5>
-<pre><code>&lt;head>
-  &lt;s:if test="<strong>task=='Create'</strong>">
-    &lt;title>&lt;s:text name="registration.title.create"/>&lt;/title>
-  &lt;/s:if>
-  &lt;s:if test="<strong>task=='Edit'</strong>">
-    &lt;title>&lt;s:text name="registration.title.edit"/>&lt;/title>
-  &lt;/s:if>
-  &lt;link href="&lt;s:url value="/css/mailreader.css"/>" rel="stylesheet"
-    type="text/css"/>
-&lt;/head></code></pre>
-<hr />
-
-<p>
-    For example, if client is editing the form (task == 'Edit'),
-    the page inserts the username from the User object.
-    For a new Registration (task == 'Create'),
-    the page creates an empty data-entry field.
-</p>
-
-<hr/>
-<h5>Note:</h5>
-<blockquote>
-    <p><font class="hint">
-        <strong>Presention Logic</strong> -
-        The "test" tag is a convenient way to express presentation
-        logic within your pages.
-        Customized pages help to prevent user error,
-        and dynamic customization reduces the number of server pages your
-        application needs to maintain, among other benefits.
-    </font></p>
-</blockquote>
-<hr/>
-
-<p>
-    The page also uses logic tags to display a list of subscriptions
-    for the given user.
-    If the RegistrationForm has task set to "Edit",
-    the lower part of the page that lists the subscriptions is exposed.
-</p>
-
-<hr/>
-<h5></h5>
-<pre><code>&lt;s:if test=<strong>"task == 'Edit'"</strong>>
-  &lt;div align="center">
-    &lt;h3>&lt;s:text name="heading.subscriptions"/>&lt;/h3>
-  &lt;/div>
-    &lt;!-- ... -->
-  &lt;/s:if>
-&lt;jsp:include page="Footer.jsp"/>
-&lt;/body>&lt;/html></code></pre>
-<hr/>
-
-<p>
-    Otherwise, the page contains just the top portion --
-    a data-entry form for managing the user's registration.
-</p>
-
-<h4><a name="iterator" id="iterator">iterator</a></h4>
-
-<p>
-    Besides "if" there are several other control tags that you can use
-    to sort, filter, or iterate over data.
-    The Registration page includes a good example of using the <strong>iterator</strong>
-    tag to display the User's Subscriptions.
-</p>
-
-<p>
-    The subscriptions are stored in a hashtable object, which is in turn
-    stored in the user object.
-    So to display each subscription, we have to reach into the user object,
-    and loop through the members of the subscription collection.
-    Using the iterator tag, you can code it the way it sounds.
- </p>
-
-<hr/>
-<h5>Using iterator to list the Subscriptions</h5>
-<pre><code>&lt;s:iterator value="<strong>user.subscriptions</strong>">
-  &lt;tr>
-    &lt;td align="left">
-      &lt;s:property value="<strong>host</strong>"/>
-    &lt;/td>
-    &lt;td align="left">
-       &lt;s:property value="<strong>username</strong>"/>
-   &lt;/td>
-  &lt;td align="center">
-      &lt;s:property value="<strong>type</strong>"/>
-  &lt;/td>
-  &lt;td align="center">
-     &lt;s:property value="<strong>autoConnect</strong>"/>
-  &lt;/td>
-  &lt;td align="center">
-    &lt;a href="&lt;s:url action="<strong>Subscription_delete</strong>">&lt;s:param name="<strong>host</strong>" value="host"/>&lt;/s:url>">
-      &lt;s:text name="registration.deleteSubscription"/>
-    &lt;/a>&nbsp;
-    &lt;a href="&lt;s:url action="<strong>Subscription_edit</strong>">&lt;s:param name="<strong>host</strong>" value="host"/>&lt;/s:url>">
-      &lt;s:text name="registration.editSubscription"/>
-     &lt;/a>
-   &lt;/td>
- &lt;/tr>
-&lt;/s:iterator></code></pre>
-<hr/>
-
-<p>
-    When the iterator renders, it generates a list of Subscriptions for the current User.
-</p>
-
-<hr />
-
-    <div align="center">
-        <h3>Current Subscriptions</h3>
-    </div>
-
-    <table border="1" width="100%">
-        <tr>
-            <th align="center" width="30%">
-                Host Name
-            </th>
-            <th align="center" width="25%">
-                User Name
-            </th>
-
-            <th align="center" width="10%">
-                Server Type
-            </th>
-            <th align="center" width="10%">
-                Auto
-            </th>
-            <th align="center" width="15%">
-                Action
-            </th>
-        </tr>
-            <tr>
-                <td align="left">
-                    mail.hotmail.com
-                </td>
-                <td align="left">
-                    user1234
-                </td>
-                <td align="center">
-                    pop3
-                </td>
-
-                <td align="center">
-                    false
-                </td>
-                <td align="center">
-                    <a href="/struts2-mailreader/Subscription_delete.do?host=mail.hotmail.com">
-                        Delete
-                    </a>
-                    &nbsp;
-                    <a href="/struts2-mailreader/Subscription_edit.do?host=mail.hotmail.com">
-                        Edit
-                    </a>
-                </td>
-            </tr>
-            <tr>
-                <td align="left">
-                    mail.yahoo.com
-                </td>
-                <td align="left">
-                    jquser
-                </td>
-                <td align="center">
-                    imap
-                </td>
-                <td align="center">
-                    false
-                </td>
-                <td align="center">
-                    <a href="/struts2-mailreader/Subscription_delete.do?host=mail.yahoo.com">
-                        Delete
-                    </a>
-                    &nbsp;
-                    <a href="/struts2-mailreader/Subscription_edit.do?host=mail.yahoo.com">
-                        Edit
-                    </a>
-                </td>
-            </tr>
-    </table>
-    <a href="/struts2-mailreader/Subscription_input.do">Add</a>
-
-<hr />
-
-    <p>
-        Now look back at the code used to generate this block.
-    </p>
-    <p>
-        Notice anything nifty?
-    </p>
-    <p>
-        How about that the markup between the iterator tag is
-        actually <em>simpler</em> than the markup that we would use to render one row of the
-        table?
-    </p>
-    <p>
-        Instead of using a qualified reference  like "value=user.subscription[0].host",
-        we use the simplest possible reference: "value=host".
-        We didn't have to define a local variable, and reference that local in the loop code.
-        The reference to each item in the list is automatically resolved, no fuss, no muss.
-    </p>
-    <p>
-        Nice trick!
-    </p>
-
-<p>
-    The secret to this magic is the <strong>value stack</strong>.
-    Next to Interceptors, the value stack is probably the coolest thing there is about the
-    framework.
-    To explain the value stack, let's step back and start from the beginning.
-</p>
-
-<p>
-    Merging dynamic data into static web pages is a primary reason
-    we create web applications.
-    The Java API has a mechanism that allows you to
-    place objects in a servlet scope (page, request, session, or
-    application), and then retrieve them using a JSP scriplet.
-    If the object is placed directly in one of the scopes,
-    a JSP tag or scriptlet can find that object by searching page scope and
-    then request scope, and session scope, and finally application scope.
-</p>
-
-<p>
-    The value stack works much the same way, only better.
-    When you push an object on the value stack,
-    the public properties of that object become first-class properties of the stack.
-    The object's properties become the stack's properties.
-    If another object on the stack has properties of the same name,
-    the last object pushed onto the stack wins. (Last-In, First-Out.)
-</p>
-
-<p>
-    When the iterator tag loops through a collection,
-    it pushes each item in the collection onto the stack.
-    The item's properties become the stack's property.
-    In the case of the Subscriptions,
-    if the Subscription has a public Host property,
-    then during that iteration,
-    the stack can access the same property.
-</p>
-
-<p>
-    Of course, at the end of each iteration, the tag "pops" the item off the stack.
-    If we were to try and access the Host property later in the page,
-    it won't be there.
-</p>
-
-<p>
-    When an Action is invoked, the Action class is pushed onto the value stack.
-    Since the Action is on the value stack,
-    our tags can access any property of the Action
-    as if it were an implicit property of the page.
-    The tags don't access the Action directly.
-    If a textfield tag is told to render the "Username" property,
-    the tag asks the value stack for the value of "Username",
-    and the value stack returns the first property it finds by that name,
-    on any object on the stack.
-</p>
-
-<p>
-    The Validators also use the stack.
-    When validation fails on a field,
-    the value for the field is pushed onto the value stack.
-    As a result, if the client enters text into an Integer field,
-    the framework can still redisplay whatever was entered.
-    An invalid input value is not stored in the field (even if it could be).
-    The invalid input is pushed onto the stack for the scope of the request.
-</p>
-
-<p>
-    The Subscription list uses another new tag: the <strong>param</strong> tag.
-    As tags go, "param" takes very few parameters of its own: just "name" and "value",
-    and neither is required.
-    Although simple, "param" is one of the most powerful tags the framework provides.
-    Not so much because of what it does,
-    but because of what "param" allows the other tags to do.
-</p>
-
-<p>
-    Essentially, the "param" tag provides parameters to other tags.
-    A tag like "text" might be retrieving a message template with several replaceable
-    parameters.
-    No matter how many parameters are in the template, and no matter what they are named,
-    you can use the "param" tag to pass in whatever you need.
-</p>
-
-<pre><code>pager.legend = Displaying {current} of {count} items matching {criteria}.
-...
-&lt;s:text name="pager.legend">
-    &lt;s:<strong>param</strong> name="current" value="42" />
-    &lt;s:<strong>param</strong> name="count" value="314" />
-    &lt;s:<strong>param</strong> name="criteria" value="Life, the Universe, and Everything" />
-&lt;/s:text></code></pre>
-
-<p>
-    In the case of an "url" tag,
-    we can use "param" to create the query string.
-    A statement like this:
-</p>
-
-<pre><code>
-  &lt;s:url action="Subscription_edit">&lt;s:param name="<strong>host" value="host</strong>"/>&lt;/s:url>">
-</code></pre>
-
-<p>
-  can render a hyperlink like this:
-</p>
-
-<pre><code>
-  &lt;a href="/struts2-mailreader/Subscription_edit.do?<strong>host=mail.yahoo.com</strong>">Edit&lt;/a>
-</code></pre>
-
-<!--
-<p>
-    At the foot of the Register page is a link for adding a subscription.
-    Let's wind up the tour by following the Add link and then logging off.
-    Like the link for creating a Registration, Add points to an "Edit" action,
-    namely "EditSubscription".
-</p>
--->
-
-<p>
-    If a hyperlink needs more parameters,
-    you can use "param" to add as many parameters as needed.
-</p>
-
-<h3>
-    <a name="Subscription" id="Subscription">Subscription</a>
-</h3>
-
-<p>
-    If we follow one of the "Edit" subscription links on the Registration page,
-    we come to the Subscriptions page,
-    which displays the details of our description in a data-entry form.
-    Let's have a look at the Subscription configuration
-    and follow the bouncing ball from page to action to page.
-</p>
-
-<hr />
-<h5>mailreader-support.xml Subscription element</h5>
-<pre><code>&lt;action name="Subscription_*" method="{1}" class="mailreader2.Subscription">
-  &lt;result name="input">/pages/Subscription.jsp&lt;/result>
-  &lt;result type="redirect-action">Registration_input&lt;/result>
-&lt;/action></code></pre>
-<hr />
-
-<p>
-    The Edit link specified the Subscription action,
-    but also includes the qualifier <strong>_edit</strong>.
-    The wildcard notation tells the framework to use any characters given after "Subscription_"
-    as the name of a method to invoke on the Action class,
-    instead of the default execute method.
-    The "alternate" execute methods are called <strong>alias</strong> methods.
-</p>
-
-<hr />
-<h5>Subscription edit alias</h5>
-<pre><code>public String <strong>edit()</strong> {
-  <strong>setTask(Constants.EDIT);</strong>>
-  return find();
-}
-
-public String find() {
-  org.apache.struts.apps.mailreader.dao.Subscription
-    sub = findSubscription();
-   if (sub == null) {
-       return ERROR;
-   }
-   <strong>setSubscription(sub);</strong>
-   return INPUT;
-}</code></pre>
-<hr />
-
-<p>
-    The "edit" alias has two responsibilities.
-    First, it must set the Task property to "Edit".
-    The Subscription page will render itself differently
-    depending on the value of the Task property.
-    Second, "edit" must locate the relevant Subscription
-    and set it to the Subscription property.
-    If all goes well, "edit" returns the INPUT token,
-    so that the "input" result will be invoked.
-</p>
-
-<p>
-    In the normal course, the Subscription should always be found,
-    since we selected the entry from a system-generated list.
-    If the Subscription is not found,
-    it would be because the database disappeared
-    or the request is being spoofed.
-    If the Subscription is not found,
-    edit returns the token for the global "error" result,
-    because this condition is unexpected.
-</p>
-
-<p>
-    The business logic for the "edit" alias is a simple wrapper
-    around the MailReader DAO classes.
-</p>
-
-<hr />
-<h5>MailreaderSupport findSubscription()</h5>
-<pre><code>public Subscription <strong>findSubscription()</strong> {
-    return findSubscription(getHost());
-}
-
-public Subscription findSubscription(String host) {
-    Subscription subscription;
-    subscription = <strong>getUser().findSubscription(host);</strong>
-    return subscription;
-}</code></pre>
-<hr />
-
-<p>
-    This code is very simple
-    and doesn't seem to provide much in the way of error handling.
-    But, that's OK.
-    Since the page is suppose to be entered from a link that we created,
-    we do expect everything to go right here.
-    But, if it doesn't, the global exception handler we defined in the
-    MailReader configuration will trap the exception for us.
-</p>
-
-<p>
-    Likewise, the AuthentificationInterceptor will ensure that only clients
-    with a valid User object can try to edit a Subscription.
-    If the session expired, or someone bookmarked the page,
-    the client will be redirected to the Login page automatically.
-</p>
-
-<p>
-    As a final layer of defense, we also configured a validator for Subscription,
-    to ensure that we are passed a Host parameter.
-</p>
-
-<hr />
-<h5>Subscription-validation.xml</h5>
-<pre><code>&lt;!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-&lt;validators>
-  &lt;field name="<strong>host</strong>">
-    &lt;field-validator type="<strong>requiredstring</strong>">
-        &lt;message key="error.host.required"/>
-    &lt;/field-validator>
-  &lt;/field>
-&lt;/validators></code></pre>
-<hr />
-
-<p>
-    By keeping routine safety precautions out of the Action class,
-    the all-important Action becomes smaller and easier to maintain.
-</p>
-
-<p>
-    After setting the relevent Subscription object to the Subscription property,
-    the framework transfers control to the (you guessed it) Subscription page.
-</p>
-
-<hr />
-<h5>Subscription.jsp</h5>
-<pre><code>&lt;%@ page contentType="text/html; charset=UTF-8" %>
-&lt;%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
-&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  &lt;head>
-    &lt;s:if test="task=='Create'">
-        &lt;title>&lt;s:text name="subscription.title.create"/>&lt;/title>
-    &lt;/s:if>
-    &lt;s:if test="task=='Edit'">
-        &lt;title>&lt;s:text name="subscription.title.edit"/>&lt;/title>
-    &lt;/s:if>
-    &lt;s:if test="task=='Delete'">
-        &lt;title>&lt;s:text name="subscription.title.delete"/>&lt;/title>
-    &lt;/s:if>
-    &lt;link href="&lt;s:url value="/css/mailreader.css"/>" rel="stylesheet"
-          type="text/css"/>
-  &lt;/head>
-  &lt;body onLoad="self.focus();document.Subscription.username.focus()">
-
-    &lt;s:actionerror/>
-    &lt;s:form <strong>action="Subscription_save"</strong> validate="true">
-      <strong>&lt;s:token /></strong>
-      <strong>&lt;s:hidden name="task"/></strong>
-      <strong>&lt;s:label key="username" name="user.username"/></strong>
-
-      &lt;s:if test="task == 'Create'">
-        &lt;s:textfield key="mailHostname" name="host"/>
-      &lt;/s:if>
-      &lt;s:else>
-        &lt;s:label key="mailHostname" name="host"/>
-        &lt;s:hidden name="host"/>
-      &lt;/s:else>
-
-      &lt;s:if test="task == 'Delete'">
-        &lt;s:label key="subscription.username"/>
-        &lt;s:label key="subscription.password"/>
-        &lt;s:label key="subscription.type"/>
-        &lt;s:label key="subscription.autoConnect"/>
-        &lt;s:submit key="button.confirm"/>
-      &lt;/s:if>
-      &lt;s:else>
-        &lt;s:textfield key="subscription.username"/>
-        &lt;s:textfield key="subscription.password"/>
-        <strong>&lt;s:select key="subscription.type" list="types"/></strong>
-        <strong>&lt;s:checkbox key="subscription.autoConnect"/></strong>
-        &lt;s:submit key="button.save"/>
-        &lt;s:reset key="button.reset"/>
-      &lt;/s:else>
-
-      &lt;s:submit action="Registration_input"
-                key="button.cancel"
-                onclick="form.onsubmit=null"/>
-  &lt;/s:form>
-
-  &lt;jsp:include page="Footer.jsp"/>
-  &lt;/body>
-&lt;/html></code></pre>
-<hr />
-
-<p>
-    As before, we'll discuss the tags and attributes that are new to this page:
-    "token", "hidden", "label", "select", and "checkbox".
-</p>
-
-<p>
-    The <strong>token</strong> tag works with the Token Session Interceptor to foil double
-    submits.
-    The tag generates a key that is embedded in the form and cached in the session.
-    Without this tag, the Interceptor can't work it's magic.
-</p>
-
-<p>
-    The <strong>hidden</strong> tag embeds the Task property into the form.
-    When the form is submitted,
-    the Subscription_save action will use the Task property to decide
-    whether to insert or update the form.
-</p>
-
-<p>
-    The <strong>label</strong> renders a "read only" version of a property,
-    suitable for placement in the form.
-    In Edit or Delete mode, we want the Host property to be immutable,
-    since it is used as a key. (As unwise as that might sound.)
-    In Delete mode, all of the properties are immutable,
-    since we are simply confirming the delete operation.
-</p>
-
-<p>
-    Saving the best for last, the Subscription form utilizes two more interesting
-    tags, "select" and "checkbox".
-</p>
-
-<p>
-    Unsurprisingly, the <strong>select</strong> tag renders a select control,
-    but the tag does so without requiring a lot of markup or redtape.
-</p>
-
-<pre><code>&lt;s:select key="subscription.type" <strong>list="types"</strong> />
-</code></pre>
-
-<p>
-    The interesting attribute of the "select" tag is "list",
-    which, in our case, specifies a value of "types".
-    If we take another look at the Subscription action,
-    we can see that it implements an interface named Preparable
-    and populates a Types property in a method named "prepare".
-</p>
-
-<hr />
-<h5>Subscription-validation.xml</h5>
-<pre><code>public class <strong>Subscription</strong> extends MailreaderSupport
-  <strong>implements Preparable</strong> {
-
-  private Map types = null;
-  public Map <strong>getTypes()</strong> {
-    return types;
-   }
-
-   public void <strong>prepare()</strong> {
-     Map m = new LinkedHashMap();
-       m.put("imap", "IMAP Protocol");
-       m.put("pop3", "POP3 Protocol");
-       types = m;
-       setHost(getSubscriptionHost());
-    }
-
-    // ... </code></pre>
-<hr />
-
-<p>
-    The default Interceptor stack includes the <strong>PrepareInterceptor</strong>,
-    which observes the Preparable interface.
-</p>
-
-<hr />
-<h5>PrepareInterceptor</h5>
-<pre><code>public class <strong>PrepareInterceptor</strong> extends AroundInterceptor {
-
-  protected void after(ActionInvocation dispatcher, String result) throws Exception {
-  }
-
-  protected void before(ActionInvocation invocation) throws Exception {
-    Object action = invocation.getAction();
-     <strong>if (action instanceof Preparable) {
-        ((Preparable) action).prepare();</strong>
-    }
-  }
-}</code></pre>
-
-<p>
-    The PrepareInterceptor ensures that the "prepare" method will always be called
-    before "execute" or an alias method is invoked.
-    We use "prepare" to setup the list of items for the select list to display.
-    We also transfer the Host property from our Subscription object
-    to a local property, where it is easier to manage.
-</p>
-
-<h4>
-    <a name="Subscription.java" id="Subscription.java">Subscription.java</a>
-</h4>
-
-<p>
-    Like many applications, the MailReader uses mainly String properties.
-    One exception is the AutoConnect property of the Subscription object.
-    On the HTML form, the AutoConnect property is represented by a checkbox.
-</p>
-
-<p>
-    When writing web applications, the checkbox can be a tricky control.
-    The Subscription object has a boolean AutoConnect property,
-    and the checkbox simply has to represent its state.
-    The problem is, if you clear a checkbox, the browser client will not submit <em>anything</em>.
-    Nada. Zip.
-    It is as if the checkbox control never existed.
-    The HTTP protocol has no way to affirm "false".
-    If the control is missing, we need to figure out it's been unclicked.
-</p>
-
-<p>
-    In Struts 1,
-    we use the <code>reset</code> method to work around checkbox issues.
-    In Struts 2, checkbox state is handled automatically.
-    The framework can detect when a checkbox tag has not been sent  back,
-    and when that happens,
-    a default "false" value is used for the checkbox value.
-    No worries, mate.
-</p>
-
-<p>
-    If we press the SAVE button,
-    the form will be submitted to the Subscription_save action.
-    Since the save method needs some additional validation,
-    we can add a validation file.
-</p>
-
-<hr />
-<h5>Subscription-Subscription_save-validation.xml</h5>
-<pre><code>&lt;!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
-    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-&lt;validators>
-  &lt;field name="<strong>host</strong>">
-    &lt;field-validator type="<strong>requiredstring</strong>">
-        &lt;message key="error.host.required"/>
-    &lt;/field-validator>
-  &lt;/field>
-&lt;/validators></code></pre>
-<hr />
-
-<p>
-    The validators follow the same type of inheritance path as the classes.
-    SubscriptionSave extends Subscription,
-    so when Subscription_save is validated,
-    the Host property specified by "Subscription-validation.xml" will also be required.
-</p>
-
-<p>
-    If validation succeeds, the <code>save</code> method of Subscription will fire.
-</p>
-
-<hr />
-<h5>Subscription</h5>
-
-<pre><code>public String <strong>save</strong>() throws Exception {
-
-  if (Constants.DELETE.equals(getTask())) {
-   <strong>removeSubscription</strong>();
-  }
-
-  if (Constants.CREATE.equals(getTask())) {
-    <strong>copySubscription(</strong>getHost());
-  }
-
-  saveUser();
-  return SUCCESS;
-}</code></pre>
-<hr />
-
-<p>
-    The <strong>save</strong> method uses the Task property to handle
-    the special cases of deleting and creating,
-    and then updates the state of the User object.
-</p>
-
-<p>
-    The <strong>removeSubscription</strong> method calls the DAO facade,
-    and then updates the application state.
-</p>
-
-<hr />
-<h5>removeSubscription</h5>
-<pre><code>public void <strong>removeSubscription</strong>() throws Exception {
-  getUser().removeSubscription(getSubscription());
-  getSession().remove(Constants.SUBSCRIPTION_KEY);
-}</code></pre>
-<hr />
-
-<p>
-    The <strong>copySubscription</strong> method is a bit more interesting.
-    The MailReader DAO layer API includes some immutable fields
-    that can't be set once the object is created.
-    Because key fields are immutable,
-    we can't just create a Subscription, let the framework populate all the fields,
-    and then save it when we are done -- because some fields can't be populated,
-    except at construction.
-</p>
-
-<p>
-    One workaround would be to declare properties on the Action
-    for all the properties we need to pass to the Subscription or User objects.
-    When we are ready to create the object,
-    we could pass the new object values from the Action properties.
-</p>
-
-<p>
-    Another workaround is to declare only the immutable properties on the Action,
-    and then use what we can from the domain object.
-</p>
-
-<p>
-    This implementation of the MailReader utilizes the second alternative.
-    We define User and Subscription objects on our base Action,
-    and add other properties only as needed.
-</p>
-
-<p>
-    To add a new Subscription or User,
-    we create a blank object to capture whatever fields we can.
-    When this "input" object returns, we create a new object,
-    setting the immutable fields to appropriate values,
-    and copy over the rest of the properties.
-</p>
-
-<hr />
-<h5>copySubscription</h5>
-<pre><code>public void <strong>copySubscription</strong>(String host) {
-  Subscription input = getSubscription();
-  Subscription sub = createSubscription(host);
-  if (null != sub) {
-    <strong>BeanUtils.setValues</strong>(sub, input, null);
-    setSubscription(sub);
-    setHost(sub.getHost());
-  }
-}</code></pre>
-<hr />
-
-<p>
-    Of course, this is not a preferred solution,
-    but merely a way to work around an issue in the MailReader DAO API
-    that would not be easy for us change.
-</p>
-
-<h4>Subscription Submit</h4>
-
-<p>
-    When we pressed the SAVE button, there was one step that we overlooked.
-    The Mailreader application uses a "double submit" guard to keep people
-    from clicking the SAVE button multiple times and submitting the form again.
-</p>
-
-<p>
-    To add the double-submit guard, we can change the actions default processing
-    stack to <code>user-submit</code>.
-    But, we don't want to just copy and paste the other action settings from
-    the main Subscription action.
-    What we can do is put the subscription actions in their own package,
-    so that they can share result types.
-</p>
-
-<hr />
-<h5>mailreader-support.xml</h5>
-<pre><code><!-- ... -->
-&lt;/package>
-
-&lt;package name="subscription" namespace="/" extends="mailreader-support">
-
-    &lt;global-results>
-        &lt;result name="input">/Subscription.jsp&lt;/result>
-        &lt;result type="redirect-action">Registration_input&lt;/result>
-    &lt;/global-results>
-
-    &lt;action name="Subscription_save" method="save" class="mailreader2.Subscription">
-        &lt;interceptor-ref name="user-submit" />
-    &lt;/action>
-
-    &lt;action name="Subscription_*" method="{1}" class="mailreader2.Subscription" />
-
-&lt;/package>
-
-&lt;package name="wildcard" namespace="/" extends="mailreader-support">
-
-    &lt;action name="*" class="mailreader2.MailreaderSupport">
-        &lt;result>/{1}.jsp&lt;/result>
-    &lt;/action>
-
-&lt;/package>
-}</code></pre>
-<hr />
-
-<p>
-    Aftering a successful save,
-    the Subscription Action will return "success",
-    and the framework will redirect us back to Registration input.
-</p>
-
-<h3>Summary</h3>
-<p>
-    At this point, we've booted the application, logged on,
-    reviewed a Registration record, and edited a Subscription.
-    Of course, there's more, but from here on, it is mostly more of the same.
-    The full source code for MailReader is
-    <a href="http://svn.apache.org/viewvc/struts/struts2/trunk/apps/mailreader/">
-        available online</a>
-    and in the distribution.
-</p>
-
-<p>
-    Enjoy!
-</p>
-</blockquote>
-</body>
-</html>
diff --git a/pom.xml b/pom.xml
index 407999d..c8f00d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.apache.struts</groupId>
     <artifactId>struts-examples</artifactId>
-    <version>1.0.0</version>
+    <version>1.1.0</version>
     <packaging>pom</packaging>
     <name>Struts 2 Examples</name>
     <description>
@@ -89,7 +89,6 @@
         <module>interceptors</module>
         <module>json</module>
         <module>json-customize</module>
-        <module>mailreader</module>
         <module>message-resource</module>
         <module>message-store</module>
         <module>portlet</module>