[SCM] davmail packaging branch, master, updated. 02c2b101f323ee4dc652f941a0d9441a59cfa0da

Alexandre Rossi alexandre.rossi at gmail.com
Mon Oct 1 09:07:48 UTC 2012


The following commit has been merged in the master branch:
commit ea77c15366c4c6b2f5fcf9a4773e225412fa7263
Author: Alexandre Rossi <alexandre.rossi at gmail.com>
Date:   Mon Oct 1 10:43:17 2012 +0200

    Imported Upstream version 4.0.0-2016

diff --git a/build.xml b/build.xml
index b3b941b..0cbba32 100644
--- a/build.xml
+++ b/build.xml
@@ -1,6 +1,6 @@
 <project name="DavMail" default="dist" basedir=".">
     <property file="user.properties"/>
-    <property name="version" value="3.9.9"/>
+    <property name="version" value="4.0.0"/>
 
     <path id="classpath">
         <pathelement location="classes"/>
@@ -236,8 +236,34 @@
         <delete dir="dist"/>
         <mkdir dir="dist"/>
         <echo file="dist/version.txt" message="${release}"/>
+        <pathconvert property="manifest-classpath" pathsep=" ">
+            <mapper>
+                <chainedmapper>
+                    <!-- remove absolute path -->
+                    <flattenmapper/>
+                    <globmapper from="*" to="lib/*"/>
+                </chainedmapper>
+            </mapper>
+            <path>
+                <fileset dir="lib">
+                    <include name="*.jar"/>
+                    <exclude name="ant-deb*.jar"/>
+                    <exclude name="jarbundler-*.jar"/>
+                    <exclude name="jsmoothgen-ant-*.jar"/>
+                    <exclude name="junit-*.jar"/>
+                    <exclude name="libgrowl-*.jar"/>
+                    <exclude name="nsisant-*.jar"/>
+                    <exclude name="redline-*.jar"/>
+                    <exclude name="servlet-api-*.jar"/>
+                    <exclude name="swt-*.jar"/>
+                    <exclude name="winrun4j-*.jar"/>
+                </fileset>
+            </path>
+        </pathconvert>
         <jar basedir="target/classes" destfile="dist/davmail.jar">
             <manifest>
+                <attribute name="Main-Class" value="davmail.DavGateway"/>
+                <attribute name="Class-Path" value="${manifest-classpath}"/>
                 <section name="davmail/">
                     <attribute name="Implementation-Title" value="DavMail Gateway"/>
                     <attribute name="Implementation-Version" value="${release-name}"/>
@@ -259,14 +285,14 @@
         </copy>
         <copy file="src/java/tray48.png" tofile="dist/davmail.png"/>
         <copy file="davmail.sh" todir="dist"/>
-        <taskdef name="jsmoothgen"
-                 classname="net.charabia.jsmoothgen.ant.JSmoothGen"
-                 classpathref="classpath"/>
-        <jsmoothgen project="davmail.jsmooth" skeletonroot="src/jsmooth/skeletons"/>
-        <jsmoothgen project="davmailconsole.jsmooth" skeletonroot="src/jsmooth/skeletons"/>
-        <!-- use WinRun4J to generate DavMail service -->
+
+        <!-- use WinRun4J wrappers -->
+        <copy file="src/winrun4j/davmail.exe" todir="dist"/>
+        <copy file="src/winrun4j/davmailconsole.exe" todir="dist"/>
         <copy file="src/winrun4j/davmailservice.exe" todir="dist"/>
-        <jsmoothgen project="davmail64.jsmooth" skeletonroot="src/jsmooth/skeletons"/>
+        <copy file="src/winrun4j/davmail64.exe" todir="dist"/>
+        <copy file="src/winrun4j/davmailservice64.exe" todir="dist"/>
+
         <zip file="dist/davmail-${release-name}.zip">
             <fileset dir="dist">
                 <include name="lib/*.jar"/>
diff --git a/davmail-setup.nsi b/davmail-setup.nsi
index c7d2dd4..24dbe78 100644
--- a/davmail-setup.nsi
+++ b/davmail-setup.nsi
@@ -85,6 +85,7 @@ Section "MainSection" SEC01
   File "dist\davmailconsole.exe"
   File "dist\davmailservice.exe"
   File "dist\davmail64.exe"
+  File "dist\davmailservice64.exe"
   SetOutPath "$INSTDIR\lib"
   File "dist\lib\activation-1.1.1.jar"
   File "dist\lib\commons-codec-1.3.jar"
@@ -183,6 +184,7 @@ no_quest:
   Delete "$INSTDIR\lib\woodstox-core-asl-4.1.2.jar"
   Delete "$INSTDIR\lib\xercesImpl-2.8.1.jar"
 
+  Delete "$INSTDIR\davmailservice64.exe"
   Delete "$INSTDIR\davmail64.exe"
   Delete "$INSTDIR\davmailservice.exe"
   Delete "$INSTDIR\davmailconsole.exe"
diff --git a/pom.xml b/pom.xml
index 898b4a5..edbe389 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
     <groupId>davmail</groupId>
     <artifactId>davmail</artifactId>
     <packaging>jar</packaging>
-    <version>3.9.9</version>
+    <version>4.0.0</version>
     <name>DavMail POP/IMAP/SMTP/Caldav/Carddav/LDAP Exchange Gateway</name>
     <organization>
         <name>Mickaël Guessant</name>
diff --git a/releasenotes.txt b/releasenotes.txt
index f95554c..e462000 100644
--- a/releasenotes.txt
+++ b/releasenotes.txt
@@ -1,3 +1,56 @@
+** DavMail 4.0.0 released **
+Includes full Exchange 2007 and 2010 support with EWS implementation, 
+fixed OSX Mountain Lion support, switched Windows wrappers to WinRun4J 
+and additional enhancements and bugfixes.
+
+IMAP:
+- IMAP: workaround for broken message headers on Exchange 2010
+- IMAP: log content if less than 2K
+- IMAP: improve Exchange 2010 header search, use direct header names to implement substring search on some headers
+- IMAP: additional fix for Exchange 2010 header search, use PR_TRANSPORT_MESSAGE_HEADERS
+- IMAP: Exchange 2010 does not support header search, workaround to avoid duplicate items in Drafts folder with Thunderbird
+- IMAP: fix 3553942, unexpected imap NIL response
+- IMAP: detect and ignore missing message to avoid NullPointerException
+- IMAP: improve bodystructure error handling
+
+Documentation:
+- Doc: fix image swap
+- Doc: update roadmap
+- Doc: add Developed with Intellij Idea link
+
+Caldav:
+- Caldav: encode semicolon in urlcompname
+- Caldav: fix attendees in modified occurences
+- Caldav: additional timezone names for Exchange 2010
+- Caldav: additional timezones available in Exchange 2007
+- Caldav: Partial fix for missing items on Exchange 2010
+- Caldav: fix OSX Mountain Lion (iCal 6) support
+
+Enhancement:
+- Merge patch 3488553: Make davmail.jar executable
+- Merge patch from 3562031, advanced noProxyFor handling
+- Display released version in about frame when different from current version
+- Fix 3562031, implement davmail.noProxyFor setting to exclude hosts from proxy settings
+- Merge preauthentication page patch
+- Prepare pre authentication page merge in ExchangeSession
+- Implement javascript redirect in executeFollowRedirects
+- Prepare javascript redirect merge (multiple authentication pages)
+- Try to improve shutdown hook
+
+Windows:
+- Update download url in 64 bit wrappers to http://java.com/en/download/manual.jsp
+- Add davmailservice64.exe WinRun4J service wrapper
+- Replace 64 bits jsmoothgen with WinRun4J wrapper
+- 64 bits Winrun4J wrapper
+- Fix Winrun4J service wrapper implementation, launch a non daemon thread
+- Win: switch to Winrun4J wrappers
+
+OSX:
+- OSX: Add a note on Gatekeeper for OSX Mountain Lion users
+
+EWS:
+- EWS: fix davmail.acceptEncodingGzip setting handling
+
 ** DavMail 3.9.9 released **
 Bugfix release with major IMAP changes to improve sync performance,
 many Caldav enhancements and bugfixes and some documentation updates.
diff --git a/src/java/davmail/DavGateway.java b/src/java/davmail/DavGateway.java
index 008b356..22fe369 100644
--- a/src/java/davmail/DavGateway.java
+++ b/src/java/davmail/DavGateway.java
@@ -173,6 +173,7 @@ public final class DavGateway {
         // clear session cache
         ExchangeSessionFactory.reset();
         DavGatewayTray.info(new BundleMessage("LOG_GATEWAY_STOP"));
+        DavGatewayTray.dispose();
     }
 
     /**
diff --git a/src/java/davmail/Settings.java b/src/java/davmail/Settings.java
index 7794709..7c6c70e 100644
--- a/src/java/davmail/Settings.java
+++ b/src/java/davmail/Settings.java
@@ -150,6 +150,7 @@ public final class Settings {
         SETTINGS.put("davmail.proxyPort", "");
         SETTINGS.put("davmail.proxyUser", "");
         SETTINGS.put("davmail.proxyPassword", "");
+        SETTINGS.put("davmail.noProxyFor", "");
         SETTINGS.put("davmail.server", Boolean.FALSE.toString());
         SETTINGS.put("davmail.server.certificate.hash", "");
         SETTINGS.put("davmail.caldavAlarmSound", "");
@@ -191,7 +192,9 @@ public final class Settings {
         String logFilePath = Settings.getProperty("davmail.logFilePath");
         // set default log file path
         if ((logFilePath == null || logFilePath.length() == 0)) {
-            if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
+            if (Settings.getBooleanProperty("davmail.server")) {
+                logFilePath = "davmail.log";
+            } else if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
                 // store davmail.log in OSX Logs directory
                 logFilePath = System.getProperty("user.home") + "/Library/Logs/DavMail/davmail.log";
             } else {
@@ -231,7 +234,7 @@ public final class Settings {
     /**
      * Update Log4J config from settings.
      */
-    private static void updateLoggingConfig() {
+    public static void updateLoggingConfig() {
         String logFilePath = getLogFilePath();
 
         Logger rootLogger = Logger.getRootLogger();
diff --git a/src/java/davmail/caldav/CaldavConnection.java b/src/java/davmail/caldav/CaldavConnection.java
index ec2f1d9..516d9c9 100644
--- a/src/java/davmail/caldav/CaldavConnection.java
+++ b/src/java/davmail/caldav/CaldavConnection.java
@@ -96,7 +96,7 @@ public class CaldavConnection extends AbstractConnection {
         while ((line = readClient()) != null && line.length() > 0) {
             int index = line.indexOf(':');
             if (index <= 0) {
-                wireLogger.warn("Invalid header: "+line);
+                wireLogger.warn("Invalid header: " + line);
                 throw new DavMailException("EXCEPTION_INVALID_HEADER");
             }
             headers.put(line.substring(0, index).toLowerCase(), line.substring(index + 1).trim());
@@ -969,7 +969,7 @@ public class CaldavConnection extends AbstractConnection {
         if (request.hasProperty("principal-URL") && request.isIcal5()) {
             response.appendHrefProperty("D:principal-URL", encodePath(request, "/principals/" + prefix + '/' + actualPrincipal));
         }
-        
+
 
         if (request.hasProperty("calendar-home-set")) {
             if ("users".equals(prefix)) {
@@ -1440,7 +1440,9 @@ public class CaldavConnection extends AbstractConnection {
         }
 
         protected boolean isIcal5() {
-            return isUserAgent("CoreDAV/") || isUserAgent("iOS/5");
+            return isUserAgent("CoreDAV/") || isUserAgent("iOS/5")
+                    // iCal 6
+                    || isUserAgent("Mac OS X/10.8");
         }
 
         protected boolean isUserAgent(String key) {
@@ -1629,12 +1631,12 @@ public class CaldavConnection extends AbstractConnection {
                  */
                 String result = calendarPath.toString();
                 // replace unsupported spaces
-                if (result.indexOf(' ') >=0 ) {
-                   result = result.replaceAll("___", " ");
+                if (result.indexOf(' ') >= 0) {
+                    result = result.replaceAll("___", " ");
                 }
                 // replace /addressbook suffix on public folders
                 if (result.startsWith("/public")) {
-                   result = result.replaceAll("/addressbook", "");
+                    result = result.replaceAll("/addressbook", "");
                 }
 
                 return result;
diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java
index d3ba208..68c53df 100644
--- a/src/java/davmail/exchange/ExchangeSession.java
+++ b/src/java/davmail/exchange/ExchangeSession.java
@@ -130,6 +130,10 @@ public abstract class ExchangeSession {
     protected final HttpClient httpClient;
 
     protected String userName;
+    /**
+     * A OTP pre-auth page may require a different username.
+     */
+    private String preAuthUsername;
 
     protected String serverVersion;
 
@@ -146,7 +150,19 @@ public abstract class ExchangeSession {
     /**
      * Logon form password field, default is password.
      */
-    private String passwordInput = "password";
+    private String passwordInput = null;
+    /**
+     * Tells if, during the login navigation, an OTP pre-auth page has been found.
+     */
+    private boolean otpPreAuthFound = false;
+    /**
+     * Lets the user try again a couple of times to enter the OTP pre-auth key before giving up.
+     */
+    private int otpPreAuthRetries = 0;
+    /**
+     * Maximum number of times the user can try to input again the OTP pre-auth key before giving up.
+     */
+    private static final int MAX_OTP_RETRIES = 3;
 
     /**
      * Create an exchange session for the given URL.
@@ -165,6 +181,22 @@ public abstract class ExchangeSession {
             DavGatewayHttpClientFacade.createMultiThreadedHttpConnectionManager(httpClient);
             boolean isBasicAuthentication = isBasicAuthentication(httpClient, url);
 
+            // The user may have configured an OTP pre-auth username. It is processed
+            // so early because OTP pre-auth may disappear in the Exchange LAN and this
+            // helps the user to not change is account settings in mail client at each network change.
+            if (preAuthUsername == null) {
+                // Searches for the delimiter in configured username for the pre-auth user. 
+                // The double-quote is not allowed inside email addresses anyway.
+                int doubleQuoteIndex = this.userName.indexOf('"');   
+                if (doubleQuoteIndex > 0) {
+                    preAuthUsername = this.userName.substring(0, doubleQuoteIndex);
+                    this.userName = this.userName.substring(doubleQuoteIndex + 1);
+                } else {
+                    // No doublequote: the pre-auth user is the full username, or it is not used at all.
+                    preAuthUsername = this.userName; 
+                }
+            }
+
             DavGatewayHttpClientFacade.setCredentials(httpClient, userName, password);
 
             // get webmail root url
@@ -358,6 +390,9 @@ public abstract class ExchangeSession {
         // create an instance of HtmlCleaner
         HtmlCleaner cleaner = new HtmlCleaner();
 
+        // A OTP token authentication form in a previous page could have username fields with different names
+        userNameInputs.clear();
+
         try {
             TagNode node = cleaner.clean(initmethod.getResponseBodyAsStream());
             List forms = node.getElementListByName("form", true);
@@ -402,7 +437,7 @@ public abstract class ExchangeSession {
                         HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod);
                         logonMethod = buildLogonMethod(httpClient, newInitMethod);
                     } else if (TOKEN_FIELDS.contains(name)) {
-                        // one time password, ask user
+                        // one time password, ask it to the user
                         ((PostMethod) logonMethod).addParameter(name, DavGatewayOTPPrompt.getOneTimePassword());
                     } else if ("otc".equals(name)) {
                         // captcha image, get image and ask user
@@ -477,39 +512,8 @@ public abstract class ExchangeSession {
     }
 
     protected HttpMethod postLogonMethod(HttpClient httpClient, HttpMethod logonMethod, String userName, String password) throws IOException {
-        String userNameInput;
-        if (userNameInputs.size() == 2) {
-            // multiple username fields, split userid|username on |
-            int pipeIndex = userName.indexOf('|');
-            if (pipeIndex < 0) {
-                LOGGER.warn("Multiple user fields detected, please use userid|username as user name in client");
-            } else {
-                String userid = userName.substring(0, pipeIndex);
-                ((PostMethod) logonMethod).removeParameter("userid");
-                ((PostMethod) logonMethod).addParameter("userid", userid);
-                userName = userName.substring(pipeIndex + 1);
-                // adjust credentials
-                this.userName = userName;
-                DavGatewayHttpClientFacade.setCredentials(httpClient, userName, password);
-            }
 
-            userNameInput = "username";
-        } else if (userNameInputs.size() == 1) {
-            // simple username field
-            userNameInput = userNameInputs.get(0);
-        } else {
-            // should not happen
-            userNameInput = "username";
-        }
-        // make sure username and password fields are empty
-        ((PostMethod) logonMethod).removeParameter(userNameInput);
-        ((PostMethod) logonMethod).removeParameter(passwordInput);
-        ((PostMethod) logonMethod).removeParameter("trusted");
-        ((PostMethod) logonMethod).removeParameter("flags");
-        ((PostMethod) logonMethod).addParameter(userNameInput, userName);
-        ((PostMethod) logonMethod).addParameter(passwordInput, password);
-        ((PostMethod) logonMethod).addParameter("trusted", "4");
-        ((PostMethod) logonMethod).addParameter("flags", "4");
+		setAuthFormFields(logonMethod, httpClient, password);
 
         // add exchange 2010 PBack cookie in compatibility mode
         httpClient.getState().addCookie(new Cookie(httpClient.getHostConfiguration().getHost(), "PBack", "0", "/", null, false));
@@ -524,6 +528,14 @@ public abstract class ExchangeSession {
             // try to get new method from script based redirection
             logonMethod = buildLogonMethod(httpClient, logonMethod);
 
+            if (otpPreAuthFound && otpPreAuthRetries < MAX_OTP_RETRIES) {
+                // A OTP pre-auth page has been found, it is needed to restart the login process.
+                // This applies to both the case the user entered a good OTP code (the usual login process
+                // takes place) and the case the user entered a wrong OTP code (another code will be asked to him).
+                // The user has up to MAX_OTP_RETRIES chances to input a valid OTP key.
+                return postLogonMethod(httpClient, logonMethod, userName, password);
+            }
+
             if (logonMethod != null) {
                 // if logonMethod is not null, try to follow redirection
                 logonMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod);
@@ -546,6 +558,54 @@ public abstract class ExchangeSession {
         return logonMethod;
     }
 
+    protected void setAuthFormFields(HttpMethod logonMethod, HttpClient httpClient, String password) throws IllegalArgumentException {
+        String userNameInput;
+        if (userNameInputs.size() == 2) {
+            // multiple username fields, split userid|username on |
+            int pipeIndex = userName.indexOf('|');
+            if (pipeIndex < 0) {
+                LOGGER.warn("Multiple user fields detected, please use userid|username as user name in client");
+            } else {
+                String userid = userName.substring(0, pipeIndex);
+                ((PostMethod) logonMethod).removeParameter("userid");
+                ((PostMethod) logonMethod).addParameter("userid", userid);
+                userName = userName.substring(pipeIndex + 1);
+                // adjust credentials
+                DavGatewayHttpClientFacade.setCredentials(httpClient, userName, password);
+            }
+
+            userNameInput = "username";
+        } else if (userNameInputs.size() == 1) {
+            // simple username field
+            userNameInput = userNameInputs.get(0);
+        } else {
+            // should not happen
+            userNameInput = "username";
+        }
+        // make sure username and password fields are empty
+        ((PostMethod) logonMethod).removeParameter(userNameInput);
+        if (passwordInput != null) {
+            ((PostMethod) logonMethod).removeParameter(passwordInput);
+        }
+        ((PostMethod) logonMethod).removeParameter("trusted");
+        ((PostMethod) logonMethod).removeParameter("flags");
+
+        if (passwordInput == null) {
+            // This is a OTP pre-auth page. A different username may be required.
+            otpPreAuthFound = true;
+            otpPreAuthRetries++;
+            ((PostMethod) logonMethod).addParameter(userNameInput, preAuthUsername);
+        } else {
+            otpPreAuthFound = false;
+            otpPreAuthRetries = 0;
+            // This is a regular Exchange login page
+            ((PostMethod) logonMethod).addParameter(userNameInput, userName);
+            ((PostMethod) logonMethod).addParameter(passwordInput, password);
+            ((PostMethod) logonMethod).addParameter("trusted", "4");
+            ((PostMethod) logonMethod).addParameter("flags", "4");
+        }
+    }
+
     protected HttpMethod formLogin(HttpClient httpClient, HttpMethod initmethod, String userName, String password) throws IOException {
         LOGGER.debug("Form based authentication detected");
 
diff --git a/src/java/davmail/exchange/VCalendar.java b/src/java/davmail/exchange/VCalendar.java
index 3dfe1d5..c61f06b 100644
--- a/src/java/davmail/exchange/VCalendar.java
+++ b/src/java/davmail/exchange/VCalendar.java
@@ -212,6 +212,7 @@ public class VCalendar extends VObject {
                     if (isCdoAllDay(vObject)) {
                         setClientAllday(vObject.getProperty("DTSTART"));
                         setClientAllday(vObject.getProperty("DTEND"));
+                        setClientAllday(vObject.getProperty("RECURRENCE-ID"));
                     }
                     String cdoBusyStatus = vObject.getPropertyValue("X-MICROSOFT-CDO-BUSYSTATUS");
                     if (cdoBusyStatus != null) {
@@ -720,6 +721,14 @@ public class VCalendar extends VObject {
     }
 
     /**
+     * Get first VEvent
+     * @return first VEvent
+     */
+    public VObject getFirstVevent() {
+        return firstVevent;
+    }
+
+    /**
      * Get recurring VCalendar occurence exceptions.
      *
      * @return event occurences
diff --git a/src/java/davmail/exchange/ews/EWSMethod.java b/src/java/davmail/exchange/ews/EWSMethod.java
index 914853a..c35bd7c 100644
--- a/src/java/davmail/exchange/ews/EWSMethod.java
+++ b/src/java/davmail/exchange/ews/EWSMethod.java
@@ -109,7 +109,7 @@ public abstract class EWSMethod extends PostMethod {
         this.methodName = methodName;
         this.responseCollectionName = responseCollectionName;
         if (Settings.getBooleanProperty("davmail.acceptEncodingGzip", true) &&
-                !Level.DEBUG.toString().equals(Settings.getBooleanProperty("log4j.logger.httpclient.wire"))) {
+                !Level.DEBUG.toString().equals(Settings.getProperty("log4j.logger.httpclient.wire"))) {
             setRequestHeader("Accept-Encoding", "gzip");
         }
         setRequestEntity(new RequestEntity() {
@@ -477,6 +477,11 @@ public abstract class EWSMethod extends PostMethod {
          * Original occurence start date
          */
         public String originalStart;
+
+        /**
+         * Occurence itemid
+         */
+        public ItemId itemId;
     }
 
     /**
@@ -704,6 +709,8 @@ public abstract class EWSMethod extends PostMethod {
     public int getStatusCode() {
         if ("ErrorAccessDenied".equals(errorDetail)) {
             return HttpStatus.SC_FORBIDDEN;
+        } else if ("ErrorItemNotFound".equals(errorDetail)) {
+            return HttpStatus.SC_NOT_FOUND;
         } else {
             return super.getStatusCode();
         }
@@ -865,17 +872,20 @@ public abstract class EWSMethod extends PostMethod {
     }
 
     protected void handleOccurrence(XMLStreamReader reader, Item item) throws XMLStreamException {
+        Occurrence occurrence = new Occurrence();
         while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Occurrence"))) {
             reader.next();
             if (XMLStreamUtil.isStartTag(reader)) {
                 String tagLocalName = reader.getLocalName();
+                if ("ItemId".equals(tagLocalName)) {
+                    occurrence.itemId = new ItemId("ItemId", getAttributeValue(reader, "Id"), getAttributeValue(reader, "ChangeKey"));
+                }
                 if ("OriginalStart".equals(tagLocalName)) {
-                    Occurrence occurrence = new Occurrence();
                     occurrence.originalStart = XMLStreamUtil.getElementText(reader);
-                    item.addOccurrence(occurrence);
                 }
             }
         }
+        item.addOccurrence(occurrence);
     }
     
     public static String responseTypeToPartstat(String responseType) {
diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java
index 7e9293a..41b25f3 100644
--- a/src/java/davmail/exchange/ews/EwsExchangeSession.java
+++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java
@@ -377,11 +377,13 @@ public class EwsExchangeSession extends ExchangeSession {
                 EWSMethod.Item item = getItemMethod.getResponseItem();
 
                 String messageHeaders = item.get(Field.get("messageheaders").getResponseName());
-                if (messageHeaders != null) {
+                if (messageHeaders != null
+                        // workaround for broken message headers on Exchange 2010
+                        && messageHeaders.toLowerCase().contains("message-id:")) {
                     // workaround for messages in Sent folder
                     if (messageHeaders.indexOf("From:") < 0) {
                         String from = item.get(Field.get("from").getResponseName());
-                        messageHeaders = "From: "+from+"\n"+messageHeaders;
+                        messageHeaders = "From: " + from + "\n" + messageHeaders;
                     }
 
                     result = new ByteArrayInputStream(messageHeaders.getBytes("UTF-8"));
@@ -540,6 +542,9 @@ public class EwsExchangeSession extends ExchangeSession {
         } catch (EWSException e) {
             LOGGER.warn("GetItem with MimeContent failed: " + e.getMessage());
         }
+        if (getItemMethod.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+            throw new HttpNotFoundException("Item " + itemId + " not found");
+        }
         if (mimeContent == null) {
             LOGGER.warn("MimeContent not available, trying to rebuild from properties");
             try {
@@ -795,8 +800,10 @@ public class EwsExchangeSession extends ExchangeSession {
 
     protected static class HeaderCondition extends AttributeCondition {
 
-        protected HeaderCondition(String attributeName, Operator operator, String value) {
-            super(attributeName, operator, value);
+        protected HeaderCondition(String attributeName, String value) {
+            super(attributeName, Operator.Contains, value);
+            containmentMode = ContainmentMode.Substring;
+            containmentComparison = ContainmentComparison.IgnoreCase;
         }
 
         @Override
@@ -857,7 +864,20 @@ public class EwsExchangeSession extends ExchangeSession {
 
     @Override
     public Condition headerIsEqualTo(String headerName, String value) {
-        return new HeaderCondition(headerName, Operator.IsEqualTo, value);
+        if (serverVersion.startsWith("Exchange2010")) {
+            if ("message-id".equals(headerName)
+                    || "from".equals(headerName)
+                    || "to".equals(headerName)
+                    || "cc".equals(headerName)
+                    || "bcc".equals(headerName)) {
+                return new AttributeCondition(headerName, Operator.Contains, value, ContainmentMode.Substring, ContainmentComparison.IgnoreCase);
+            } else {
+                // Exchange 2010 does not support header search, use PR_TRANSPORT_MESSAGE_HEADERS instead
+                return new AttributeCondition("messageheaders", Operator.Contains, headerName + ": " + value, ContainmentMode.Substring, ContainmentComparison.IgnoreCase);
+            }
+        } else {
+            return new HeaderCondition(headerName, value);
+        }
     }
 
     @Override
@@ -1304,7 +1324,7 @@ public class EwsExchangeSession extends ExchangeSession {
             String instancetype = response.get(Field.get("instancetype").getResponseName());
             boolean isrecurring = "true".equals(response.get(Field.get("isrecurring").getResponseName()));
             String calendaritemtype = response.get(Field.get("calendaritemtype").getResponseName());
-            isException = "3".equals(instancetype) || (isrecurring && "Single".equals(calendaritemtype));
+            isException = "3".equals(instancetype);
         }
 
         /**
@@ -1625,30 +1645,19 @@ public class EwsExchangeSession extends ExchangeSession {
                         content = getICS(new SharedByteArrayInputStream(content));
                     }
                     VCalendar localVCalendar = new VCalendar(content, email, getVTimezone());
-                    // remove additional reminder
-                    if (!"true".equals(getItemMethod.getResponseItem().get(Field.get("reminderset").getResponseName()))) {
-                        localVCalendar.removeVAlarm();
-                    }
+
                     String calendaruid = getItemMethod.getResponseItem().get(Field.get("calendaruid").getResponseName());
-                    if (calendaruid != null) {
-                        localVCalendar.setFirstVeventPropertyValue("UID", calendaruid);
-                    }
-                    List<EWSMethod.Attendee> attendees = getItemMethod.getResponseItem().getAttendees();
-                    if (attendees != null) {
-                        for (EWSMethod.Attendee attendee : attendees) {
-                            VProperty attendeeProperty = new VProperty("ATTENDEE", "mailto:" + attendee.email);
-                            attendeeProperty.addParam("CN", attendee.name);
-                            String myResponseType = getItemMethod.getResponseItem().get(Field.get("myresponsetype").getResponseName());
-                            if ("Exchange2007_SP1".equals(serverVersion) && email.equalsIgnoreCase(attendee.email) && myResponseType != null) {
-                                attendeeProperty.addParam("PARTSTAT", EWSMethod.responseTypeToPartstat(myResponseType));
-                            } else {
-                                attendeeProperty.addParam("PARTSTAT", attendee.partstat);
-                            }
-                            //attendeeProperty.addParam("RSVP", "TRUE");
-                            attendeeProperty.addParam("ROLE", attendee.role);
-                            localVCalendar.addFirstVeventProperty(attendeeProperty);
+
+                    if ("Exchange2007_SP1".equals(serverVersion)) {
+                        // remove additional reminder
+                        if (!"true".equals(getItemMethod.getResponseItem().get(Field.get("reminderset").getResponseName()))) {
+                            localVCalendar.removeVAlarm();
+                        }
+                        if (calendaruid != null) {
+                            localVCalendar.setFirstVeventPropertyValue("UID", calendaruid);
                         }
                     }
+                    fixAttendees(getItemMethod, localVCalendar.getFirstVevent());
                     // fix UID and RECURRENCE-ID, broken at least on Exchange 2007
                     List<EWSMethod.Occurrence> occurences = getItemMethod.getResponseItem().getOccurrences();
                     if (occurences != null) {
@@ -1656,14 +1665,25 @@ public class EwsExchangeSession extends ExchangeSession {
                         for (EWSMethod.Occurrence occurrence : occurences) {
                             if (modifiedOccurrencesIterator.hasNext()) {
                                 VObject modifiedOccurrence = modifiedOccurrencesIterator.next();
-                                // fix uid, should be the same as main VEVENT
-                                if (calendaruid != null) {
-                                    modifiedOccurrence.setPropertyValue("UID", calendaruid);
-                                }
-                                VProperty recurrenceId = modifiedOccurrence.getProperty("RECURRENCE-ID");
-                                if (recurrenceId != null) {
-                                    recurrenceId.removeParam("TZID");
-                                    recurrenceId.getValues().set(0, convertDateFromExchange(occurrence.originalStart));
+                                // fix modified occurrences attendees
+                                GetItemMethod getOccurrenceMethod = new GetItemMethod(BaseShape.ID_ONLY, occurrence.itemId, false);
+                                getOccurrenceMethod.addAdditionalProperty(Field.get("requiredattendees"));
+                                getOccurrenceMethod.addAdditionalProperty(Field.get("optionalattendees"));
+                                getOccurrenceMethod.addAdditionalProperty(Field.get("modifiedoccurrences"));
+                                executeMethod(getOccurrenceMethod);
+                                fixAttendees(getOccurrenceMethod, modifiedOccurrence);
+
+                                if ("Exchange2007_SP1".equals(serverVersion)) {
+                                    // fix uid, should be the same as main VEVENT
+                                    if (calendaruid != null) {
+                                        modifiedOccurrence.setPropertyValue("UID", calendaruid);
+                                    }
+
+                                    VProperty recurrenceId = modifiedOccurrence.getProperty("RECURRENCE-ID");
+                                    if (recurrenceId != null) {
+                                        recurrenceId.removeParam("TZID");
+                                        recurrenceId.getValues().set(0, convertDateFromExchange(occurrence.originalStart));
+                                    }
                                 }
                             }
                         }
@@ -1687,6 +1707,25 @@ public class EwsExchangeSession extends ExchangeSession {
             }
             return content;
         }
+
+        protected void fixAttendees(GetItemMethod getItemMethod, VObject vEvent) throws EWSException {
+            List<EWSMethod.Attendee> attendees = getItemMethod.getResponseItem().getAttendees();
+            if (attendees != null) {
+                for (EWSMethod.Attendee attendee : attendees) {
+                    VProperty attendeeProperty = new VProperty("ATTENDEE", "mailto:" + attendee.email);
+                    attendeeProperty.addParam("CN", attendee.name);
+                    String myResponseType = getItemMethod.getResponseItem().get(Field.get("myresponsetype").getResponseName());
+                    if ("Exchange2007_SP1".equals(serverVersion) && email.equalsIgnoreCase(attendee.email) && myResponseType != null) {
+                        attendeeProperty.addParam("PARTSTAT", EWSMethod.responseTypeToPartstat(myResponseType));
+                    } else {
+                        attendeeProperty.addParam("PARTSTAT", attendee.partstat);
+                    }
+                    //attendeeProperty.addParam("RSVP", "TRUE");
+                    attendeeProperty.addParam("ROLE", attendee.role);
+                    vEvent.addProperty(attendeeProperty);
+                }
+            }
+        }
     }
 
     @Override
diff --git a/src/java/davmail/exchange/ews/Field.java b/src/java/davmail/exchange/ews/Field.java
index af9daa4..f7b0c0e 100644
--- a/src/java/davmail/exchange/ews/Field.java
+++ b/src/java/davmail/exchange/ews/Field.java
@@ -73,16 +73,16 @@ public final class Field {
 
         FIELD_MAP.put("iconIndex", new ExtendedFieldURI(0x1080, ExtendedFieldURI.PropertyType.Integer));// PR_ICON_INDEX
         FIELD_MAP.put("datereceived", new ExtendedFieldURI(0x0e06, ExtendedFieldURI.PropertyType.SystemTime));// PR_MESSAGE_DELIVERY_TIME
-        FIELD_MAP.put("bcc", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "bcc"));
 
-        FIELD_MAP.put("to", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "to"));
-        FIELD_MAP.put("cc", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "cc"));
-        FIELD_MAP.put("from", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "from"));
+        FIELD_MAP.put("to", new UnindexedFieldURI("message:ToRecipients"));
+        FIELD_MAP.put("cc", new UnindexedFieldURI("message:CcRecipients"));
+        FIELD_MAP.put("from", new UnindexedFieldURI("message:From"));
+        FIELD_MAP.put("bcc", new UnindexedFieldURI("message:BccRecipients"));
 
         FIELD_MAP.put("messageheaders", new ExtendedFieldURI(0x007D, ExtendedFieldURI.PropertyType.String)); // PR_TRANSPORT_MESSAGE_HEADERS
 
         FIELD_MAP.put("contentclass", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "content-class"));
-        FIELD_MAP.put("message-id", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "message-id"));
+        FIELD_MAP.put("message-id", new UnindexedFieldURI("message:InternetMessageId"));
 
         FIELD_MAP.put("body", new UnindexedFieldURI("item:Body"));
 
@@ -232,6 +232,7 @@ public final class Field {
 
         // attachments
         FIELD_MAP.put("attachments", new UnindexedFieldURI("item:Attachments"));
+
     }
 
     /**
diff --git a/src/java/davmail/exchange/ews/ItemId.java b/src/java/davmail/exchange/ews/ItemId.java
index 86c3d9a..c7ee14b 100644
--- a/src/java/davmail/exchange/ews/ItemId.java
+++ b/src/java/davmail/exchange/ews/ItemId.java
@@ -70,6 +70,17 @@ public class ItemId {
     }
 
     /**
+     * Build Item id object from item id and change key.
+     *
+     * @param itemId item id
+     */
+    public ItemId(String name, String itemId, String changeKey) {
+        this.name = name;
+        this.id = itemId;
+        this.changeKey = changeKey;
+    }
+
+    /**
      * Write item id as XML.
      *
      * @param writer request writer
diff --git a/src/java/davmail/http/DavGatewayHttpClientFacade.java b/src/java/davmail/http/DavGatewayHttpClientFacade.java
index 0475b34..403ace5 100644
--- a/src/java/davmail/http/DavGatewayHttpClientFacade.java
+++ b/src/java/davmail/http/DavGatewayHttpClientFacade.java
@@ -51,6 +51,8 @@ import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Create HttpClient instance according to DavGateway Settings
@@ -141,6 +143,20 @@ public final class DavGatewayHttpClientFacade {
         }
     }
 
+    protected static boolean isNoProxyFor(java.net.URI uri) {
+        final String noProxyFor = Settings.getProperty("davmail.noProxyFor");
+        if (noProxyFor != null) {
+            final String urihost = uri.getHost().toLowerCase();
+            final String[] domains = noProxyFor.toLowerCase().split(",\\s*");
+            for (String domain : domains) {
+                if (urihost.endsWith(domain)) {
+                    return true; //break;
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * Update http client configuration (proxy)
      *
@@ -151,7 +167,12 @@ public final class DavGatewayHttpClientFacade {
     public static void configureClient(HttpClient httpClient, String url) throws DavMailException {
         setClientHost(httpClient, url);
 
-        if (!needNTLM) {
+        /*if (Settings.getBooleanProperty("davmail.enableKerberos", false)) {
+            AuthPolicy.registerAuthScheme("Negotiate", NegotiateScheme.class);
+            ArrayList<String> authPrefs = new ArrayList<String>();
+            authPrefs.add("Negotiate");
+            httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+        } else */if (!needNTLM) {
             ArrayList<String> authPrefs = new ArrayList<String>();
             authPrefs.add(AuthPolicy.DIGEST);
             authPrefs.add(AuthPolicy.BASIC);
@@ -166,11 +187,14 @@ public final class DavGatewayHttpClientFacade {
         String proxyUser = null;
         String proxyPassword = null;
 
-        if (useSystemProxies) {
-            // get proxy for url from system settings
-            System.setProperty("java.net.useSystemProxies", "true");
-            try {
-                List<Proxy> proxyList = getProxyForURI(new java.net.URI(url));
+        try {
+            java.net.URI uri = new java.net.URI(url);
+            if (isNoProxyFor(uri)) {
+                LOGGER.debug("no proxy for "+uri.getHost());
+            } else if (useSystemProxies) {
+                // get proxy for url from system settings
+                System.setProperty("java.net.useSystemProxies", "true");
+                List<Proxy> proxyList = getProxyForURI(uri);
                 if (!proxyList.isEmpty() && proxyList.get(0).address() != null) {
                     InetSocketAddress inetSocketAddress = (InetSocketAddress) proxyList.get(0).address();
                     proxyHost = inetSocketAddress.getHostName();
@@ -180,14 +204,14 @@ public final class DavGatewayHttpClientFacade {
                     proxyUser = Settings.getProperty("davmail.proxyUser");
                     proxyPassword = Settings.getProperty("davmail.proxyPassword");
                 }
-            } catch (URISyntaxException e) {
-                throw new DavMailException("LOG_INVALID_URL", url);
+            } else if (enableProxy) {
+                    proxyHost = Settings.getProperty("davmail.proxyHost");
+                    proxyPort = Settings.getIntProperty("davmail.proxyPort");
+                    proxyUser = Settings.getProperty("davmail.proxyUser");
+                    proxyPassword = Settings.getProperty("davmail.proxyPassword");
             }
-        } else if (enableProxy) {
-            proxyHost = Settings.getProperty("davmail.proxyHost");
-            proxyPort = Settings.getIntProperty("davmail.proxyPort");
-            proxyUser = Settings.getProperty("davmail.proxyUser");
-            proxyPassword = Settings.getProperty("davmail.proxyPassword");
+        } catch (URISyntaxException e) {
+            throw new DavMailException("LOG_INVALID_URL", url);
         }
 
         // configure proxy
@@ -291,6 +315,49 @@ public final class DavGatewayHttpClientFacade {
     }
 
     /**
+     * Checks if there is a Javascript redirect inside the page,
+     * and returns it.
+     * <p/>
+     * A Javascript redirect is usually found on OTP pre-auth page,
+     * when the pre-auth form is in a distinct page from the regular Exchange login one.
+     *
+     * @param method http method
+     * @return the redirect URL if found, or null if no Javascript redirect has been found
+     */
+    private static String getJavascriptRedirectUrl(HttpMethod method) throws IOException {
+        String responseBody = method.getResponseBodyAsString();
+        String jsRedirectionUrl = null;
+        if (responseBody.indexOf("javascript:go_url()") > 0) {
+            // Create a pattern to match a javascript redirect url
+            Pattern p = Pattern.compile("go_url\\(\\)[^{]+\\{[^l]+location.replace\\(\"(/[^\"]+)\"\\)");
+            Matcher m = p.matcher(responseBody);
+            if (m.find()) {
+                // Javascript redirect found!
+                jsRedirectionUrl = m.group(1);
+            }
+        }
+        return jsRedirectionUrl;
+    }
+
+
+    private static String getLocationValue(HttpMethod method) throws URIException {
+        String locationValue = null;
+        Header location = method.getResponseHeader("Location");
+        if (location != null && isRedirect(method.getStatusCode())) {
+            locationValue = location.getValue();
+            // Novell iChain workaround
+            if (locationValue.indexOf('"') >= 0) {
+                locationValue = URIUtil.encodePath(locationValue);
+            }
+            // workaround for invalid relative location
+            if (locationValue.startsWith("./")) {
+                locationValue = locationValue.substring(1);
+            }
+        }
+        return locationValue;
+    }
+
+    /**
      * Execute method with httpClient, follow 30x redirects.
      *
      * @param httpClient Http client instance
@@ -303,31 +370,26 @@ public final class DavGatewayHttpClientFacade {
         try {
             DavGatewayTray.debug(new BundleMessage("LOG_EXECUTE_FOLLOW_REDIRECTS", currentMethod.getURI()));
             httpClient.executeMethod(currentMethod);
-            int status = checkNTLM(httpClient, currentMethod);
+            checkNTLM(httpClient, currentMethod);
+
+            String locationValue = getLocationValue(currentMethod);
+            // check javascript redirect (multiple authentication pages)
+            if (locationValue == null) {
+                locationValue = getJavascriptRedirectUrl(currentMethod);
+            }
 
-            Header location = currentMethod.getResponseHeader("Location");
             int redirectCount = 0;
             while (redirectCount++ < 10
-                    && location != null
-                    && isRedirect(status)) {
-                // Novell iChain workaround
-                String locationValue = location.getValue();
-                if (locationValue.indexOf('"') >= 0) {
-                    locationValue = URIUtil.encodePath(locationValue);
-                }
-                // workaround for invalid relative location
-                if (locationValue.startsWith("./")) {
-                    locationValue = locationValue.substring(1);
-                }
+                    && locationValue != null) {
                 currentMethod.releaseConnection();
                 currentMethod = new GetMethod(locationValue);
                 currentMethod.setFollowRedirects(false);
                 DavGatewayTray.debug(new BundleMessage("LOG_EXECUTE_FOLLOW_REDIRECTS_COUNT", currentMethod.getURI(), redirectCount));
                 httpClient.executeMethod(currentMethod);
                 checkNTLM(httpClient, currentMethod);
-                location = currentMethod.getResponseHeader("Location");
+                locationValue = getLocationValue(currentMethod);
             }
-            if (location != null && isRedirect(currentMethod.getStatusCode())) {
+            if (locationValue != null) {
                 currentMethod.releaseConnection();
                 throw new HttpException("Maximum redirections reached");
             }
@@ -405,8 +467,8 @@ public final class DavGatewayHttpClientFacade {
      *
      * @param httpClient Http client instance
      * @param path       Path to be deleted
-     * @throws IOException on error
      * @return http status
+     * @throws IOException on error
      */
     public static int executeDeleteMethod(HttpClient httpClient, String path) throws IOException {
         DeleteMethod deleteMethod = new DeleteMethod(path);
diff --git a/src/java/davmail/imap/ImapConnection.java b/src/java/davmail/imap/ImapConnection.java
index d54ba81..ecabef9 100644
--- a/src/java/davmail/imap/ImapConnection.java
+++ b/src/java/davmail/imap/ImapConnection.java
@@ -48,8 +48,7 @@ import java.text.SimpleDateFormat;
 import java.util.*;
 
 /**
- * Dav Gateway smtp connection implementation.
- * Still alpha code : need to find a way to handle message ids
+ * Dav Gateway IMAP connection implementation.
  */
 public class ImapConnection extends AbstractConnection {
     private static final Logger LOGGER = Logger.getLogger(ImapConnection.class);
@@ -300,6 +299,8 @@ public class ImapConnection extends AbstractConnection {
                                                         ExchangeSession.Message message = uidRangeIterator.next();
                                                         try {
                                                             handleFetch(message, uidRangeIterator.currentIndex, parameters);
+                                                        } catch (HttpNotFoundException e) {
+                                                            LOGGER.warn("Ignore missing message "+uidRangeIterator.currentIndex);
                                                         } catch (SocketException e) {
                                                             // client closed connection
                                                             throw e;
@@ -384,6 +385,8 @@ public class ImapConnection extends AbstractConnection {
                                             ExchangeSession.Message message = rangeIterator.next();
                                             try {
                                                 handleFetch(message, rangeIterator.currentIndex, parameters);
+                                            } catch (HttpNotFoundException e) {
+                                                LOGGER.warn("Ignore missing message "+rangeIterator.currentIndex);
                                             } catch (SocketException e) {
                                                 // client closed connection, rethrow exception
                                                 throw e;
@@ -850,6 +853,10 @@ public class ImapConnection extends AbstractConnection {
                     }
                     buffer.append(" {").append(baos.size()).append('}');
                     sendClient(buffer.toString());
+                    // log content if less than 2K
+                    if (LOGGER.isDebugEnabled() && baos.size() < 2048) {
+                        LOGGER.debug(new String(baos.toByteArray(), "UTF-8"));
+                    }
                     os.write(baos.toByteArray());
                     os.flush();
                     buffer.setLength(0);
@@ -988,7 +995,7 @@ public class ImapConnection extends AbstractConnection {
             try {
                 String unfoldedValue = MimeUtility.unfold(value[0]);
                 InternetAddress[] addresses = InternetAddress.parseHeader(unfoldedValue, false);
-                if (addresses != null && addresses.length > 1) {
+                if (addresses != null && addresses.length > 0) {
                     buffer.append('(');
                     for (InternetAddress address : addresses) {
                         buffer.append('(');
@@ -1068,12 +1075,22 @@ public class ImapConnection extends AbstractConnection {
 
         for (int i = 0; i < multiPart.getCount(); i++) {
             MimeBodyPart bodyPart = (MimeBodyPart) multiPart.getBodyPart(i);
-            Object mimeBody = bodyPart.getContent();
-            if (mimeBody instanceof MimeMultipart) {
-                appendBodyStructure(buffer, (MimeMultipart) mimeBody);
-            } else {
-                // no multipart, single body
-                appendBodyStructure(buffer, bodyPart);
+            try {
+                Object mimeBody = bodyPart.getContent();
+                if (mimeBody instanceof MimeMultipart) {
+                    appendBodyStructure(buffer, (MimeMultipart) mimeBody);
+                } else {
+                    // no multipart, single body
+                    appendBodyStructure(buffer, bodyPart);
+                }
+            } catch (UnsupportedEncodingException e) {
+                LOGGER.warn(e);
+                // failover: send default bodystructure
+                buffer.append("(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"US-ASCII\") NIL NIL NIL NIL NIL)");
+            } catch (MessagingException me) {
+                DavGatewayTray.warn(me);
+                // failover: send default bodystructure
+                buffer.append("(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"US-ASCII\") NIL NIL NIL NIL NIL)");
             }
         }
         int slashIndex = multiPart.getContentType().indexOf('/');
diff --git a/src/java/davmail/service/DavService.java b/src/java/davmail/service/DavService.java
index 6cd64e9..a205cb8 100644
--- a/src/java/davmail/service/DavService.java
+++ b/src/java/davmail/service/DavService.java
@@ -30,6 +30,8 @@ import org.boris.winrun4j.ServiceException;
  */
 public class DavService extends AbstractService {
 
+    protected boolean stopped;
+
     /**
      * Perform a service request.
      *
@@ -44,6 +46,7 @@ public class DavService extends AbstractService {
             case SERVICE_CONTROL_SHUTDOWN:
                 DavGatewayTray.debug(new BundleMessage("LOG_STOPPING_DAVMAIL"));
                 DavGateway.stop();
+                stopped = true;
         }
         return 0;
     }
@@ -61,11 +64,29 @@ public class DavService extends AbstractService {
         }
 
         Settings.load();
-        DavGatewayTray.init();
+        if (!Settings.getBooleanProperty("davmail.server")) {
+            Settings.setProperty("davmail.server", "true");
+            Settings.updateLoggingConfig();
+        }
 
         DavGateway.start();
         DavGatewayTray.debug(new BundleMessage("LOG_DAVMAIL_STARTED"));
 
+        // launch a non daemon thread
+        Thread shutdownListenerThread = new Thread("ShutDownListener") {
+            public void run() {
+                try {
+                    while (!stopped) {
+                        Thread.sleep(1000);
+                    }
+                } catch (InterruptedException e) {
+                    DavGatewayTray.debug(new BundleMessage("LOG_GATEWAY_INTERRUPTED"));
+                    DavGateway.stop();
+                    DavGatewayTray.debug(new BundleMessage("LOG_GATEWAY_STOP"));
+                }
+            }
+        };
+        shutdownListenerThread.start();
         return 0;
     }
 }
diff --git a/src/java/davmail/ui/AboutFrame.java b/src/java/davmail/ui/AboutFrame.java
index ce01d4f..95d11fe 100644
--- a/src/java/davmail/ui/AboutFrame.java
+++ b/src/java/davmail/ui/AboutFrame.java
@@ -125,7 +125,8 @@ public class AboutFrame extends JFrame {
         if (currentVersion != null) {
             buffer.append(BundleMessage.format("UI_CURRENT_VERSION", currentVersion));
         }
-        if (currentVersion != null && releasedVersion != null && currentVersion.compareTo(releasedVersion) < 0) {
+        if ((currentVersion != null && releasedVersion != null && currentVersion.compareTo(releasedVersion) != 0)
+                || (currentVersion == null && releasedVersion != null)) {
             buffer.append(BundleMessage.format("UI_LATEST_VERSION", releasedVersion));
         }
         buffer.append(BundleMessage.format("UI_HELP_INSTRUCTIONS"));
diff --git a/src/java/davmail/ui/SettingsFrame.java b/src/java/davmail/ui/SettingsFrame.java
index 3ee4e63..b200bdd 100644
--- a/src/java/davmail/ui/SettingsFrame.java
+++ b/src/java/davmail/ui/SettingsFrame.java
@@ -67,6 +67,7 @@ public class SettingsFrame extends JFrame {
     JTextField httpProxyPortField;
     JTextField httpProxyUserField;
     JTextField httpProxyPasswordField;
+    JTextField noProxyForField;
 
     JCheckBox allowRemoteField;
     JTextField bindAddressField;
@@ -248,7 +249,7 @@ public class SettingsFrame extends JFrame {
     }
 
     protected JPanel getProxyPanel() {
-        JPanel proxyPanel = new JPanel(new GridLayout(6, 2));
+        JPanel proxyPanel = new JPanel(new GridLayout(7, 2));
         proxyPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_PROXY")));
 
         boolean useSystemProxies = Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE);
@@ -261,12 +262,14 @@ public class SettingsFrame extends JFrame {
         httpProxyPortField = new JTextField(Settings.getProperty("davmail.proxyPort"), 4);
         httpProxyUserField = new JTextField(Settings.getProperty("davmail.proxyUser"), 10);
         httpProxyPasswordField = new JPasswordField(Settings.getProperty("davmail.proxyPassword"), 10);
+        noProxyForField = new JTextField(Settings.getProperty("davmail.noProxyFor"), 15);
 
         enableProxyField.setEnabled(!useSystemProxies);
         httpProxyField.setEnabled(enableProxy);
         httpProxyPortField.setEnabled(enableProxy);
         httpProxyUserField.setEnabled(enableProxy || useSystemProxies);
         httpProxyPasswordField.setEnabled(enableProxy || useSystemProxies);
+        noProxyForField.setEnabled(enableProxy || useSystemProxies);
 
         useSystemProxiesField.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent evt) {
@@ -277,6 +280,7 @@ public class SettingsFrame extends JFrame {
                 httpProxyPortField.setEnabled(!newUseSystemProxies && newEnableProxy);
                 httpProxyUserField.setEnabled(newUseSystemProxies || newEnableProxy);
                 httpProxyPasswordField.setEnabled(newUseSystemProxies || newEnableProxy);
+                noProxyForField.setEnabled(newUseSystemProxies || newEnableProxy);
             }
         });
         enableProxyField.addActionListener(new ActionListener() {
@@ -286,6 +290,7 @@ public class SettingsFrame extends JFrame {
                 httpProxyPortField.setEnabled(newEnableProxy);
                 httpProxyUserField.setEnabled(newEnableProxy);
                 httpProxyPasswordField.setEnabled(newEnableProxy);
+                noProxyForField.setEnabled(newEnableProxy);
             }
         });
 
@@ -295,6 +300,7 @@ public class SettingsFrame extends JFrame {
         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_PORT"), httpProxyPortField);
         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_USER"), httpProxyUserField);
         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_PASSWORD"), httpProxyPasswordField);
+        addSettingComponent(proxyPanel, BundleMessage.format("UI_NO_PROXY"), noProxyForField);
         updateMaximumSize(proxyPanel);
         return proxyPanel;
     }
@@ -569,10 +575,12 @@ public class SettingsFrame extends JFrame {
         httpProxyPortField.setEnabled(!useSystemProxies && enableProxy);
         httpProxyUserField.setEnabled(useSystemProxies || enableProxy);
         httpProxyPasswordField.setEnabled(useSystemProxies || enableProxy);
+        noProxyForField.setEnabled(useSystemProxies || enableProxy);
         httpProxyField.setText(Settings.getProperty("davmail.proxyHost"));
         httpProxyPortField.setText(Settings.getProperty("davmail.proxyPort"));
         httpProxyUserField.setText(Settings.getProperty("davmail.proxyUser"));
         httpProxyPasswordField.setText(Settings.getProperty("davmail.proxyPassword"));
+        noProxyForField.setText(Settings.getProperty("davmail.noProxyFor"));
 
         bindAddressField.setText(Settings.getProperty("davmail.bindAddress"));
         allowRemoteField.setSelected(Settings.getBooleanProperty(("davmail.allowRemote")));
@@ -732,6 +740,7 @@ public class SettingsFrame extends JFrame {
                 Settings.setProperty("davmail.proxyPort", httpProxyPortField.getText());
                 Settings.setProperty("davmail.proxyUser", httpProxyUserField.getText());
                 Settings.setProperty("davmail.proxyPassword", httpProxyPasswordField.getText());
+                Settings.setProperty("davmail.noProxyFor", noProxyForField.getText());
 
                 Settings.setProperty("davmail.bindAddress", bindAddressField.getText());
                 Settings.setProperty("davmail.clientSoTimeout", String.valueOf(clientSoTimeoutField.getText()));
diff --git a/src/java/davmail/ui/tray/AwtGatewayTray.java b/src/java/davmail/ui/tray/AwtGatewayTray.java
index a0303da..ba1890e 100644
--- a/src/java/davmail/ui/tray/AwtGatewayTray.java
+++ b/src/java/davmail/ui/tray/AwtGatewayTray.java
@@ -37,6 +37,7 @@ import java.awt.event.ActionListener;
 /**
  * Tray icon handler based on java 1.6
  */
+ at SuppressWarnings("Since15")
 public class AwtGatewayTray implements DavGatewayTrayInterface {
     protected static final String TRAY_ACTIVE_PNG = "tray2.png";
     protected static final String TRAY_PNG = "tray.png";
@@ -163,6 +164,7 @@ public class AwtGatewayTray implements DavGatewayTrayInterface {
                 settingsFrame.reload();
                 settingsFrame.setVisible(true);
                 settingsFrame.toFront();
+                settingsFrame.repaint();
                 settingsFrame.requestFocus();
             }
         });
@@ -179,6 +181,17 @@ public class AwtGatewayTray implements DavGatewayTrayInterface {
         });
     }
 
+    public void dispose() {
+        SystemTray.getSystemTray().remove(trayIcon);
+
+        // dispose frames
+        settingsFrame.dispose();
+        aboutFrame.dispose();
+        if (logBrokerMonitor != null) {
+            logBrokerMonitor.dispose();
+        }
+    }
+
     protected void createAndShowGUI() {
         System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
 
@@ -241,14 +254,6 @@ public class AwtGatewayTray implements DavGatewayTrayInterface {
             public void actionPerformed(ActionEvent e) {
                 try {
                     DavGateway.stop();
-                    SystemTray.getSystemTray().remove(trayIcon);
-
-                    // dispose frames
-                    settingsFrame.dispose();
-                    aboutFrame.dispose();
-                    if (logBrokerMonitor != null) {
-                        logBrokerMonitor.dispose();
-                    }
                 } catch (Exception exc) {
                     DavGatewayTray.error(exc);
                 }
@@ -278,6 +283,7 @@ public class AwtGatewayTray implements DavGatewayTrayInterface {
         if (Settings.isFirstStart()) {
             settingsFrame.setVisible(true);
             settingsFrame.toFront();
+            settingsFrame.repaint();
             settingsFrame.requestFocus();
         }
     }
diff --git a/src/java/davmail/ui/tray/DavGatewayTray.java b/src/java/davmail/ui/tray/DavGatewayTray.java
index 1e1dd6a..cff867b 100644
--- a/src/java/davmail/ui/tray/DavGatewayTray.java
+++ b/src/java/davmail/ui/tray/DavGatewayTray.java
@@ -290,4 +290,7 @@ public final class DavGatewayTray {
         return result;
     }
 
+    public static void dispose() {
+        davGatewayTray.dispose();
+    }
 }
diff --git a/src/java/davmail/ui/tray/DavGatewayTrayInterface.java b/src/java/davmail/ui/tray/DavGatewayTrayInterface.java
index 7220cea..b7f1254 100644
--- a/src/java/davmail/ui/tray/DavGatewayTrayInterface.java
+++ b/src/java/davmail/ui/tray/DavGatewayTrayInterface.java
@@ -68,4 +68,8 @@ public interface DavGatewayTrayInterface {
      */
     void init();
 
+    /**
+     * destroy frames
+     */
+    void dispose();
 }
diff --git a/src/java/davmail/ui/tray/FrameGatewayTray.java b/src/java/davmail/ui/tray/FrameGatewayTray.java
index 622abcb..883d7bb 100644
--- a/src/java/davmail/ui/tray/FrameGatewayTray.java
+++ b/src/java/davmail/ui/tray/FrameGatewayTray.java
@@ -196,6 +196,15 @@ public class FrameGatewayTray implements DavGatewayTrayInterface {
         });
     }
 
+    public void dispose() {
+        // dispose frames
+        settingsFrame.dispose();
+        aboutFrame.dispose();
+        if (logBrokerMonitor != null) {
+            logBrokerMonitor.dispose();
+        }
+    }
+
     protected void buildMenu() {
         // create a popup menu
         JMenu menu = new JMenu(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
@@ -239,12 +248,6 @@ public class FrameGatewayTray implements DavGatewayTrayInterface {
             public void actionPerformed(ActionEvent e) {
                 try {
                     DavGateway.stop();
-                    // dispose frames
-                    settingsFrame.dispose();
-                    aboutFrame.dispose();
-                    if (logBrokerMonitor != null) {
-                        logBrokerMonitor.dispose();
-                    }
                 } catch (Exception exc) {
                     DavGatewayTray.error(exc);
                 }
diff --git a/src/java/davmail/ui/tray/OSXAwtGatewayTray.java b/src/java/davmail/ui/tray/OSXAwtGatewayTray.java
index 9eff9c0..3c0d3e1 100644
--- a/src/java/davmail/ui/tray/OSXAwtGatewayTray.java
+++ b/src/java/davmail/ui/tray/OSXAwtGatewayTray.java
@@ -35,6 +35,7 @@ import java.awt.image.RenderedImage;
 /**
  * Extended Awt tray with OSX extensions.
  */
+ at SuppressWarnings("Since15")
 public class OSXAwtGatewayTray extends AwtGatewayTray {
     protected static final String OSX_TRAY_ACTIVE_PNG = "osxtray2.png";
     protected static final String OSX_TRAY_PNG = "osxtray.png";
diff --git a/src/java/davmail/ui/tray/SwtGatewayTray.java b/src/java/davmail/ui/tray/SwtGatewayTray.java
index 09b9d9e..01c6866 100644
--- a/src/java/davmail/ui/tray/SwtGatewayTray.java
+++ b/src/java/davmail/ui/tray/SwtGatewayTray.java
@@ -312,7 +312,6 @@ public class SwtGatewayTray implements DavGatewayTrayInterface {
                         exitItem.addListener(SWT.Selection, new Listener() {
                             public void handleEvent(Event event) {
                                 DavGateway.stop();
-                                shell.dispose();
                             }
                         });
 
@@ -339,34 +338,7 @@ public class SwtGatewayTray implements DavGatewayTrayInterface {
                             }
                         }
 
-                        if (trayItem != null) {
-                            trayItem.dispose();
-                            trayItem = null;
-                        }
-
-                        if (image != null) {
-                            image.dispose();
-                        }
-                        if (image2 != null) {
-                            image2.dispose();
-                        }
-                        try {
-                            if (!display.isDisposed()) {
-                                display.dispose();
-                            }
-                        } catch (Exception e) {
-                            // already disposed
-                        }
-                        // dispose AWT frames
-                        if (settingsFrame != null) {
-                            settingsFrame.dispose();
-                        }
-                        if (aboutFrame != null) {
-                            aboutFrame.dispose();
-                        }
-                        if (logBrokerMonitor != null) {
-                            logBrokerMonitor.dispose();
-                        }
+                        dispose();
                     }
                 } catch (Exception exc) {
                     DavGatewayTray.error(exc);
@@ -390,4 +362,36 @@ public class SwtGatewayTray implements DavGatewayTrayInterface {
         }
     }
 
+    public void dispose() {
+        shell.dispose();
+        if (trayItem != null) {
+            trayItem.dispose();
+            trayItem = null;
+        }
+
+        if (image != null) {
+            image.dispose();
+        }
+        if (image2 != null) {
+            image2.dispose();
+        }
+        try {
+            if (!display.isDisposed()) {
+                display.dispose();
+            }
+        } catch (Exception e) {
+            // already disposed
+        }
+        // dispose AWT frames
+        if (settingsFrame != null) {
+            settingsFrame.dispose();
+        }
+        if (aboutFrame != null) {
+            aboutFrame.dispose();
+        }
+        if (logBrokerMonitor != null) {
+            logBrokerMonitor.dispose();
+        }
+    }
+
 }
diff --git a/src/java/davmail/util/StringUtil.java b/src/java/davmail/util/StringUtil.java
index 9e6a4e4..c11674e 100644
--- a/src/java/davmail/util/StringUtil.java
+++ b/src/java/davmail/util/StringUtil.java
@@ -143,6 +143,7 @@ public final class StringUtil {
     private static final Pattern URLENCODED_AMP_PATTERN = Pattern.compile("%26");
     private static final Pattern URLENCODED_PLUS_PATTERN = Pattern.compile("%2B");
     private static final Pattern URLENCODED_COLON_PATTERN = Pattern.compile("%3A");
+    private static final Pattern URLENCODED_SEMICOLON_PATTERN = Pattern.compile("%3B");
     private static final Pattern URLENCODED_LT_PATTERN = Pattern.compile("%3C");
     private static final Pattern URLENCODED_GT_PATTERN = Pattern.compile("%3E");
     private static final Pattern URLENCODED_QUOTE_PATTERN = Pattern.compile("%22");
@@ -162,6 +163,7 @@ public final class StringUtil {
 
     private static final Pattern PLUS_PATTERN = Pattern.compile("\\+");
     private static final Pattern COLON_PATTERN = Pattern.compile(":");
+    private static final Pattern SEMICOLON_PATTERN = Pattern.compile(";");
     private static final Pattern SLASH_PATTERN = Pattern.compile("/");
     private static final Pattern UNDERSCORE_PATTERN = Pattern.compile("_");
     private static final Pattern DASH_PATTERN = Pattern.compile("-");
@@ -315,6 +317,9 @@ public final class StringUtil {
         if (result.indexOf(':') >= 0) {
             result = COLON_PATTERN.matcher(result).replaceAll("%3A");
         }
+        if (result.indexOf(';') >= 0) {
+            result = SEMICOLON_PATTERN.matcher(result).replaceAll("%3B");
+        }
         if (result.indexOf('<') >= 0) {
             result = LT_PATTERN.matcher(result).replaceAll("%3C");
         }
@@ -363,6 +368,9 @@ public final class StringUtil {
             if (result.indexOf("%3A") >= 0) {
                 result = URLENCODED_COLON_PATTERN.matcher(result).replaceAll(":");
             }
+            if (result.indexOf("%3B") >= 0) {
+                result = URLENCODED_SEMICOLON_PATTERN.matcher(result).replaceAll(";");
+            }
             if (result.indexOf("%3C") >= 0) {
                 result = URLENCODED_LT_PATTERN.matcher(result).replaceAll("<");
             }
diff --git a/src/java/davmailmessages.properties b/src/java/davmailmessages.properties
index 9dacdfe..0131aa1 100644
--- a/src/java/davmailmessages.properties
+++ b/src/java/davmailmessages.properties
@@ -219,6 +219,7 @@ UI_PROXY_PASSWORD=Proxy password:
 UI_PROXY_PORT=Proxy port:
 UI_PROXY_SERVER=Proxy server:
 UI_PROXY_USER=Proxy user:
+UI_NO_PROXY=No proxy for:
 UI_SENT_KEEP_DELAY=Sent keep delay (POP):
 UI_SENT_KEEP_DELAY_HELP=Number of days to keep messages in sent folder
 UI_SERIAL=Serial
diff --git a/src/java/davmailmessages_fr.properties b/src/java/davmailmessages_fr.properties
index e9c10b3..e84e4c5 100644
--- a/src/java/davmailmessages_fr.properties
+++ b/src/java/davmailmessages_fr.properties
@@ -194,6 +194,7 @@ UI_PROXY_PASSWORD=Mot de passe proxy :
 UI_PROXY_PORT=Port du serveur proxy :
 UI_PROXY_SERVER=Serveur proxy :
 UI_PROXY_USER=Identifiant proxy :
+UI_NO_PROXY=Pas de proxy pour :
 UI_SENT_KEEP_DELAY=Délai de rétention envoyés (POP) :
 UI_SENT_KEEP_DELAY_HELP=Nombre de jours de conservation des messages dans le dossier des messages envoyés
 UI_SERIAL=Numéro de série
diff --git a/src/java/timezoneids.properties b/src/java/timezoneids.properties
index 8a54d6b..0a309ef 100644
--- a/src/java/timezoneids.properties
+++ b/src/java/timezoneids.properties
@@ -87,16 +87,22 @@ Hawaiian\ Standard\ Time=15
 Samoa\ Standard\ Time=16
 Dateline\ Standard\ Time=39
 # Additional
-UTC=31
 Middle\ East\ Standard\ Time=7
-Bangladesh\ Standard\ Time=71
-Ulaanbaatar\ Standard\ Time=63
-Kamchatka\ Standard\ Time=40
-UTC-02=30
-Paraguay\ Standard\ Time=65
 Mexico\ Standard\ Time=37
 Mexico\ Standard\ Time\ 2=77
-UTC-11=16
-# Unknown
-#UTC+12=N/A
-#Namibia\ Standard\ Time=N/A
+# 2007
+#AUS\ Eastern\ Standard\ Time=57
+Kamchatka\ Standard\ Time=93
+Paraguay\ Standard\ Time=94
+UTC=95
+Ulaanbaatar\ Standard\ Time=96
+Bangladesh\ Standard\ Time=97
+Syria\ Standard\ Time=98
+UTC-02=99
+UTC+12=100
+UTC-11=101
+Namibia\ Standard\ Time=102
+Magadan\ Standard\ Time=103
+Kaliningrad\ Standard\ Time=104
+Turkey\ Standard\ Time=105
+Bahia\ Standard\ Time=106
\ No newline at end of file
diff --git a/src/java/timezones.properties b/src/java/timezones.properties
index f264624..d62d53a 100644
--- a/src/java/timezones.properties
+++ b/src/java/timezones.properties
@@ -9,10 +9,12 @@
 (GMT+01.00)\ Prague/Central\ Europe=Europe/Prague
 (GMT+01.00)\ Sarajevo/Warsaw/Zagreb=Europe/Sarajevo
 (GMT+01.00)\ West\ Central\ Africa=Africa/Algiers
+(GMT+01.00)\ Windhoek=Africa/Windhoek
 (GMT+02.00)\ Athens/Istanbul/Minsk=Europe/Athens
 (GMT+02.00)\ Athens/Bucharest/Istanbul=Europe/Athens
 (GMT+02.00)\ Bucharest/Eastern\ Europe=Europe/Bucharest
 (GMT+02.00)\ Minsk/Eastern\ Europe=Europe/Bucharest
+(GMT+02.00)\ Nicosia=Asia/Nicosia
 (GMT+02.00)\ Cairo=Africa/Cairo
 (GMT+02.00)\ Harare/Pretoria=Africa/Harare
 (GMT+02.00)\ Helsinki/Riga/Tallinn=Europe/Helsinki
@@ -27,15 +29,18 @@
 (GMT+03.00)\ Moscow/St.\ Petersburg/Volgograd=Europe/Moscow
 (GMT+03.00)\ East\ Africa/Nairobi=Africa/Nairobi
 (GMT+03.00)\ Kaliningrad=Europe/Kaliningrad
+(GMT+03.00)\ Kaliningrad,\ Minsk=Europe/Kaliningrad
 (GMT+03.00)\ Kuwait/Riyadh=Asia/Kuwait
 (GMT+03.00)\ Tbilisi=Asia/Tbilisi
 (GMT+03.30)\ Tehran=Asia/Tehran
+(GMT+04.00)\ Tbilisi=Asia/Tbilisi
 (GMT+04.00)\ Abu\ Dhabi/Muscat=Asia/Dubai
 (GMT+04.00)\ Caucasus/Baku/Tbilisi/Yerevan=Asia/Tbilisi
 (GMT+04.00)\ Baku=Asia/Baku
 (GMT+04.00)\ Caucasus\ Standard\ Time=Asia/Baku
 (GMT+04.00)\ Port\ Louis=Asia/Baku
-(GMT+04.00)\ Yerevan=Asia/Baku
+(GMT+04.00)\ Yerevan=Asia/Yerevan
+(GMT+04.00)\ Moscow/St.\ Petersburg/Volgograd=Europe/Moscow
 (GMT+04.30)\ Kabul=Asia/Kabul
 (GMT+05.00)\ Ekaterinburg=Asia/Yekaterinburg
 (GMT+05.00)\ Islamabad/Karachi/Sverdlovsk/Tashkent=Asia/Tashkent
@@ -45,6 +50,7 @@
 (GMT+05.30)\ Kolkata/Chennai/Mumbai/New\ Delhi/India\ Standard\ Time=Asia/Kolkata
 (GMT+05.30)\ Sri\ Jayawardenepura/Sri\ Lanka=Asia/Kolkata
 (GMT+05.45)\ Kathmandu/Nepal=Asia/Katmandu
+(GMT+06.00)\ Ekaterinburg=Asia/Yekaterinburg
 (GMT+06.00)\ Almaty/North\ Central\ Asia/Novosibirsk=Asia/Almaty
 (GMT+06.00)\ Astana/Dhaka=Asia/Dhaka
 (GMT+06.00)\ Sri\ Jayawardenepura/Sri\ Lanka=Asia/Kolkata
@@ -54,6 +60,8 @@
 (GMT+06.30)\ Rangoon=Asia/Rangoon
 (GMT+07.00)\ Bangkok/Jakarta/Hanoi=Asia/Bangkok
 (GMT+07.00)\ Krasnoyarsk/North\ Asia=Asia/Krasnoyarsk
+(GMT+07.00)\ Novosibirsk=Asia/Novosibirsk
+(GMT+08.00)\ Krasnoyarsk/North\ Asia=Asia/Krasnoyarsk
 (GMT+08.00)\ Beijing/Chongqing/Hong\ Kong/Urumqi=Asia/Hong_Kong
 (GMT+08.00)\ Irkutsk/Ulaan\ Bataar=Asia/Irkutsk
 (GMT+08.00)\ Kuala\ Lumpur/Singapore=Asia/Kuala_Lumpur
@@ -62,12 +70,14 @@
 (GMT+08.00)\ Beijing/Chongqing/Hong\ Kong\ SAR/Urumqi=Asia/Beijing
 (GMT+08.00)\ Irkutsk=Asia/Irkutsk
 (GMT+08.00)\ Ulaanbaatar=Asia/Ulaanbaatar
+(GMT+09.00)\ Irkutsk=Asia/Irkutsk
 (GMT+09.00)\ Tokyo/Osaka/Sapporo=Asia/Tokyo
 (GMT+09.00)\ Seoul/Korea\ Standard\ Time=Asia/Seoul
 (GMT+09.00)\ Yakutsk=Asia/Yakutsk
 (GMT+09.30)\ Adelaide/Central\ Australia=Australia/Adelaide
 (GMT+09.30)\ Darwin=Australia/Darwin
 (GMT+09.30)\ Adelaide\ (Commonwealth\ Games)=Australia/Adelaide
+(GMT+10.00)\ Yakutsk=Asia/Yakutsk
 (GMT+10.00)\ Canberra,\ Melbourne,\ Sydney,\ Hobart\ (Year\ 2000\ only)=Australia/Melbourne
 (GMT+10.00)\ Canberra,\ Melbourne,\ Sydney\ (Commonwealth\ Games)=Australia/Melbourne
 (GMT+10.00)\ Hobart\ (Commonwealth\ Games)=Australia/Melbourne
@@ -77,6 +87,7 @@
 (GMT+10.00)\ Hobart/Tasmania=Australia/Hobart
 (GMT+10.00)\ Vladivostok=Asia/Vladivostok
 (GMT+10.00)\ Melbourne/Sydney=Australia/Melbourne
+(GMT+11.00)\ Vladivostok=Asia/Vladivostok
 (GMT+11.00)\ Magadan/Solomon\ Is./New\ Caledonia=Asia/Magadan
 (GMT+11.00)\ Solomon\ Is./New\ Caledonia=Pacific/Noumea
 (GMT+12.00)\ Wellington/Auckland=Pacific/Auckland
@@ -87,6 +98,7 @@
 (GMT+12.00)\ Petropavlovsk-Kamchatsky\ -\ Old=
 (GMT+13.00)\ Tonga/Nuku'alofa=Pacific/Tongatapu
 (GMT+13.00)\ Nuku'alofa=Pacific/Tongatapu
+(GMT+13.00)\ Samoa=Pacific/Samoa
 (GMT-01.00)\ Azores=Atlantic/Azores
 (GMT-01.00)\ Cape\ Verde\ Is.=Atlantic/Cape_Verde
 (GMT-02.00)\ Mid-Atlantic=Atlantic/South_Georgia
@@ -98,6 +110,7 @@
 (GMT-03.00)\ Buenos\ Aires=America/Argentina/Buenos_Aires
 (GMT-03.00)\ Cayenne/Fortaleza=America/Cayenne
 (GMT-03.00)\ Montevideo=America/Montevideo
+(GMT-03.00)\ Salvador=America/El_Salvador
 (GMT-03.30)\ Newfoundland=America/St_Johns
 (GMT-04.00)\ Atlantic\ Time\ (Canada)=America/Halifax
 (GMT-04.00)\ Caracas/La\ Paz=America/Caracas
@@ -108,7 +121,6 @@
 (GMT-04.30)\ Caracas=America/Caracas
 (GMT-05.00)\ Bogota/Lima=America/Lima
 (GMT-05.00)\ Bogota/Lima/Quito=America/Lima
-SA\ Pacific\ Standard\ Time=America/Lima
 (GMT-05.00)\ Eastern\ Time\ (US\ &\ Canada)=America/New_York
 (GMT-05.00)\ Indiana\ (East)=America/Indiana/Knox
 (GMT-06.00)\ Central\ America=America/Chicago
@@ -122,7 +134,6 @@ SA\ Pacific\ Standard\ Time=America/Lima
 (GMT-08.00)\ Pacific\ Time\ (US\ &\ Canada)=America/Los_Angeles
 (GMT-08.00)\ Baja\ California=America/Los_Angeles
 (GMT-0800)\ Pacific\ Standard\ Time=America/Los_Angeles
-Pacific\ Standard\ Time=America/Los_Angeles
 (GMT-09.00)\ Alaska=America/Anchorage
 (GMT-10.00)\ Hawaii=Pacific/Honolulu
 (GMT-11.00)\ Midway\ Island/Samoa=Pacific/Pago_Pago
@@ -142,7 +153,107 @@ GMT\ -0500\ (Standard)\ /\ GMT\ -0400\ (Daylight)=America/New_York
 GMT\ -0600\ (Standard)\ /\ GMT\ -0500\ (Daylight)=America/Chicago
 GMT\ -0700\ (Standard)\ /\ GMT\ -0600\ (Daylight)=America/Denver
 GMT\ -0800\ (Standard)\ /\ GMT\ -0700\ (Daylight)=America/Los_Angeles
-GMT\ Standard\ Time=GMT Standard Time
-Greenwich\ Standard\ Time=Greenwich Standard Time
 Mexico\ Standard\ Time=America/Mexico_City
 (GMT)\ Coordinated\ Universal\ Time=Greenwich Standard Time
+# Exchange 2010
+GMT\ Standard\ Time=GMT
+Central\ European\ Standard\ Time=Europe/Sarajevo
+Romance\ Standard\ Time=Europe/Paris
+W.\ Europe\ Standard\ Time=Europe/Berlin
+E.\ Europe\ Standard\ Time=Asia/Nicosia
+Central\ Europe\ Standard\ Time=Europe/Prague
+GTB\ Standard\ Time=Europe/Athens
+E.\ South\ America\ Standard\ Time=America/Sao_Paulo
+Atlantic\ Standard\ Time=America/Halifax
+Eastern\ Standard\ Time=America/New_York
+Central\ Standard\ Time=America/Chicago
+Mountain\ Standard\ Time=America/Denver
+Pacific\ Standard\ Time=America/Los_Angeles
+Alaskan\ Standard\ Time=America/Anchorage
+Hawaiian\ Standard\ Time=Pacific/Honolulu
+Samoa\ Standard\ Time=Pacific/Samoa
+New\ Zealand\ Standard\ Time=Pacific/Auckland
+E.\ Australia\ Standard\ Time=Australia/Brisbane
+Cen.\ Australia\ Standard\ Time=Australia/Adelaide
+Tokyo\ Standard\ Time=Asia/Tokyo
+Singapore\ Standard\ Time=Asia/Kuala_Lumpur
+SE\ Asia\ Standard\ Time=Asia/Bangkok
+India\ Standard\ Time=Asia/Kolkata
+Arabian\ Standard\ Time=Asia/Dubai
+Iran\ Standard\ Time=Asia/Tehran
+Arabic\ Standard\ Time=Asia/Baghdad
+Israel\ Standard\ Time=Asia/Jerusalem
+Newfoundland\ Standard\ Time=America/St_Johns
+Azores\ Standard\ Time=Atlantic/Azores
+Mid-Atlantic\ Standard\ Time=Atlantic/South_Georgia
+Greenwich\ Standard\ Time=Greenwich
+SA\ Eastern\ Standard\ Time=America/Cayenne
+SA\ Western\ Standard\ Time=America/Manaus
+US\ Eastern\ Standard\ Time=America/Indiana/Knox
+SA\ Pacific\ Standard\ Time=America/Lima
+Canada\ Central\ Standard\ Time=America/Regina
+Central\ Standard\ Time\ (Mexico)=America/Mexico_City
+US\ Mountain\ Standard\ Time=America/Phoenix
+Dateline\ Standard\ Time=Pacific/Kwajalein
+Fiji\ Standard\ Time=Pacific/Fiji
+Central\ Pacific\ Standard\ Time=Pacific/Noumea
+Tasmania\ Standard\ Time=Australia/Hobart
+West\ Pacific\ Standard\ Time=Pacific/Guam
+AUS\ Central\ Standard\ Time=Australia/Darwin
+China\ Standard\ Time=Asia/Beijing
+N.\ Central\ Asia\ Standard\ Time=Asia/Novosibirsk
+West\ Asia\ Standard\ Time=Asia/Tashkent
+Afghanistan\ Standard\ Time=Asia/Kabul
+Egypt\ Standard\ Time=Africa/Cairo
+South\ Africa\ Standard\ Time=Africa/Harare
+Russian\ Standard\ Time=Europe/Moscow
+Cape\ Verde\ Standard\ Time=Atlantic/Cape_Verde
+Caucasus\ Standard\ Time=Asia/Baku
+Central\ America\ Standard\ Time=America/Chicago
+E.\ Africa\ Standard\ Time=Africa/Nairobi
+Ekaterinburg\ Standard\ Time=Asia/Yekaterinburg
+FLE\ Standard\ Time=Europe/Helsinki
+Greenland\ Standard\ Time=America/Godthab
+Myanmar\ Standard\ Time=Asia/Rangoon
+Nepal\ Standard\ Time=Asia/Katmandu
+North\ Asia\ East\ Standard\ Time=Asia/Irkutsk
+North\ Asia\ Standard\ Time=Asia/Krasnoyarsk
+Pacific\ SA\ Standard\ Time=America/Santiago
+Sri\ Lanka\ Standard\ Time=Asia/Kolkata
+Tonga\ Standard\ Time=Pacific/Tongatapu
+Vladivostok\ Standard\ Time=Asia/Vladivostok
+W.\ Central\ Africa\ Standard\ Time=Africa/Algiers
+Yakutsk\ Standard\ Time=Asia/Yakutsk
+Central\ Asia\ Standard\ Time=Asia/Dhaka
+Korea\ Standard\ Time=Asia/Seoul
+W.\ Australia\ Standard\ Time=Australia/Perth
+Arab\ Standard\ Time=Asia/Kuwait
+Taipei\ Standard\ Time=Asia/Taipei
+Mountain\ Standard\ Time\ (Mexico)=America/Chihuahua
+AUS\ Eastern\ Standard\ Time=Australia/Melbourne
+Pacific\ Standard\ Time\ (Mexico)=America/Los_Angeles
+Venezuela\ Standard\ Time=America/Caracas
+Jordan\ Standard\ Time=Asia/Amman
+Azerbaijan\ Standard\ Time=Asia/Baku
+Armenian\ Standard\ Time=Asia/Yerevan
+Georgian\ Standard\ Time=Asia/Tbilisi
+Argentina\ Standard\ Time=America/Argentina/Buenos_Aires
+Morocco\ Standard\ Time=Africa/Casablanca
+Pakistan\ Standard\ Time=Asia/Karachi
+Central\ Brazilian\ Standard\ Time=America/Cuiaba
+Mauritius\ Standard\ Time=Asia/Baku
+Montevideo\ Standard\ Time=America/Montevideo
+Kamchatka\ Standard\ Time=
+Paraguay\ Standard\ Time=America/Asuncion
+UTC=Greenwich Standard Time
+Ulaanbaatar\ Standard\ Time=Asia/Ulaanbaatar
+Bangladesh\ Standard\ Time=Asia/Dhaka
+Syria\ Standard\ Time=Asia/Damascus
+UTC-02=Atlantic/South_Georgia
+UTC+12=Pacific/Fiji
+UTC-11=Pacific/Samoa
+Namibia\ Standard\ Time=Africa/Windhoek
+Magadan\ Standard\ Time=Asia/Magadan
+Kaliningrad\ Standard\ Time=Europe/Kaliningrad
+Turkey\ Standard\ Time=Asia/Istanbul
+Bahia\ Standard\ Time=America/El_Salvador
diff --git a/src/site/resources/css/site.css b/src/site/resources/css/site.css
index 7c9be4d..5fb4cc9 100644
--- a/src/site/resources/css/site.css
+++ b/src/site/resources/css/site.css
@@ -58,8 +58,7 @@ a.download {
   color: white;
   font-weight: bold;
   padding: 8px;
-  -moz-border-radius: 8px;
-  -webkit-border-radius: 10px;
+  border-radius: 8px;
   margin: 5px;
 }
 a.donate {
@@ -68,8 +67,7 @@ a.donate {
   color: white;
   font-weight: bold;
   padding: 8px;
-  -moz-border-radius: 8px;
-  -webkit-border-radius: 10px;
+  border-radius: 8px;
   margin: 5px;
 }
 .about p {
diff --git a/src/site/xdoc/advanced.xml b/src/site/xdoc/advanced.xml
index 0e0fb8a..93249f6 100644
--- a/src/site/xdoc/advanced.xml
+++ b/src/site/xdoc/advanced.xml
@@ -57,6 +57,11 @@
                         <th>Sample value</th>
                     </tr>
                     <tr>
+                        <td>No proxy for</td>
+                        <td>comma separated list of hosts accessible without a proxy</td>
+                        <td>davmail.sourceforge.net</td>
+                    </tr>
+                    <tr>
                         <td>Allow remote connections</td>
                         <td>Allow remote connections to the gateway (server mode)</td>
                         <td>false</td>
diff --git a/src/site/xdoc/download.xml b/src/site/xdoc/download.xml
index a9b6202..1cb8346 100644
--- a/src/site/xdoc/download.xml
+++ b/src/site/xdoc/download.xml
@@ -39,7 +39,9 @@
                         </a>
                         <br/>
                         and follow instructions at
-                        <a href="macosxsetup.html">DavMail Setup on Mac OS X</a>
+                        <a href="macosxsetup.html">DavMail Setup on Mac OS X</a><br/>
+                        Note to OSX Mountain Lion users: you need to disable Gatekeeper (at least temporarily) to avoid
+                        the <code>DavMail is damaged and can’t be opened</code> message.
                     </li>
                     <li>
                         <strong>Debian Linux (Ubuntu):</strong>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
index b07f980..39a164c 100644
--- a/src/site/xdoc/index.xml
+++ b/src/site/xdoc/index.xml
@@ -55,6 +55,16 @@
                         <a class="download" href="download.html">
                             Download DavMail Gateway
                         </a>
+                        <div style='padding: 20px;'>
+                        <a href="http://www.jetbrains.com/idea/"
+                           style="position: relative;display:block; width:88px; height:31px; border:0; margin:0;padding:0;text-decoration:none;text-indent:0;">
+                            <span style="margin: 0;padding: 0;position: absolute;top: -1px;left: 4px;font-size: 10px;cursor:pointer;  background-image:none;border:0;color: #0d3a9e; font-family: trebuchet ms,arial,sans-serif;font-weight: normal;text-align:left;">
+                                Developed with
+                            </span>
+                            <img src="http://www.jetbrains.com/idea/opensource/img/all/banners/idea88x31_white.gif"
+                                 alt="The best Java IDE" border="0"/>
+                        </a>
+                        </div>
                     </td>
                 </tr>
             </table>
diff --git a/src/site/xdoc/macosxsetup.xml b/src/site/xdoc/macosxsetup.xml
index 20c294b..5678dc1 100644
--- a/src/site/xdoc/macosxsetup.xml
+++ b/src/site/xdoc/macosxsetup.xml
@@ -11,6 +11,9 @@
     <body>
 
         <section name="DavMail Setup on Mac OS X">
+            <p>Note to OSX Mountain Lion users: you need to disable Gatekeeper (at least temporarily) to avoid the
+                <code>DavMail is damaged and can’t be opened</code> message.
+            </p>
             <p>Older OSX releases include Java 5, this version does not support Tray icon,
                 and DavMail uses a dedicated frame instead. An upgrade to Java 1.6 will enable tray icon.
                 Recent OSX versions either include Java 6 or can install it automatically on first Java application
diff --git a/src/site/xdoc/roadmap.xml b/src/site/xdoc/roadmap.xml
index 0bb78ad..4bde3fd 100644
--- a/src/site/xdoc/roadmap.xml
+++ b/src/site/xdoc/roadmap.xml
@@ -15,33 +15,33 @@
                 for improvement. The following section lists the expected new features
                 and enhancements in next DavMail versions.
             </p>
-            <subsection name="3.9.9">
-                <p>
-                    <strong>Next minor release</strong>
-                </p>
-                <ul>
-                    <li>Improve IMAP sync performance</li>
-                </ul>
-            </subsection>
             <subsection name="4.0">
                 <p>
                     <strong>Next major version</strong>
                 </p>
                 <ul>
-                    <li>Implement split and kerberos authentication</li>
                     <li>Implement optional ICS Todo/Task conversion to Outlook tasks: Done</li>
                     <li>Exchange 2010 support through EWS: Done</li>
+                    <li>Switch wrappers to WinRun4J</li>
                 </ul>
             </subsection>
             <subsection name="4.0.1">
                 <p>
-                    <strong>Next minor version</strong>
+                    <strong>Next patch release</strong>
                 </p>
                 <ul>
-                    <li>Switch from registry to link on windows</li>
                     <li>Test windows install on seven without admin rights</li>
                 </ul>
             </subsection>
+            <subsection name="4.1">
+                <p>
+                    <strong>Next minor release</strong>
+                </p>
+                <ul>
+                    <li>Switch from registry to link on windows</li>
+                    <li>Implement split and kerberos authentication</li>
+                </ul>
+            </subsection>
             <subsection name="4.x">
                 <p>
                     <strong>Future version</strong>
@@ -49,7 +49,6 @@
                 <ul>
                     <li>Implement Caldav attachments</li>
                     <li>Test the RPM package</li>
-                    <li>Switch wrappers to WinRun4J</li>
                     <li>Implement ActiveSync backend</li>
                     <li>Implement EWS frontend for Exchange 2003 backend and Outlook 2011</li>
                     <li>Implement custom authenticator interface to handle specific authentications
diff --git a/src/site/xdoc/serversetup.xml b/src/site/xdoc/serversetup.xml
index 9f25547..e621d4e 100644
--- a/src/site/xdoc/serversetup.xml
+++ b/src/site/xdoc/serversetup.xml
@@ -45,6 +45,7 @@ davmail.proxyHost=
 davmail.proxyPort=
 davmail.proxyUser=
 davmail.proxyPassword=
+davmail.noProxyFor=
 davmail.ssl.keystoreType=JKS
 davmail.ssl.keyPass=
 davmail.ssl.keystoreFile=
diff --git a/src/site/xdoc/thunderbirdimapmailsetup.xml b/src/site/xdoc/thunderbirdimapmailsetup.xml
index f911ce5..febd2aa 100644
--- a/src/site/xdoc/thunderbirdimapmailsetup.xml
+++ b/src/site/xdoc/thunderbirdimapmailsetup.xml
@@ -44,7 +44,7 @@
                     <code>Re-test</code> to validate account settings, then <code>Create Account</code>:
                 </p>
                 <div style="width: 100%;text-align: center">
-                    <img src="images/thunderbirdAccountPop3.png" alt=""/>
+                    <img src="images/thunderbirdAccount3.png" alt=""/>
                 </div>
 
 
diff --git a/src/site/xdoc/thunderbirdmailsetup.xml b/src/site/xdoc/thunderbirdmailsetup.xml
index 243b7d2..72eb3f3 100644
--- a/src/site/xdoc/thunderbirdmailsetup.xml
+++ b/src/site/xdoc/thunderbirdmailsetup.xml
@@ -46,7 +46,7 @@
                     <code>Re-test</code> to validate account settings, then <code>Create Account</code>:
                 </p>
                 <div style="width: 100%;text-align: center">
-                    <img src="images/thunderbirdAccount3.png" alt=""/>
+                    <img src="images/thunderbirdAccountPop3.png" alt=""/>
                 </div>
 
 
diff --git a/src/test/davmail/imap/TestImap.java b/src/test/davmail/imap/TestImap.java
index ef10471..2d93aa1 100644
--- a/src/test/davmail/imap/TestImap.java
+++ b/src/test/davmail/imap/TestImap.java
@@ -23,6 +23,7 @@ import davmail.Settings;
 import javax.mail.MessagingException;
 import javax.mail.Session;
 import javax.mail.internet.MimeMessage;
+import javax.mail.util.SharedByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Random;
@@ -66,6 +67,7 @@ public class TestImap extends AbstractImapTestCase {
     }
 
     public void testUidSearchdeleted() throws IOException {
+        testSelectInbox();
         writeLine(". UID SEARCH DELETED");
         assertEquals(". OK SEARCH completed", readFullAnswer("."));
     }
@@ -366,7 +368,7 @@ public class TestImap extends AbstractImapTestCase {
     public void testDraftMessageMessageId() throws IOException, InterruptedException, MessagingException {
         testCreateFolder();
         MimeMessage mimeMessage = new MimeMessage((Session) null);
-        mimeMessage.addHeader("to", Settings.getProperty("davmail.to"));
+        mimeMessage.addHeader("to", "testto <"+Settings.getProperty("davmail.to")+">");
         mimeMessage.setText("Test message");
         mimeMessage.setSubject("Test subject");
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -380,7 +382,13 @@ public class TestImap extends AbstractImapTestCase {
         writeLine(". UID SEARCH UNDELETED (HEADER Message-ID "+mimeMessage.getMessageID().substring(1, mimeMessage.getMessageID().length()-1)+")");
         assertEquals(". OK SEARCH completed", readFullAnswer("."));
 
-        testDeleteFolder();
+        writeLine(". UID SEARCH (HEADER To "+Settings.getProperty("davmail.to")+")");
+        assertEquals(". OK SEARCH completed", readFullAnswer("."));
+
+        writeLine(". UID SEARCH (HEADER To testto)");
+        assertEquals(". OK SEARCH completed", readFullAnswer("."));
+
+        //testDeleteFolder();
     }
 
     public void testFetchOSX() throws IOException {
@@ -394,4 +402,53 @@ public class TestImap extends AbstractImapTestCase {
         writeLine(". FETCH 1:* (UID RFC822.SIZE FLAGS BODY.PEEK[HEADER.FIELDS (From To Cc Bcc Subject Date Message-ID Priority X-Priority References Newsgroups In-Reply-To Content-Type)])");
         assertEquals(". OK FETCH completed", readFullAnswer("."));
     }
+
+    public void testInvalidMime() throws MessagingException, IOException {
+        testCreateFolder();
+
+        MimeMessage mimeMessage = new MimeMessage((Session) null);
+        mimeMessage.addHeader("to", Settings.getProperty("davmail.to"));
+        mimeMessage.addHeader("bcc", Settings.getProperty("davmail.bcc"));
+        mimeMessage.setText("test");
+        mimeMessage.setSubject("subject");
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        mimeMessage.writeTo(baos);
+        byte[] content = baos.toByteArray();
+        String invalidMessageContent = "MAIL FROM: " + Settings.getProperty("davmail.bcc") + "\n" +
+                "RCPT TO: " + Settings.getProperty("davmail.to") + "\n\n" + new String(content, "UTF-8");
+
+        mimeMessage = new MimeMessage((Session) null, new SharedByteArrayInputStream(invalidMessageContent.getBytes("UTF-8")));
+        baos = new ByteArrayOutputStream();
+        mimeMessage.writeTo(baos);
+
+        content = baos.toByteArray();
+        writeLine(". APPEND testfolder (\\Seen \\Draft) {" + content.length + '}');
+        assertEquals("+ send literal data", readLine());
+        writeLine(new String(content));
+        assertEquals(". OK APPEND completed", readFullAnswer("."));
+        writeLine(". NOOP");
+        assertEquals(". OK NOOP completed", readFullAnswer("."));
+
+        // fetch message uid
+        writeLine(". UID FETCH 1:* (FLAGS BODYSTRUCTURE)");
+        String messageLine = readLine();
+        int uidIndex = messageLine.indexOf("UID ") + 4;
+        messageUid = messageLine.substring(uidIndex, messageLine.indexOf(' ', uidIndex));
+        assertEquals(". OK UID FETCH completed", readFullAnswer("."));
+        assertNotNull(messageUid);
+
+        testDeleteFolder();
+
+    }
+
+    public void testFetchHeadersSentThunderbird() throws IOException {
+        writeLine(". SELECT Sent");
+        //writeLine(". SELECT INBOX");
+        assertEquals(". OK [READ-WRITE] SELECT completed", readFullAnswer("."));
+        writeLine(". UID SEARCH (SINCE \"01-Jun-2012\")");
+        assertEquals(". OK SEARCH completed", readFullAnswer("."));
+        writeLine(". UID FETCH 6071:* (UID RFC822.SIZE FLAGS BODY.PEEK[HEADER.FIELDS (From To Cc Bcc Subject Date Message-ID Priority X-Priority References Newsgroups In-Reply-To Content-Type)])");
+        assertEquals(". OK UID FETCH completed", readFullAnswer("."));
+    }
+
 }
diff --git a/src/web/WEB-INF/classes/davmail.properties b/src/web/WEB-INF/classes/davmail.properties
index ad0e495..0a49025 100644
--- a/src/web/WEB-INF/classes/davmail.properties
+++ b/src/web/WEB-INF/classes/davmail.properties
@@ -11,6 +11,7 @@ davmail.proxyHost=
 davmail.proxyPort=
 davmail.proxyUser=
 davmail.proxyPassword=
+davmail.noProxyFor=
 
 davmail.allowRemote=true
 davmail.bindAddress=
diff --git a/src/winrun4j/davmail.exe b/src/winrun4j/davmail.exe
new file mode 100644
index 0000000..8a3db9c
Binary files /dev/null and b/src/winrun4j/davmail.exe differ
diff --git a/src/winrun4j/davmail.ico b/src/winrun4j/davmail.ico
new file mode 100644
index 0000000..7f07861
Binary files /dev/null and b/src/winrun4j/davmail.ico differ
diff --git a/src/winrun4j/davmail.ini b/src/winrun4j/davmail.ini
new file mode 100644
index 0000000..bf637c3
--- /dev/null
+++ b/src/winrun4j/davmail.ini
@@ -0,0 +1,29 @@
+main.class=davmail.DavGateway
+classpath.1=davmail.jar
+classpath.2=lib/activation-1.1.1.jar
+classpath.3=lib/commons-codec-1.3.jar
+classpath.4=lib/commons-collections-3.1.jar
+classpath.5=lib/commons-httpclient-3.1.jar
+classpath.6=lib/commons-logging-1.0.4.jar
+classpath.7=lib/htmlcleaner-2.1.jar
+classpath.8=lib/jackrabbit-webdav-1.4.jar
+classpath.9=lib/jcharset-1.3.jar
+classpath.10=lib/jcifs-1.3.14.jar
+classpath.11=lib/jdom-1.0.jar
+classpath.12=lib/log4j-1.2.16.jar
+classpath.13=lib/mail-1.4.3.jar
+classpath.14=lib/slf4j-api-1.3.1.jar
+classpath.15=lib/slf4j-log4j12-1.3.1.jar
+classpath.16=lib/stax-api-1.0.1.jar
+classpath.17=lib/stax2-api-3.1.1.jar
+classpath.18=lib/swt-3.7-win32-x86.jar
+classpath.19=lib/woodstox-core-asl-4.1.2.jar
+classpath.20=lib/xercesImpl-2.8.1.jar
+
+vm.version.min=1.6
+vmarg.1=-Dsun.net.inetaddr.ttl=60
+vmarg.2=-XmX512M
+
+[ErrorMessages]
+java.not.found=A suitable version of Java could not be found on your system, please install Java from http://java.com
+java.failed=Java failed to startup successfully, please install Java from http://java.com
diff --git a/src/winrun4j/davmail64.exe b/src/winrun4j/davmail64.exe
new file mode 100644
index 0000000..6329c39
Binary files /dev/null and b/src/winrun4j/davmail64.exe differ
diff --git a/src/winrun4j/davmail64.ini b/src/winrun4j/davmail64.ini
new file mode 100644
index 0000000..8a9f909
--- /dev/null
+++ b/src/winrun4j/davmail64.ini
@@ -0,0 +1,29 @@
+main.class=davmail.DavGateway
+classpath.1=davmail.jar
+classpath.2=lib/activation-1.1.1.jar
+classpath.3=lib/commons-codec-1.3.jar
+classpath.4=lib/commons-collections-3.1.jar
+classpath.5=lib/commons-httpclient-3.1.jar
+classpath.6=lib/commons-logging-1.0.4.jar
+classpath.7=lib/htmlcleaner-2.1.jar
+classpath.8=lib/jackrabbit-webdav-1.4.jar
+classpath.9=lib/jcharset-1.3.jar
+classpath.10=lib/jcifs-1.3.14.jar
+classpath.11=lib/jdom-1.0.jar
+classpath.12=lib/log4j-1.2.16.jar
+classpath.13=lib/mail-1.4.3.jar
+classpath.14=lib/slf4j-api-1.3.1.jar
+classpath.15=lib/slf4j-log4j12-1.3.1.jar
+classpath.16=lib/stax-api-1.0.1.jar
+classpath.17=lib/stax2-api-3.1.1.jar
+classpath.18=lib/swt-3.7-win32-x86_64.jar
+classpath.19=lib/woodstox-core-asl-4.1.2.jar
+classpath.20=lib/xercesImpl-2.8.1.jar
+
+vm.version.min=1.6
+vmarg.1=-Dsun.net.inetaddr.ttl=60
+vmarg.2=-XmX512M
+
+[ErrorMessages]
+java.not.found=A suitable version of Java could not be found on your system, please install Java (64-bit) from http://java.com/en/download/manual.jsp
+java.failed=Java failed to startup successfully, please install Java (64-bit) from http://java.com/en/download/manual.jsp
diff --git a/src/winrun4j/davmailservice.exe b/src/winrun4j/davmailconsole.exe
similarity index 79%
copy from src/winrun4j/davmailservice.exe
copy to src/winrun4j/davmailconsole.exe
index e8428aa..f6767fd 100644
Binary files a/src/winrun4j/davmailservice.exe and b/src/winrun4j/davmailconsole.exe differ
diff --git a/src/winrun4j/davmailservice.exe b/src/winrun4j/davmailservice.exe
index e8428aa..b0686a0 100644
Binary files a/src/winrun4j/davmailservice.exe and b/src/winrun4j/davmailservice.exe differ
diff --git a/src/winrun4j/davmailservice.ini b/src/winrun4j/davmailservice.ini
index bf5b70a..1cfb7ce 100644
--- a/src/winrun4j/davmailservice.ini
+++ b/src/winrun4j/davmailservice.ini
@@ -13,3 +13,7 @@ vmarg.2=-Xrs
 
 
 arg.1=davmail.properties
+
+[ErrorMessages]
+java.not.found=A suitable version of Java could not be found on your system, please install Java from http://java.com
+java.failed=Java failed to startup successfully, please install Java from http://java.com
diff --git a/src/winrun4j/davmailservice64.exe b/src/winrun4j/davmailservice64.exe
new file mode 100644
index 0000000..b11f15a
Binary files /dev/null and b/src/winrun4j/davmailservice64.exe differ
diff --git a/src/winrun4j/davmailservice64.ini b/src/winrun4j/davmailservice64.ini
new file mode 100644
index 0000000..8412932
--- /dev/null
+++ b/src/winrun4j/davmailservice64.ini
@@ -0,0 +1,19 @@
+service.startup=auto
+service.class=davmail.service.DavService
+service.id=DavMail
+service.name=DavMail Gateway
+service.description=DavMail POP/IMAP/SMTP/Caldav/Carddav/LDAP Exchange Gateway
+
+classpath.1=davmail.jar
+classpath.2=lib/*
+
+vm.version.min=1.6
+vmarg.1=-Dsun.net.inetaddr.ttl=60
+vmarg.2=-Xrs
+
+
+arg.1=davmail.properties
+
+[ErrorMessages]
+java.not.found=A suitable version of Java could not be found on your system, please install Java (64-bit) from http://java.com/en/download/manual.jsp
+java.failed=Java failed to startup successfully, please install Java (64-bit) from http://java.com/en/download/manual.jsp
diff --git a/src/winrun4j/rcedit64.exe b/src/winrun4j/rcedit64.exe
new file mode 100644
index 0000000..ce17dcb
Binary files /dev/null and b/src/winrun4j/rcedit64.exe differ

-- 
davmail packaging



More information about the pkg-java-commits mailing list