[Pkg-cli-apps-commits] [SCM] keepass2 branch, upstream, updated. upstream/2.17-1-gc10829c

Julian Taylor jtaylor.debian at googlemail.com
Thu Jan 5 23:04:34 UTC 2012


The following commit has been merged in the upstream branch:
commit c10829ceae406fcc6ac846409ce1fc1f42efee51
Author: Julian Taylor <jtaylor.debian at googlemail.com>
Date:   Thu Jan 5 23:28:32 2012 +0100

    Imported Upstream version 2.18

diff --git a/Build/KeePassLibSD_Distrib/KeePassLibSD.dll b/Build/KeePassLibSD_Distrib/KeePassLibSD.dll
index f32e380..543aa5b 100644
Binary files a/Build/KeePassLibSD_Distrib/KeePassLibSD.dll and b/Build/KeePassLibSD_Distrib/KeePassLibSD.dll differ
diff --git a/Build/KeePassLib_Distrib/KeePassLib.dll b/Build/KeePassLib_Distrib/KeePassLib.dll
index db41282..3cd1848 100644
Binary files a/Build/KeePassLib_Distrib/KeePassLib.dll and b/Build/KeePassLib_Distrib/KeePassLib.dll differ
diff --git a/Build/KeePassLib_Distrib/KeePassLib.xml b/Build/KeePassLib_Distrib/KeePassLib.xml
index 62ea7d7..744d618 100644
--- a/Build/KeePassLib_Distrib/KeePassLib.xml
+++ b/Build/KeePassLib_Distrib/KeePassLib.xml
@@ -134,11 +134,6 @@
             Interface to a user key, like a password, key file data, etc.
             </summary>
         </member>
-        <member name="M:KeePassLib.Keys.IUserKey.Clear">
-            <summary>
-            Clear the key and securely erase all security-critical information.
-            </summary>
-        </member>
         <member name="P:KeePassLib.Keys.IUserKey.KeyData">
             <summary>
             Get key data. Querying this property is fast (it returns a
@@ -202,11 +197,6 @@
             Construct a user account key.
             </summary>
         </member>
-        <member name="M:KeePassLib.Keys.KcpUserAccount.Clear">
-            <summary>
-            Clear the key and securely erase all security-critical information.
-            </summary>
-        </member>
         <member name="P:KeePassLib.Keys.KcpUserAccount.KeyData">
             <summary>
             Get key data. Querying this property is fast (it returns a
@@ -360,17 +350,6 @@
             Construct a new, empty key object.
             </summary>
         </member>
-        <member name="M:KeePassLib.Keys.CompositeKey.Finalize">
-            <summary>
-            Deconstructor, clears up the key.
-            </summary>
-        </member>
-        <member name="M:KeePassLib.Keys.CompositeKey.Clear">
-            <summary>
-            Clears the key. This function also erases all previously stored
-            user key data objects.
-            </summary>
-        </member>
         <member name="M:KeePassLib.Keys.CompositeKey.AddUserKey(KeePassLib.Keys.IUserKey)">
             <summary>
             Add a user key.
@@ -457,23 +436,14 @@
         <member name="T:KeePassLib.Security.ProtectedString">
             <summary>
             Represents an in-memory encrypted string.
+            <c>ProtectedString</c> objects are immutable and thread-safe.
             </summary>
         </member>
         <member name="M:KeePassLib.Security.ProtectedString.#ctor">
             <summary>
             Construct a new protected string object. Protection is
-            disabled by default! You need to call the
-            <c>EnableProtection</c> member function in order to
-            enable the protection, if you wish the string to be protected.
-            </summary>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedString.#ctor(System.Boolean)">
-            <summary>
-            Construct a new in-memory encrypted string object.
+            disabled.
             </summary>
-            <param name="bEnableProtection">If this parameter is <c>true</c>,
-            the string will be protected in-memory (encrypted). If it
-            is <c>false</c>, the string will be stored as plain-text.</param>
         </member>
         <member name="M:KeePassLib.Security.ProtectedString.#ctor(System.Boolean,System.String)">
             <summary>
@@ -495,17 +465,8 @@
             the string will be protected in-memory (encrypted). If it
             is <c>false</c>, the string will be stored as plain-text.</param>
             <param name="vUtf8Value">The initial string value, encoded as
-            UTF-8 byte array. This parameter won't be modified.</param>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedString.#ctor(KeePassLib.Security.ProtectedString)">
-            <summary>
-            Construct a new protected string. The string is initialized
-            to the value passed in the <c>pbTemplate</c> protected string.
-            </summary>
-            <param name="psTemplate">The initial string value. This
-            parameter won't be modified. Must not be <c>null</c>.</param>
-            <exception cref="T:System.ArgumentNullException">Thrown if the input
-            parameter is <c>null</c>.</exception>
+            UTF-8 byte array. This parameter won't be modified; the caller
+            is responsible for clearing it.</param>
         </member>
         <member name="M:KeePassLib.Security.ProtectedString.#ctor(System.Boolean,KeePassLib.Security.XorredBuffer)">
             <summary>
@@ -519,38 +480,11 @@
             <exception cref="T:System.ArgumentNullException">Thrown if the input
             parameter is <c>null</c>.</exception>
         </member>
-        <member name="M:KeePassLib.Security.ProtectedString.Clear">
-            <summary>
-            Clear the string. Doesn't change the protection level.
-            </summary>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedString.EnableProtection(System.Boolean)">
-            <summary>
-            Change the protection level (protect or don't protect). Note: you
-            only need to call this function if you really want to change the
-            protection. If you specified the protection flag in the constructor,
-            and don't want to change it, you don't need to call this function.
-            </summary>
-            <param name="bProtect">If <c>true</c>, the string will be protected
-            (encrypted in-memory). Otherwise the string will be stored in
-            plain-text in the process memory.</param>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedString.SetString(System.String)">
-            <summary>
-            Assign a new string value to the object.
-            </summary>
-            <param name="strNewValue">New string. The string must not contain
-            a <c>null</c> terminator.</param>
-            <exception cref="T:System.ArgumentNullException">Thrown if the input
-            parameter is <c>null</c>.</exception>
-            <exception cref="T:System.ArgumentException">Thrown if the new string
-            contains a <c>null</c> terminator.</exception>
-        </member>
         <member name="M:KeePassLib.Security.ProtectedString.ReadString">
             <summary>
             Convert the protected string to a normal string object.
             Be careful with this function, the returned string object
-            isn't protected any more and stored in plain-text in the
+            isn't protected anymore and stored in plain-text in the
             process memory.
             </summary>
             <returns>Plain-text string. Is never <c>null</c>.</returns>
@@ -566,12 +500,7 @@
         <member name="M:KeePassLib.Security.ProtectedString.ReadXorredString(KeePassLib.Cryptography.CryptoRandomStream)">
             <summary>
             Read the protected string and return it protected with a sequence
-            of bytes generated by a random stream. The object's data will be
-            invisible in process memory only if the object has been initialized
-            using a <c>XorredBuffer</c>. If no <c>XorredBuffer</c> has been used
-            or the string has been read once already (in plain-text), the
-            operation won't be secure and the protected string will be visible
-            in process memory.
+            of bytes generated by a random stream.
             </summary>
             <param name="crsRandomSource">Random number source.</param>
             <returns>Protected string.</returns>
@@ -580,62 +509,34 @@
         </member>
         <member name="P:KeePassLib.Security.ProtectedString.IsProtected">
             <summary>
-            A flag specifying whether the <c>ProtectedString</c> object has turned on
-            in-memory protection or not.
-            </summary>
-        </member>
-        <member name="P:KeePassLib.Security.ProtectedString.IsViewable">
-            <summary>
-            A value specifying whether the <c>ProtectedString</c> object is currently
-            in-memory protected or not. This flag can be different than
-            <c>IsProtected</c>: if a <c>XorredBuffer</c> is used, the <c>IsProtected</c>
-            flag represents the memory protection flag, but not the actual protection.
-            In this case use <c>IsViewable</c>, which returns <c>true</c> if a
-            <c>XorredBuffer</c> is currently in use.
+            A flag specifying whether the <c>ProtectedString</c> object
+            has turned on in-memory protection or not.
             </summary>
         </member>
         <member name="T:KeePassLib.Security.ProtectedBinary">
             <summary>
             Represents a protected binary, i.e. a byte array that is encrypted
-            in-memory.
+            in memory. A <c>ProtectedBinary</c> object is immutable and
+            thread-safe.
             </summary>
         </member>
         <member name="M:KeePassLib.Security.ProtectedBinary.#ctor">
             <summary>
             Construct a new, empty protected binary data object. Protection
-            is disabled by default! You need to call the
-            <c>EnableProtection</c> member function to enable the protection
-            manually, if you wish the data to be protected.
+            is disabled.
             </summary>
         </member>
-        <member name="M:KeePassLib.Security.ProtectedBinary.#ctor(System.Boolean)">
-            <summary>
-            Construct a new, empty protected binary data object.
-            </summary>
-            <param name="bEnableProtection">If this parameter is <c>true</c>,
-            the data will be encrypted in-memory. If it is <c>false</c>, the
-            data is stored in plain-text in the process memory.</param>
-        </member>
         <member name="M:KeePassLib.Security.ProtectedBinary.#ctor(System.Boolean,System.Byte[])">
             <summary>
             Construct a new protected binary data object.
             </summary>
             <param name="bEnableProtection">If this paremeter is <c>true</c>,
-            the data will be encrypted in-memory. If it is <c>false</c>, the
+            the data will be encrypted in memory. If it is <c>false</c>, the
             data is stored in plain-text in the process memory.</param>
-            <param name="pbInitialValue">Initial value of the protected
-            object. The input parameter is not modified.</param>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedBinary.#ctor(KeePassLib.Security.ProtectedBinary)">
-            <summary>
-            Construct a new protected binary data object. Copy the data from
-            an existing object.
-            </summary>
-            <param name="pbTemplate">Existing <c>ProtectedBinary</c> object,
-            which is used to initialize the new object. This parameter must
-            not be <c>null</c>.</param>
-            <exception cref="T:System.ArgumentNullException">Thrown if the input
-            parameter is <c>null</c>.</exception>
+            <param name="pbData">Value of the protected object.
+            The input parameter is not modified and
+            <c>ProtectedBinary</c> doesn't take ownership of the data,
+            i.e. the caller is responsible for clearing it.</param>
         </member>
         <member name="M:KeePassLib.Security.ProtectedBinary.#ctor(System.Boolean,KeePassLib.Security.XorredBuffer)">
             <summary>
@@ -648,40 +549,12 @@
             <exception cref="T:System.ArgumentNullException">Thrown if the input
             parameter is <c>null</c>.</exception>
         </member>
-        <member name="M:KeePassLib.Security.ProtectedBinary.Clear">
-            <summary>
-            Clear the protected data object. Doesn't change the protection level.
-            </summary>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedBinary.EnableProtection(System.Boolean)">
-            <summary>
-            Change the protection level (protect or don't protect). Note: you
-            only need to call this function if you really want to change the
-            protection. If you specified the protection flag in the constructor,
-            and don't want to change it, you don't need to call this function.
-            </summary>
-            <param name="bEnableProtection">If <c>true</c>, the data will be protected
-            (encrypted in-memory). Otherwise the data will be stored in
-            plain-text in the process memory.</param>
-        </member>
-        <member name="M:KeePassLib.Security.ProtectedBinary.SetData(System.Byte[])">
-            <summary>
-            Set protected data. This function also clears the internal
-            <c>XorredBuffer</c> object.
-            </summary>
-            <param name="pbNew">Data to store in the protected object. The input
-            byte array will not be modified, the data is copied to an internal
-            buffer of the protected object. This parameter must not be <c>null</c>;
-            if you want to clear the object, call the <c>Clear</c> member
-            function.</param>
-            <exception cref="T:System.ArgumentNullException">Thrown if the input
-            parameter is <c>null</c>.</exception>
-        </member>
         <member name="M:KeePassLib.Security.ProtectedBinary.ReadData">
             <summary>
-            Get the protected data as a byte array. Please note that the returned
-            byte array is not protected and can therefore been read by any other
-            applications. Make sure that your clear it properly after usage.
+            Get a copy of the protected data as a byte array.
+            Please note that the returned byte array is not protected and
+            can therefore been read by any other application.
+            Make sure that your clear it properly after usage.
             </summary>
             <returns>Unprotected byte array. This is always a copy of the internal
             protected data and can therefore be cleared safely.</returns>
@@ -689,12 +562,7 @@
         <member name="M:KeePassLib.Security.ProtectedBinary.ReadXorredData(KeePassLib.Cryptography.CryptoRandomStream)">
             <summary>
             Read the protected data and return it protected with a sequence
-            of bytes generated by a random stream. The object's data will be
-            invisible in process memory only if the object has been initialized
-            using a <c>XorredBuffer</c>. If no <c>XorredBuffer</c> has been used
-            or the binary has been read once already (in plain-text), the
-            operation won't be secure and the protected string will be visible
-            in process memory.
+            of bytes generated by a random stream.
             </summary>
             <param name="crsRandomSource">Random number source.</param>
             <returns>Protected data.</returns>
@@ -703,18 +571,8 @@
         </member>
         <member name="P:KeePassLib.Security.ProtectedBinary.IsProtected">
             <summary>
-            A flag specifying whether the <c>ProtectedBinary</c> object has turned on
-            in-memory protection or not.
-            </summary>
-        </member>
-        <member name="P:KeePassLib.Security.ProtectedBinary.IsViewable">
-            <summary>
-            A value specifying whether the <c>ProtectedString</c> object is currently
-            in-memory protected or not. This flag can be different than
-            <c>IsProtected</c>: if a <c>XorredBuffer</c> is used, the <c>IsProtected</c>
-            flag represents the memory protection flag, but not the actual protection.
-            In this case use <c>IsViewable</c>, which returns <c>true</c> if a
-            <c>XorredBuffer</c> is currently in use.
+            A flag specifying whether the <c>ProtectedBinary</c> object has
+            turned on in-memory protection or not.
             </summary>
         </member>
         <member name="P:KeePassLib.Security.ProtectedBinary.Length">
@@ -823,6 +681,12 @@
             'Failed to load the specified file!'.
             </summary>
         </member>
+        <member name="P:KeePassLib.Resources.KLRes.FileLockedWrite">
+            <summary>
+            Look up a localized string similar to
+            'The file is locked, because the following user is currently writing to it:'.
+            </summary>
+        </member>
         <member name="P:KeePassLib.Resources.KLRes.FileNewVerReq">
             <summary>
             Look up a localized string similar to
@@ -913,6 +777,12 @@
             'The selected file appears to be an old format'.
             </summary>
         </member>
+        <member name="P:KeePassLib.Resources.KLRes.TryAgainSecs">
+            <summary>
+            Look up a localized string similar to
+            'Please try it again in a few seconds.'.
+            </summary>
+        </member>
         <member name="P:KeePassLib.Resources.KLRes.UnknownHeaderId">
             <summary>
             Look up a localized string similar to
@@ -1042,11 +912,11 @@
             Convert a hexadecimal string to a byte array. The input string must be
             even (i.e. its length is a multiple of 2).
             </summary>
-            <param name="strHexString">String containing hexadecimal characters.</param>
+            <param name="strHex">String containing hexadecimal characters.</param>
             <returns>Returns a byte array. Returns <c>null</c> if the string parameter
             was <c>null</c> or is an uneven string (i.e. if its length isn't a
             multiple of 2).</returns>
-            <exception cref="T:System.ArgumentNullException">Thrown if <paramref name="strHexString"/>
+            <exception cref="T:System.ArgumentNullException">Thrown if <paramref name="strHex"/>
             is <c>null</c>.</exception>
         </member>
         <member name="M:KeePassLib.Utility.MemUtil.ByteArrayToHexString(System.Byte[])">
@@ -1535,8 +1405,8 @@
         <member name="T:KeePassLib.Security.XorredBuffer">
             <summary>
             Represents an object that is encrypted using a XOR pad until
-            it is read. The key XOR pad can be changed without revealing the
-            protected data in process memory.
+            it is read. <c>XorredBuffer</c> objects are immutable and
+            thread-safe.
             </summary>
         </member>
         <member name="M:KeePassLib.Security.XorredBuffer.#ctor(System.Byte[],System.Byte[])">
@@ -1545,10 +1415,12 @@
             and a XOR pad that decrypts the protected data. The
             <paramref name="pbProtectedData"/> byte array must have the same size
             as the <paramref name="pbXorPad"/> byte array.
+            The <c>XorredBuffer</c> object takes ownership of the two byte
+            arrays, i.e. the caller must not use or modify them afterwards.
             </summary>
             <param name="pbProtectedData">Protected data (XOR pad applied).</param>
-            <param name="pbXorPad">XOR pad that is used to decrypt the
-            <paramref name="pbData"/> parameter.</param>
+            <param name="pbXorPad">XOR pad that can be used to decrypt the
+            <paramref name="pbProtectedData"/> parameter.</param>
             <exception cref="T:System.ArgumentNullException">Thrown if one of the input
             parameters is <c>null</c>.</exception>
             <exception cref="T:System.ArgumentException">Thrown if the byte arrays are
@@ -1556,40 +1428,11 @@
         </member>
         <member name="M:KeePassLib.Security.XorredBuffer.ReadPlainText">
             <summary>
-            Decrypt the buffer. The <c>XorredBuffer</c> protection is useless
-            after you used this method. The object cannot be re-encrypted.
+            Get a copy of the plain-text. The caller is responsible
+            for clearing the byte array safely after using it.
             </summary>
             <returns>Unprotected plain-text byte array.</returns>
         </member>
-        <member name="M:KeePassLib.Security.XorredBuffer.ChangeKey(System.Byte[])">
-            <summary>
-            Change the protection key for this <c>XorredBuffer</c> object.
-            The data will first be decrypted using the old key and then
-            re-encrypted using the new key. This operation doesn't reveal
-            the plain-text in the process memory.
-            </summary>
-            <param name="pbNewXorPad">New protection pad. Must contain exactly
-            the same number of bytes as the length of the currently protected data.
-            Use the <c>Length</c> property of the <c>XorredBuffer</c> to query
-            the data length and pass a correct number of bytes to <c>ChangeKey</c>.</param>
-            <returns>New protected data (encrypted using the new XOR pad).</returns>
-            <exception cref="T:System.ArgumentNullException">Thrown if the input
-            parameter is <c>null</c>.</exception>
-            <exception cref="T:System.ArgumentException">Thrown if the input
-            byte array doesn't have the correct size.</exception>
-        </member>
-        <member name="M:KeePassLib.Security.XorredBuffer.XorArrays(System.Byte[],System.Byte[])">
-            <summary>
-            XOR all bytes in a data buffer with a pad. Both byte arrays must
-            be of the same size.
-            </summary>
-            <param name="pbData">Data to be protected.</param>
-            <param name="pbPad">XOR pad.</param>
-            <exception cref="T:System.ArgumentNullException">Thrown if one of the
-            parameters is <c>null</c>.</exception>
-            <exception cref="T:System.ArgumentException">Thrown if the length of
-            the data array and the pad aren't equal.</exception>
-        </member>
         <member name="P:KeePassLib.Security.XorredBuffer.Length">
             <summary>
             Length of the protected data in bytes.
@@ -1768,6 +1611,13 @@
             Compare in-memory protection states.
             </summary>
         </member>
+        <member name="F:KeePassLib.PwCompareOptions.NullEmptyEquivStd">
+            <summary>
+            Empty standard string fields are considered to be the
+            same as non-existing standard string fields.
+            This doesn't affect custom string comparisons.
+            </summary>
+        </member>
         <member name="T:KeePassLib.PwEntry">
             <summary>
             A class representing a password entry. A password entry consists of several
@@ -1990,11 +1840,6 @@
             Master password / passphrase as provided by the user.
             </summary>
         </member>
-        <member name="M:KeePassLib.Keys.KcpPassword.Clear">
-            <summary>
-            Clear the key and securely erase all security-critical information.
-            </summary>
-        </member>
         <member name="P:KeePassLib.Keys.KcpPassword.Password">
             <summary>
             Get the password as protected string.
@@ -2277,11 +2122,6 @@
             Key files as provided by the user.
             </summary>
         </member>
-        <member name="M:KeePassLib.Keys.KcpKeyFile.Clear">
-            <summary>
-            Clear the key and securely erase all security-critical information.
-            </summary>
-        </member>
         <member name="M:KeePassLib.Keys.KcpKeyFile.Create(System.String,System.Byte[])">
             <summary>
             Create a new, random key-file.
@@ -2372,6 +2212,18 @@
             default system directory separator character is used.</param>
             <returns>Path having a directory separator as last character.</returns>
         </member>
+        <member name="M:KeePassLib.Utility.UrlUtil.GetHost(System.String)">
+            <summary>
+            Get the host component of an URL.
+            This method is faster and more fault-tolerant than creating
+            an <code>Uri</code> object and querying its <code>Host</code>
+            property.
+            </summary>
+            <example>
+            For the input <code>s://u:p@d.tld:p/p?q#f</code> the return
+            value is <code>d.tld</code>.
+            </example>
+        </member>
         <member name="T:KeePassLib.Cryptography.HmacOtp">
             <summary>
             Generate HMAC-based one-time passwords as specified in RFC 4226.
@@ -2391,7 +2243,7 @@
             <summary>
             Encrypt a stream.
             </summary>
-            <param name="sPlainText">Stream to read the plain text from.</param>
+            <param name="sPlainText">Stream to read the plain-text from.</param>
             <param name="pbKey">Key to use.</param>
             <param name="pbIV">Initialization vector.</param>
             <returns>Stream, from which the encrypted data can be read.</returns>
@@ -2482,6 +2334,19 @@
             <param name="strText">Source text.</param>
             <returns>Text containing only valid XML characters.</returns>
         </member>
+        <member name="M:KeePassLib.Utility.StrUtil.NormalizeNewLines(System.String,System.Boolean)">
+            <summary>
+            Normalize new line characters in a string. Input strings may
+            contain mixed new line character sequences from all commonly
+            used operating systems (i.e. \r\n from Windows, \n from Unix
+            and \r from Mac OS.
+            </summary>
+            <param name="str">String with mixed new line characters.</param>
+            <param name="bWindows">If <c>true</c>, new line characters
+            are normalized for Windows (\r\n); if <c>false</c>, new line
+            characters are normalized for Unix (\n).</param>
+            <returns>String with normalized new line characters.</returns>
+        </member>
         <member name="M:KeePassLib.Utility.StrUtil.SplitWithSep(System.String,System.String[],System.Boolean)">
             <summary>
             Split a string and include the separators in the splitted array.
@@ -2508,6 +2373,12 @@
             <param name="strDataUri">Data URI to decode.</param>
             <returns>Decoded binary data.</returns>
         </member>
+        <member name="M:KeePassLib.Utility.StrUtil.RemovePlaceholders(System.String)">
+            <summary>
+            Remove placeholders from a string (wrapped in '{' and '}').
+            This doesn't remove environment variables (wrapped in '%').
+            </summary>
+        </member>
         <member name="T:KeePassLib.Serialization.Kdb4Format">
             <summary>
             The <c>Kdb4File</c> class supports saving the data to various
@@ -2902,8 +2773,8 @@
         </member>
         <member name="F:KeePassLib.PwDefs.VersionUrl">
             <summary>
-            URL to an XML file that contains information about the latest KeePass
-            available on the website.
+            URL to a TXT file (eventually compressed) that contains information
+            about the latest KeePass version available on the website.
             </summary>
         </member>
         <member name="F:KeePassLib.PwDefs.HelpUrl">
@@ -3094,6 +2965,11 @@
             <param name="dt"><c>DateTime</c> object to convert to a string.</param>
             <returns>String representing the specified <c>DateTime</c> object.</returns>
         </member>
+        <member name="M:KeePassLib.Utility.TimeUtil.ParseUSTextDate(System.String)">
+            <summary>
+            Parse a US textual date string, like e.g. "January 02, 2012".
+            </summary>
+        </member>
         <member name="F:KeePassLib.Serialization.IOCredSaveMode.NoSave">
             <summary>
             Do not remember user name or password.
diff --git a/Docs/Chm/default.css b/Docs/Chm/default.css
index 73d519c..07410e7 100644
--- a/Docs/Chm/default.css
+++ b/Docs/Chm/default.css
@@ -1,5 +1,5 @@
 /*
-	Design Copyright (c) 2003-2011 Dominik Reichl
+	Design Copyright (c) 2003-2012 Dominik Reichl
 */
 
 body, p, div, h1, h2, h3, h4, h5, h6, ol, ul, li, td, th, dd, dt, a {
diff --git a/Docs/Chm/help/base/autotype.html b/Docs/Chm/help/base/autotype.html
index 3de78f7..5c466e8 100644
--- a/Docs/Chm/help/base/autotype.html
+++ b/Docs/Chm/help/base/autotype.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Auto-Type - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/autourl.html b/Docs/Chm/help/base/autourl.html
index e743bee..f39ce63 100644
--- a/Docs/Chm/help/base/autourl.html
+++ b/Docs/Chm/help/base/autourl.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>URL Field Capabilities - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/cmdline.html b/Docs/Chm/help/base/cmdline.html
index 9d50b8f..c35639e 100644
--- a/Docs/Chm/help/base/cmdline.html
+++ b/Docs/Chm/help/base/cmdline.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Command Line Options - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/configuration.html b/Docs/Chm/help/base/configuration.html
index d12671b..f85df6e 100644
--- a/Docs/Chm/help/base/configuration.html
+++ b/Docs/Chm/help/base/configuration.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Configuration - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/credits.html b/Docs/Chm/help/base/credits.html
index bf783e8..1db2491 100644
--- a/Docs/Chm/help/base/credits.html
+++ b/Docs/Chm/help/base/credits.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Acknowledgements - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/credits_icons_license.html b/Docs/Chm/help/base/credits_icons_license.html
index 91d5078..badd000 100644
--- a/Docs/Chm/help/base/credits_icons_license.html
+++ b/Docs/Chm/help/base/credits_icons_license.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Acknowledgements - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/disclaimer.html b/Docs/Chm/help/base/disclaimer.html
index 2583984..db7e167 100644
--- a/Docs/Chm/help/base/disclaimer.html
+++ b/Docs/Chm/help/base/disclaimer.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Disclaimer</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/faq.html b/Docs/Chm/help/base/faq.html
index caed80c..63916bb 100644
--- a/Docs/Chm/help/base/faq.html
+++ b/Docs/Chm/help/base/faq.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Administrative FAQ - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/faq_tech.html b/Docs/Chm/help/base/faq_tech.html
index 6f6803e..7076086 100644
--- a/Docs/Chm/help/base/faq_tech.html
+++ b/Docs/Chm/help/base/faq_tech.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Technical FAQ - KeePass</title>
 	<base target="_self" />
@@ -81,7 +81,7 @@ Security:
 <li><a href="#encryptionalgo">Could you add the ... encryption algorithm to KeePass?</a></li>
 <li><a href="#noautolock">Why doesn't KeePass lock when Windows locks and a KeePass sub-dialog is open?</a></li>
 <li><a href="#printtempfile">Printing creates a temporary file. Will it be erased securely?</a></li>
-<li><a href="#memprot">Why KeePass 2.x resets in-memory protection options?</a></li>
+<!-- <li><a href="#memprot">Why KeePass 2.x resets in-memory protection options?</a></li> -->
 <li><a href="#qualest">Why the estimated quality of a password suddenly drops?</a></li>
 </ul>
 
@@ -513,7 +513,7 @@ target="_blank">KeePass 2.x Plugin Development</a>.</p>
 
 <br />
 
-<a name="memprot"></a>
+<!-- <a name="memprot"></a>
 <h2 class="sectiontitle">
 <img src="../images/b16x16_help.png" class="singleimg" alt="Info" />  Why
 KeePass 2.x resets in-memory protection options?</h2>
@@ -531,7 +531,7 @@ never search this field type. In-memory protection is useless otherwise.
 If you don't hide by asterisks or search, your data is clear in memory, no
 matter whether the in-memory protection is on or off.</p>
 
-<br />
+<br /> -->
 
 <a name="qualest"></a>
 <h2 class="sectiontitle">
diff --git a/Docs/Chm/help/base/fieldrefs.html b/Docs/Chm/help/base/fieldrefs.html
index e082192..c5183d1 100644
--- a/Docs/Chm/help/base/fieldrefs.html
+++ b/Docs/Chm/help/base/fieldrefs.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Field References - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/firststeps.html b/Docs/Chm/help/base/firststeps.html
index e39542c..ebfe048 100644
--- a/Docs/Chm/help/base/firststeps.html
+++ b/Docs/Chm/help/base/firststeps.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>First Steps Tutorial - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/importexport.html b/Docs/Chm/help/base/importexport.html
index e7c4f70..250b28e 100644
--- a/Docs/Chm/help/base/importexport.html
+++ b/Docs/Chm/help/base/importexport.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>File Formats - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/index.html b/Docs/Chm/help/base/index.html
index ea259db..5cbd208 100644
--- a/Docs/Chm/help/base/index.html
+++ b/Docs/Chm/help/base/index.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Help Center - KeePass</title>
 	<base target="_self" />
@@ -56,7 +56,7 @@ target="_blank"><img src="../../images/osi_certified_72x60.gif" class="singleimg
 </tr></table>
 
 
-<p>KeePass: Copyright © 2003-2011 Dominik Reichl. The program is OSI Certified
+<p>KeePass: Copyright © 2003-2012 Dominik Reichl. The program is OSI Certified
 Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.
 For more information see the
 
diff --git a/Docs/Chm/help/base/integration.html b/Docs/Chm/help/base/integration.html
index 4878ca2..735616e 100644
--- a/Docs/Chm/help/base/integration.html
+++ b/Docs/Chm/help/base/integration.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Integration - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/keys.html b/Docs/Chm/help/base/keys.html
index e953511..0ef657b 100644
--- a/Docs/Chm/help/base/keys.html
+++ b/Docs/Chm/help/base/keys.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Composite Master Key - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/license_lgpl.html b/Docs/Chm/help/base/license_lgpl.html
index 42724db..0e75706 100644
--- a/Docs/Chm/help/base/license_lgpl.html
+++ b/Docs/Chm/help/base/license_lgpl.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>LGPL License - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/multiuser.html b/Docs/Chm/help/base/multiuser.html
index b5c80f4..5228d63 100644
--- a/Docs/Chm/help/base/multiuser.html
+++ b/Docs/Chm/help/base/multiuser.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Multi-User - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/placeholders.html b/Docs/Chm/help/base/placeholders.html
index 613bac3..c7d376b 100644
--- a/Docs/Chm/help/base/placeholders.html
+++ b/Docs/Chm/help/base/placeholders.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Placeholders - KeePass</title>
 	<base target="_self" />
@@ -127,7 +127,7 @@ class="singleimg" alt="Placeholder" />  Paths and Date/Time Placeholde
 <tr><td width="50%">{FIREFOX}</td><td width="50%">Path of Mozilla Firefox, if installed.</td></tr>
 <tr><td width="50%">{OPERA}</td><td width="50%">Path of Opera, if installed.</td></tr>
 <tr><td width="50%">{GOOGLECHROME}</td><td width="50%">Path of Google Chrome, if installed.</td></tr>
-<tr><td width="50%">{SAFARI}</td><td width="50%">Path of Safari, if installed. (KeePass ≥ 1.21 and ≥ 2.17)</td></tr>
+<tr><td width="50%">{SAFARI}</td><td width="50%">Path of Safari, if installed.</td></tr>
 </table>
 
 <br />
@@ -283,8 +283,10 @@ in all following placeholders with the same ID.<br />
 Usage examples:<br />
 <br />
 <code>{USERNAME}{TAB}{PICKCHARS:Password:C=5}{ENTER}</code><br />
-Types the user name, presses Tab, allows the user to pick exactly 5 characters
-from the entry password, types these 5 characters, and presses Enter.<br />
+First a dialog is shown in which the user can pick exactly 5 characters
+from the entry password.
+Afterwards KeePass types the user name into the target window, presses Tab,
+types the 5 picked characters and presses Enter.<br />
 <br />
 <a href="http://keepass.info/screenshots/windows_vista/comboboxform_big.png"
 target="_blank"><img src="../../screenshots/windows_vista/comboboxform.png"
@@ -293,13 +295,17 @@ align="right" alt="ComboBox Form" /></a>
 Conv-Offset=1}{TAB}{PICKCHARS:Password:ID=2, C=1, Conv=D,
 Conv-Offset=1}{TAB}{PICKCHARS:Password:ID=3, C=1, Conv=D,
 Conv-Offset=1}{ENTER}</code><br />
-This first types the contents of a custom entry string named "Memorable",
-and presses Tab. Then the character picking dialog allows to pick exactly
-one character from the password, and this character is converted to
-down arrow keypresses (with one additional keypress, e.g. a '1' is converted
-to two down arrow keypresses), and the focus is switched to the next control
-by pressing Tab. This is repeated two more times
-(the IDs are different, thus the dialog is shown two more times).<br />
+First the character picking dialog is shown three times and each time the user
+can pick exactly one character from the entry password.
+Afterwards the auto-type process starts:
+KeePass types the contents of a custom entry string named "Memorable"
+into the target window.
+The focus is switched to the next control by pressing Tab,
+and the first previously picked character is converted to
+down arrow keypresses (with one additional keypress; e.g. a '1' is converted
+to two down arrow keypresses).
+This is repeated two more times with the other picked characters,
+and finally Enter is pressed.<br />
 <br />
 Note this is not equivalent to picking three characters at once.
 If you'd use <code>{S:Memorable}{TAB}{PICKCHARS:Password:C=3, Conv=D, Conv-Offset=1}</code>,
diff --git a/Docs/Chm/help/base/pwgenerator.html b/Docs/Chm/help/base/pwgenerator.html
index d84f642..b6194d2 100644
--- a/Docs/Chm/help/base/pwgenerator.html
+++ b/Docs/Chm/help/base/pwgenerator.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Password Generator - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/repair.html b/Docs/Chm/help/base/repair.html
index 6eb09c8..a6a64de 100644
--- a/Docs/Chm/help/base/repair.html
+++ b/Docs/Chm/help/base/repair.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Repairing Databases - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/secedits.html b/Docs/Chm/help/base/secedits.html
index c0885ef..84a7be6 100644
--- a/Docs/Chm/help/base/secedits.html
+++ b/Docs/Chm/help/base/secedits.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Secure Edit Controls - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/security.html b/Docs/Chm/help/base/security.html
index dcb8ff7..08b2427 100644
--- a/Docs/Chm/help/base/security.html
+++ b/Docs/Chm/help/base/security.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Security - KeePass</title>
 	<base target="_self" />
@@ -240,12 +240,10 @@ entry passwords) is stored encrypted in process memory.</p>
 <p>This means that even if you would dump the KeePass process memory to disk,
 you couldn't find the passwords.</p>
 
-
-By default, entry passwords are in-memory protected, the other fields not
+<!-- By default, entry passwords are in-memory protected, the other fields not
 (like in 1.x). However, you can turn on in-memory protection for other fields
 in the database settings dialog (not recommended though, because of
-performance reasons).
-
+performance reasons). -->
 
 <p>For example, when you are copying a password to the clipboard, KeePass
 first decrypts the password field, copies it to the clipboard
diff --git a/Docs/Chm/help/base/tans.html b/Docs/Chm/help/base/tans.html
index 28aec26..313d479 100644
--- a/Docs/Chm/help/base/tans.html
+++ b/Docs/Chm/help/base/tans.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>TAN Support - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/base/usingpws.html b/Docs/Chm/help/base/usingpws.html
index 5208eec..61d4679 100644
--- a/Docs/Chm/help/base/usingpws.html
+++ b/Docs/Chm/help/base/usingpws.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Using Stored Passwords - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/autotype_obfuscation.html b/Docs/Chm/help/v2/autotype_obfuscation.html
index 7f1f637..860a1ac 100644
--- a/Docs/Chm/help/v2/autotype_obfuscation.html
+++ b/Docs/Chm/help/v2/autotype_obfuscation.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Two-Channel Auto-Type Obfuscation - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/dbsettings.html b/Docs/Chm/help/v2/dbsettings.html
index ecd88bf..959ea2a 100644
--- a/Docs/Chm/help/v2/dbsettings.html
+++ b/Docs/Chm/help/v2/dbsettings.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Database Settings - KeePass</title>
 	<base target="_self" />
@@ -50,7 +50,7 @@ settings.</p>
 <ul>
 <li><a href="#general">General</a></li>
 <li><a href="#security">Security Options</a></li>
-<li><a href="#protection">Protection Options</a></li>
+<!-- <li><a href="#protection">Protection Options</a></li> -->
 <li><a href="#compression">Compression Options</a></li>
 <li><a href="#templates">Templates</a></li>
 </ul>
@@ -93,7 +93,7 @@ half the number resulted from the benchmark.</p>
 
 <br />
 
-<a name="protection"></a>
+<!-- <a name="protection"></a>
 <h2 class="sectiontitle">
 <img src="../images/b16x16_file_locked.png" class="singleimg" alt="Info" />  Protection
 Options</h2>
@@ -114,7 +114,7 @@ KeePass offers you to turn on visual hiding in the main window for the selected
 protected fields. It is highly recommended to check this option before closing
 the dialog.</p>
 
-<br />
+<br /> -->
 
 <a name="compression"></a>
 <h2 class="sectiontitle">
diff --git a/Docs/Chm/help/v2/entry.html b/Docs/Chm/help/v2/entry.html
index e8a04d4..47b5b33 100644
--- a/Docs/Chm/help/v2/entry.html
+++ b/Docs/Chm/help/v2/entry.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Entry Dialog - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/guioptions.html b/Docs/Chm/help/v2/guioptions.html
index fb5935d..c0cfc9e 100644
--- a/Docs/Chm/help/v2/guioptions.html
+++ b/Docs/Chm/help/v2/guioptions.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>GUI Options - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/ioconnect.html b/Docs/Chm/help/v2/ioconnect.html
index 9f1d78f..f31e084 100644
--- a/Docs/Chm/help/v2/ioconnect.html
+++ b/Docs/Chm/help/v2/ioconnect.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Loading/Saving From/To URL - KeePass</title>
 	<base target="_self" />
@@ -49,6 +49,10 @@ KeePass can load/save databases from/to URLs.
 but additional protocols might
 be available on your system (if specific providers are installed).</p>
 
+<p>The <a href="http://keepass.info/plugins.html#ioprotocolext"
+target="_blank">IOProtocolExt</a> plugin adds support for
+<b>SCP</b>, <b>SFTP</b> and <b>FTPS</b>.</p>
+
 <br />
 
 <a name="ftp"></a>
diff --git a/Docs/Chm/help/v2/license.html b/Docs/Chm/help/v2/license.html
index 91a25a1..6bb900b 100644
--- a/Docs/Chm/help/v2/license.html
+++ b/Docs/Chm/help/v2/license.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>License - KeePass</title>
 	<base target="_self" />
@@ -45,7 +45,7 @@ class="singleimg" align="left" alt="System" />
 License terms of KeePass 2.x.
 </td></tr></table>
 
-<p>KeePass: Copyright © 2003-2011 Dominik Reichl.</p>
+<p>KeePass: Copyright © 2003-2012 Dominik Reichl.</p>
 
 <p>The program is distributed under the
 terms of the GNU General Public License version 2 or later. The complete
diff --git a/Docs/Chm/help/v2/plugins.html b/Docs/Chm/help/v2/plugins.html
index 34faa31..6dc2056 100644
--- a/Docs/Chm/help/v2/plugins.html
+++ b/Docs/Chm/help/v2/plugins.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Plugins - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/policy.html b/Docs/Chm/help/v2/policy.html
index da9a90b..22d54ef 100644
--- a/Docs/Chm/help/v2/policy.html
+++ b/Docs/Chm/help/v2/policy.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Application Policy - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/setup.html b/Docs/Chm/help/v2/setup.html
index e66313b..086a744 100644
--- a/Docs/Chm/help/v2/setup.html
+++ b/Docs/Chm/help/v2/setup.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Setup - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/sync.html b/Docs/Chm/help/v2/sync.html
index d4d5f58..831c62d 100644
--- a/Docs/Chm/help/v2/sync.html
+++ b/Docs/Chm/help/v2/sync.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Synchronization - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/translation.html b/Docs/Chm/help/v2/translation.html
index 35c4a02..e010b06 100644
--- a/Docs/Chm/help/v2/translation.html
+++ b/Docs/Chm/help/v2/translation.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Translations - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/triggers.html b/Docs/Chm/help/v2/triggers.html
index 0d9612c..9594cd2 100644
--- a/Docs/Chm/help/v2/triggers.html
+++ b/Docs/Chm/help/v2/triggers.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Triggers - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2/version.html b/Docs/Chm/help/v2/version.html
index b1ceb56..33f4433 100644
--- a/Docs/Chm/help/v2/version.html
+++ b/Docs/Chm/help/v2/version.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Compatibility - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2_dev/customize.html b/Docs/Chm/help/v2_dev/customize.html
index 986702b..4990026 100644
--- a/Docs/Chm/help/v2_dev/customize.html
+++ b/Docs/Chm/help/v2_dev/customize.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Customize - KeePass</title>
 	<base target="_self" />
@@ -96,6 +96,8 @@ the following flags:</p>
 <tr><td align="right">0x1</td><td align="right">1</td><td>Disable 'Tools' -> 'Options' menu item.</td></tr>
 <tr><td align="right">0x2</td><td align="right">2</td><td>Disable 'Tools' -> 'Plugins' menu item.</td></tr>
 <tr><td align="right">0x4</td><td align="right">4</td><td>Disable 'Tools' -> 'Triggers' menu item.</td></tr>
+<tr><td align="right">0x8</td><td align="right">8</td><td>Disable controls to specify after how many
+days the master key should/must be changed.</td></tr>
 </table>
 
 <p>For example, if you want to disable the 'Options' and 'Plugins' items in
diff --git a/Docs/Chm/help/v2_dev/plg_index.html b/Docs/Chm/help/v2_dev/plg_index.html
index de610b9..f680139 100644
--- a/Docs/Chm/help/v2_dev/plg_index.html
+++ b/Docs/Chm/help/v2_dev/plg_index.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Plugin Development - KeePass</title>
 	<base target="_self" />
@@ -53,6 +53,7 @@ different from 1.x plugins. 1.x plugins cannot be loaded by KeePass 2.x.</p>
 <li><a href="#tutorial">Step-by-Step Tutorial</a></li>
 <li><a href="#commonops">Common Operations</a></li>
 <li><a href="#conventions">Plugin Conventions</a></li>
+<li><a href="#upd">Update Checking</a></li>
 <li><a href="#unmanagedcpp">Can KeePass 2.x Plugins be written in Unmanaged C++?</a></li>
 <li><a href="#plgx">PLGX Files</a></li>
 </ul>
@@ -289,6 +290,80 @@ For the SecretImporter plugin, this would be <code>SecretImporterExt</code>.</p>
 
 <br />
 
+<a name="upd"></a>
+<h2 class="sectiontitle">
+<img src="../images/b16x16_dataexchange.png" class="singleimg" alt="Exchange" />  Update
+Checking</h2>
+
+<p>The update check of KeePass ≥ 2.18 can also check for plugin updates.
+Update check support is optional; plugins don't have to support update
+checks.</p>
+
+<p>In order to support update checks, plugin developers need to do the following:</p>
+
+<ul>
+<li><b>Provide version information file.</b>
+When an end-user invokes an update check, KeePass downloads a version information
+file, which specifies the current version numbers of one or more plugins.
+Every plugin author hosts an own version information file.
+The format of the version information file is described in detail below.</li>
+<li><b>Let KeePass know.</b>
+In order to be able to check the plugin's version, KeePass must know where
+your version information file is located. To let KeePass know,
+override the <code>UpdateUrl</code> string property of your plugin class
+(the one derived from <code>Plugin</code>)
+to return the full, absolute URL of your version information file.
+This should be an <code>http://</code> URL, but an <code>ftp://</code> URL
+is also acceptable.</li>
+</ul>
+
+<p>Plugin developers have to update their version information file each time
+they release new versions of their plugins.</p>
+
+<p><b>Version information file format.</b></p>
+<ul>
+<li>The file is a simple text file. It must be encoded using UTF-8 without
+byte order marks (BOM). All line endings are supported.</li>
+<li>The first line of the file must start with a separator character of
+your choice. The separator character may be any character,
+but it must not appear within plugin names and versions.
+Suggested is '<code>:</code>'.</li>
+<li>Each of the following lines specifies a plugin name and its currently
+available version, separated by the separator character that was specified in
+the header line.</li>
+<li>As plugin name, the value of the 'Title' field in the version information
+block of the plugin must be specified.
+For managed plugins, this is the value specified using the
+<code>AssemblyTitle</code> assembly attribute.</li>
+<li>As version number, the value of the file version in the version information
+block of the plugin must be specified.
+For managed plugins, this is the value specified using the
+<code>AssemblyFileVersion</code> assembly attribute.
+Trailing <code>.0</code> may be removed
+(e.g. specify <code>1.3</code> instead of <code>1.3.0.0</code>).</li>
+<li>The file must end with a line containing only the separator character.</li>
+<li>You may optionally compress your version information file using GZip
+(note this is not the same as Zip). The file
+name must then end with "<code>.gz</code>".</li>
+</ul>
+
+<p>Example. Let's assume you're developing two plugins: <em>MyPlugin1</em>
+(version 1.5) and <em>MyPlugin2</em> (version 1.13.2.17). Then your version
+information file could look as follows:</p>
+<pre>:
+MyPlugin1:1.5
+MyPlugin2:1.13.2.17
+:</pre>
+
+<p>If you've developed multiple plugins, it is recommended to create one
+version information file, list all your plugins in this file and specify
+the URL of the file in all your plugins. When KeePass checks for updates,
+it'll download your version information file only once.
+This reduces network traffic and is faster than downloading a version information
+file for every plugin separately.</p>
+
+<br />
+
 <a name="unmanagedcpp"></a>
 <h2 class="sectiontitle">
 <img src="../images/b16x16_help.png" class="singleimg" alt="Info" />  Can
diff --git a/Docs/Chm/help/v2_dev/scr_index.html b/Docs/Chm/help/v2_dev/scr_index.html
index aeb0f80..f248dd2 100644
--- a/Docs/Chm/help/v2_dev/scr_index.html
+++ b/Docs/Chm/help/v2_dev/scr_index.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Scripting Introduction - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2_dev/scr_kps_index.html b/Docs/Chm/help/v2_dev/scr_kps_index.html
index 822d549..384392b 100644
--- a/Docs/Chm/help/v2_dev/scr_kps_index.html
+++ b/Docs/Chm/help/v2_dev/scr_kps_index.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>KPS Script Files - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/Chm/help/v2_dev/scr_sc_index.html b/Docs/Chm/help/v2_dev/scr_sc_index.html
index 6e2478a..51c0610 100644
--- a/Docs/Chm/help/v2_dev/scr_sc_index.html
+++ b/Docs/Chm/help/v2_dev/scr_sc_index.html
@@ -25,7 +25,7 @@
 	<meta name="DC.Format" content="text/html" />
 	<meta name="DC.Identifier" content="http://keepass.info/" />
 	<meta name="DC.Language" content="en" />
-	<meta name="DC.Rights" content="Copyright (c) 2003-2011 Dominik Reichl" />
+	<meta name="DC.Rights" content="Copyright (c) 2003-2012 Dominik Reichl" />
 
 	<title>Single Command Operations - KeePass</title>
 	<base target="_self" />
diff --git a/Docs/History.txt b/Docs/History.txt
index b2532d4..213a2ae 100644
--- a/Docs/History.txt
+++ b/Docs/History.txt
@@ -1,3 +1,88 @@
+2012-01-05: 2.18
+- The update check now also checks for plugin updates (if
+  plugin developers provide version information files)
+- When starting KeePass 2.18 for the first time, it asks
+  whether to enable the automatic update check or not (if not
+  enabled already)
+- When closing the entry editing dialog by closing the window
+  (using [X], Esc, ...) and there are unsaved changes, KeePass
+  now asks whether to save or discard the changes; only when
+  explicitly clicking the 'Cancel' button, KeePass doesn't
+  prompt
+- When not hiding passwords using asterisks, they don't need to
+  be repeated anymore
+- Password repetition boxes now provide instant visual feedback
+  whether the password has been repeated correctly (if
+  incorrect, the background color is changed to light red)
+- When clicking an '***' button to change the visibility of the
+  entered password, KeePass now automatically transfers the
+  input focus into the password box
+- Visibility of columns in the auto-type entry selection dialog
+  can now be customized using the new 'Options' button
+- Added auto-type option 'An entry matches if the host
+  component of its URL is contained in the target window title'
+- Added shortcut keys: Ctrl+Shift+O for 'Open URL',
+  Ctrl+Shift+U for copying URLs to the clipboard, Ctrl+I for
+  'Add Entry', Ctrl+R for synchronizing with a file,
+  Ctrl+Shift+R for synchronizing with a URL
+- Ensuring same keyboard layouts during auto-type is now
+  optional (option enabled by default)
+- Plain text KDB4 XML exports now store the memory protection
+  flag of strings in an attribute 'ProtectInMemory'
+- Added option to use database lock files (intended for storage
+  providers that don't lock files while writing to them, like
+  e.g. some FTP servers); the option is turned off by default
+  (and especially for local files and files on a network share
+  it's recommended to leave it turned off)
+- Added UIFlags bit for disabling the controls to specify after
+  how many days the master key should/must be changed
+- Added support for in-memory protecting strings that are
+  longer than 65536 characters
+- Added workaround for '@' .NET SendKeys issue
+
+- .NET 4.0 is now preferred, if installed
+- PLGX plugins are now preferably compiled using the .NET 4.0
+  compiler, if KeePass is currently running under the 4.0 CLR
+- Automatic update checks are now performed at maximum once per
+  day (you can still check manually as often as you wish)
+- Auto-Type: entry titles and URLs are now Spr-compiled before
+  being compared with the target window title
+- Decoupled the options 'Show expired entries' and 'Show
+  entries that will expire soon'
+- Specifying the data hiding setting (using asterisks) in the
+  column configuration dialog is now done using a checkbox
+- The entry view now preferably uses the hiding settings
+  (asterisks) of the entry list columns
+- Improved entry expiry date calculation
+- Enhanced Password Agent importer to support version 2.6.2
+- Enhanced SplashID importer to import last modification dates
+- Improved locating of system executables
+- Password generator profiles are now sorted by name
+- Separated built-in and user-defined password generator
+  profiles (built-in profiles aren't stored in the
+  configuration file anymore)
+- Improved naming of shortcut keys, and shortcut keys are now
+  displayed in tooltips
+- Internal window manager can now close windows opened in other
+  threads
+- Improved entry touching when closing the entry editing dialog
+  by closing the window (using [X], Esc, ...)
+- Improved behavior when entering an invalid URL in the 'Open
+  URL' dialog
+- Improved workaround for Mono tab bar height bug
+- ShInstUtil: improved Native Image Generator version detection
+- Unified in-memory protection
+- In-memory protection performance improvements
+- Developers: in-memory protected objects are now immutable and
+  thread-safe
+- Various UI text improvements
+- Various code optimizations
+- Minor other improvements
+
+- The cached/temporary custom icons image list is now updated
+  correctly after running the 'Delete unused custom icons'
+  command
+
 2011-10-19: 2.17
 - Multiple auto-type sequences can now be defined for a window
   in one entry
diff --git a/Docs/License.txt b/Docs/License.txt
index 0a80642..714b1fd 100644
--- a/Docs/License.txt
+++ b/Docs/License.txt
@@ -1,4 +1,4 @@
-KeePass: Copyright (c) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>.
+KeePass: Copyright (c) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>.
 
 The software is distributed under the terms of the GNU General Public
 License version 2 or later.
diff --git a/Docs/License_Install.txt b/Docs/License_Install.txt
index 18be2cc..b97b53f 100644
--- a/Docs/License_Install.txt
+++ b/Docs/License_Install.txt
@@ -1,4 +1,4 @@
-KeePass: Copyright (c) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>.
+KeePass: Copyright (c) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>.
 
 The software is distributed under the terms of the GNU General Public
 License version 2 or later.
diff --git a/KeePassLib/Security/ProtectedString.cs b/Ext/DeprecatedSources/ProtectedString_111029.cs
similarity index 96%
copy from KeePassLib/Security/ProtectedString.cs
copy to Ext/DeprecatedSources/ProtectedString_111029.cs
index 2cee9b6..e37fd06 100644
--- a/KeePassLib/Security/ProtectedString.cs
+++ b/Ext/DeprecatedSources/ProtectedString_111029.cs
@@ -35,7 +35,7 @@ namespace KeePassLib.Security
 	/// <summary>
 	/// Represents an in-memory encrypted string.
 	/// </summary>
-#if !KeePassLibSD
+#if (DEBUG && !KeePassLibSD)
 	[DebuggerDisplay(@"{ReadString()}")]
 #endif
 	public sealed class ProtectedString
diff --git a/KeePass/Util/CheckForUpdate.cs b/Ext/DeprecatedSources/UpdateCheck_111216.cs
similarity index 88%
rename from KeePass/Util/CheckForUpdate.cs
rename to Ext/DeprecatedSources/UpdateCheck_111216.cs
index 6fc78f6..aaae237 100644
--- a/KeePass/Util/CheckForUpdate.cs
+++ b/Ext/DeprecatedSources/UpdateCheck_111216.cs
@@ -37,7 +37,7 @@ using KeePassLib.Utility;
 
 namespace KeePass.Util
 {
-	public static class CheckForUpdate
+	/* public static class UpdateCheck
 	{
 		private const string ElemRoot = "KeePass";
 
@@ -53,7 +53,7 @@ namespace KeePass.Util
 			m_tsResultsViewer = tsResultsViewer;
 
 			// Local, but thread will continue to run anyway
-			Thread th = new Thread(new ThreadStart(CheckForUpdate.OnStartCheck));
+			Thread th = new Thread(new ThreadStart(UpdateCheck.OnStartCheck));
 			th.Start();
 		}
 
@@ -98,7 +98,7 @@ namespace KeePass.Util
 					if(m_tsResultsViewer == null)
 						MessageService.ShowWarning(KPRes.UpdateCheckingFailed, e.Error);
 					else if(e.Error.Message != null)
-						CheckForUpdate.SetTsStatus(KPRes.UpdateCheckingFailed + " " +
+						UpdateCheck.SetTsStatus(KPRes.UpdateCheckingFailed + " " +
 							e.Error.Message);
 				}
 				else ReportStatusEx(KPRes.UpdateCheckingFailed, true);
@@ -141,7 +141,7 @@ namespace KeePass.Util
 						WinUtil.OpenUrl(PwDefs.HomepageUrl, null);
 					}
 				}
-				else CheckForUpdate.SetTsStatus(KPRes.ChkForUpdNewVersion);
+				else UpdateCheck.SetTsStatus(KPRes.ChkForUpdNewVersion);
 			}
 			else if(uVersion == PwDefs.Version32)
 				ReportStatusEx(KPRes.ChkForUpdGotLatest, false);
@@ -162,7 +162,7 @@ namespace KeePass.Util
 				if(bIsWarning) MessageService.ShowWarning(strLongText);
 				else MessageService.ShowInfo(strLongText);
 			}
-			else CheckForUpdate.SetTsStatus(strShortText);
+			else UpdateCheck.SetTsStatus(strShortText);
 		}
 
 		private static void StructureFail()
@@ -172,7 +172,7 @@ namespace KeePass.Util
 			if(m_tsResultsViewer == null)
 				MessageService.ShowWarning(KPRes.InvalidFileStructure);
 			else
-				CheckForUpdate.SetTsStatus(KPRes.ChkForUpdGotLatest + " " +
+				UpdateCheck.SetTsStatus(KPRes.ChkForUpdGotLatest + " " +
 					KPRes.InvalidFileStructure);
 		}
 
@@ -186,10 +186,10 @@ namespace KeePass.Util
 				ToolStrip pParent = m_tsResultsViewer.Owner;
 				if((pParent != null) && pParent.InvokeRequired)
 				{
-					pParent.Invoke(new Priv_CfuSsd(CheckForUpdate.SetTsStatusDirect),
+					pParent.Invoke(new Priv_CfuSsd(UpdateCheck.SetTsStatusDirect),
 						new object[] { strText });
 				}
-				else CheckForUpdate.SetTsStatusDirect(strText);
+				else UpdateCheck.SetTsStatusDirect(strText);
 			}
 			catch(Exception) { Debug.Assert(false); }
 		}
@@ -201,5 +201,5 @@ namespace KeePass.Util
 			try { m_tsResultsViewer.Text = strText; }
 			catch(Exception) { Debug.Assert(false); }
 		}
-	}
+	} */
 }
diff --git a/KeePassLib/Security/XorredBuffer.cs b/Ext/DeprecatedSources/XorredBuffer_111029.cs
similarity index 100%
copy from KeePassLib/Security/XorredBuffer.cs
copy to Ext/DeprecatedSources/XorredBuffer_111029.cs
diff --git a/Ext/KeePass.exe.config b/Ext/KeePass.exe.config
index 193ac9d..62795ed 100644
--- a/Ext/KeePass.exe.config
+++ b/Ext/KeePass.exe.config
@@ -1,7 +1,7 @@
 <configuration>
 	<startup>
-		<supportedRuntime version="v2.0.50727" />
 		<supportedRuntime version="v4.0" />
+		<supportedRuntime version="v2.0.50727" />
 	</startup>
 	<runtime>
 		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
@@ -9,8 +9,8 @@
 				<assemblyIdentity name="KeePass"
 					publicKeyToken="fed2ed7716aecf5c"
 					culture="neutral" />
-				<bindingRedirect oldVersion="2.0.9.0-2.1.7.0"
-					newVersion="2.1.7.16602" />
+				<bindingRedirect oldVersion="2.0.9.0-2.1.8.0"
+					newVersion="2.1.8.18961" />
 			</dependentAssembly>
 		</assemblyBinding>
 		<enforceFIPSPolicy enabled="false" />
diff --git a/Ext/KeePass.iss b/Ext/KeePass.iss
index 096aa3f..1ceb617 100644
--- a/Ext/KeePass.iss
+++ b/Ext/KeePass.iss
@@ -8,16 +8,16 @@
 #define MyAppNameEx "KeePass Password Safe 2"
 #define MyAppPublisher "Dominik Reichl"
 
-#define KeeVersionStr "2.17"
-#define KeeVersionStrWithMinor "2.17"
-#define KeeVersionStrWithMinorPath "2.17"
-#define KeeVersionWin "2.1.7.0"
+#define KeeVersionStr "2.18"
+#define KeeVersionStrWithMinor "2.18"
+#define KeeVersionStrWithMinorPath "2.18"
+#define KeeVersionWin "2.1.8.0"
 
 #define MyAppURL "http://keepass.info/"
 #define MyAppExeName "KeePass.exe"
 #define MyAppUrlName "KeePass.url"
 #define MyAppHelpName "KeePass.chm"
-#define KeeDevPeriod "2003-2011"
+#define KeeDevPeriod "2003-2012"
 #define MyAppId "KeePassPasswordSafe2"
 
 [Setup]
diff --git a/Ext/KeePassMsi/KeePassMsi.vdproj b/Ext/KeePassMsi/KeePassMsi.vdproj
index 2e8aa44..c7521a6 100644
--- a/Ext/KeePassMsi/KeePassMsi.vdproj
+++ b/Ext/KeePassMsi/KeePassMsi.vdproj
@@ -118,7 +118,7 @@
         "Entry"
         {
         "MsmKey" = "8:_UNDEFINED"
-        "OwnerKey" = "8:_8C05ADB649434D7892E36709EBDED4CC"
+        "OwnerKey" = "8:_838987B3C51D42C3C7B9BDA1339A5500"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
@@ -130,7 +130,7 @@
         "Entry"
         {
         "MsmKey" = "8:_UNDEFINED"
-        "OwnerKey" = "8:_838987B3C51D42C3C7B9BDA1339A5500"
+        "OwnerKey" = "8:_8C05ADB649434D7892E36709EBDED4CC"
         "MsmSig" = "8:_UNDEFINED"
         }
     }
@@ -382,7 +382,7 @@
             {
             "AssemblyRegister" = "3:1"
             "AssemblyIsInGAC" = "11:FALSE"
-            "AssemblyAsmDisplayName" = "8:KeePass, Version=2.1.7.16602, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL"
+            "AssemblyAsmDisplayName" = "8:KeePass, Version=2.1.8.18961, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL"
                 "ScatterAssemblies"
                 {
                     "_838987B3C51D42C3C7B9BDA1339A5500"
@@ -413,7 +413,7 @@
             {
             "AssemblyRegister" = "3:1"
             "AssemblyIsInGAC" = "11:FALSE"
-            "AssemblyAsmDisplayName" = "8:KeePass.XmlSerializers, Version=2.1.7.16602, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL"
+            "AssemblyAsmDisplayName" = "8:KeePass.XmlSerializers, Version=2.1.8.18961, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL"
                 "ScatterAssemblies"
                 {
                     "_8C05ADB649434D7892E36709EBDED4CC"
@@ -564,7 +564,7 @@
             {
             "AssemblyRegister" = "3:1"
             "AssemblyIsInGAC" = "11:FALSE"
-            "AssemblyAsmDisplayName" = "8:KeePass, Version=2.1.7.16602, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL"
+            "AssemblyAsmDisplayName" = "8:KeePass, Version=2.1.8.18961, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL"
                 "ScatterAssemblies"
                 {
                     "_C4F8814F844C43EE8C9F5B662182B11A"
@@ -712,14 +712,14 @@
         {
         "Name" = "8:Microsoft Visual Studio"
         "ProductName" = "8:KeePass"
-        "ProductCode" = "8:{B9112CDC-2DA7-44FA-B806-D3F4525F0E89}"
-        "PackageCode" = "8:{271FAC71-F54F-41AA-BC48-755858A2027C}"
+        "ProductCode" = "8:{3560D137-75F3-4E06-BE84-FB80CABF40AC}"
+        "PackageCode" = "8:{38E032C9-1409-4F5F-BF01-43B99210854B}"
         "UpgradeCode" = "8:{F2F19898-4F86-4940-9BFA-426574CE03E1}"
         "RestartWWWService" = "11:FALSE"
         "RemovePreviousVersions" = "11:TRUE"
         "DetectNewerInstalledVersion" = "11:TRUE"
         "InstallAllUsers" = "11:TRUE"
-        "ProductVersion" = "8:2.1.7"
+        "ProductVersion" = "8:2.1.8"
         "Manufacturer" = "8:Dominik Reichl"
         "ARPHELPTELEPHONE" = "8:"
         "ARPHELPLINK" = "8:http://keepass.info/"
@@ -954,7 +954,7 @@
                             "ContextData" = "8:"
                             "Attributes" = "3:0"
                             "Setting" = "3:2"
-                            "Value" = "8:KeePass: Copyright (c) 2003-2011 Dominik Reichl. The software is distributed under the terms of the GNU General Public License version 2 or later."
+                            "Value" = "8:KeePass: Copyright (c) 2003-2012 Dominik Reichl. The software is distributed under the terms of the GNU General Public License version 2 or later."
                             "DefaultValue" = "8:#1202"
                             "UsePlugInResources" = "11:TRUE"
                             }
@@ -1077,7 +1077,7 @@
                             "ContextData" = "8:"
                             "Attributes" = "3:0"
                             "Setting" = "3:2"
-                            "Value" = "8:KeePass: Copyright (c) 2003-2011 Dominik Reichl. The software is distributed under the terms of the GNU General Public License version 2 or later."
+                            "Value" = "8:KeePass: Copyright (c) 2003-2012 Dominik Reichl. The software is distributed under the terms of the GNU General Public License version 2 or later."
                             "DefaultValue" = "8:#1202"
                             "UsePlugInResources" = "11:TRUE"
                             }
diff --git a/KeePass/App/AppDefs.cs b/KeePass/App/AppDefs.cs
index ba9ed48..cac2e4d 100644
--- a/KeePass/App/AppDefs.cs
+++ b/KeePass/App/AppDefs.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -66,7 +66,7 @@ namespace KeePass.App
 			public const string DatabaseSettings = "v2/dbsettings";
 			public const string DbSettingsGeneral = "general";
 			public const string DbSettingsSecurity = "security";
-			public const string DbSettingsProtection = "protection";
+			// public const string DbSettingsProtection = "protection";
 			public const string DbSettingsCompression = "compression";
 
 			public const string AutoType = "base/autotype";
@@ -100,8 +100,8 @@ namespace KeePass.App
 			public const string Setup = "v2/setup";
 			public const string SetupMono = "mono";
 
-			public const string FaqTech = "base/faq_tech";
-			public const string FaqTechMemProt = "memprot";
+			// public const string FaqTech = "base/faq_tech";
+			// public const string FaqTechMemProt = "memprot";
 		}
 
 		public static class CommandLineOptions
diff --git a/KeePass/App/AppHelp.cs b/KeePass/App/AppHelp.cs
index 335eb71..e9292b9 100644
--- a/KeePass/App/AppHelp.cs
+++ b/KeePass/App/AppHelp.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -131,7 +131,7 @@ namespace KeePass.App
 
 			strCmd += "\"";
 
-			try { Process.Start("hh.exe", strCmd); }
+			try { Process.Start(WinUtil.LocateSystemApp("hh.exe"), strCmd); }
 			catch(Exception exStart)
 			{
 				MessageService.ShowWarning(@"hh.exe " + strCmd, exStart);
diff --git a/KeePass/App/AppPolicy.cs b/KeePass/App/AppPolicy.cs
index 0208f78..d751860 100644
--- a/KeePass/App/AppPolicy.cs
+++ b/KeePass/App/AppPolicy.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceApplication.cs b/KeePass/App/Configuration/AceApplication.cs
index 140a0b4..8f5757c 100644
--- a/KeePass/App/Configuration/AceApplication.cs
+++ b/KeePass/App/Configuration/AceApplication.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -55,6 +55,19 @@ namespace KeePass.App.Configuration
 			set { m_bHelpUseLocal = value; }
 		}
 
+		// Serialize DateTime with TimeUtil
+		private string m_strLastUpdChk = string.Empty;
+		[DefaultValue("")]
+		public string LastUpdateCheck
+		{
+			get { return m_strLastUpdChk; }
+			set
+			{
+				if(value == null) throw new ArgumentNullException("value");
+				m_strLastUpdChk = value;
+			}
+		}
+
 		private IOConnectionInfo m_ioLastDb = new IOConnectionInfo();
 		public IOConnectionInfo LastUsedFile
 		{
@@ -115,6 +128,14 @@ namespace KeePass.App.Configuration
 			set { m_bTransactedWrites = value; }
 		}
 
+		private bool m_bFileLocks = false;
+		[DefaultValue(false)]
+		public bool UseFileLocks
+		{
+			get { return m_bFileLocks; }
+			set { m_bFileLocks = value; }
+		}
+
 		private AceCloseDb m_fc = new AceCloseDb();
 		public AceCloseDb FileClosing
 		{
@@ -165,13 +186,21 @@ namespace KeePass.App.Configuration
 		}
 
 		private bool m_bCheckForUpdate = false;
-		[DefaultValue(false)]
+		// [DefaultValue(false)] // Avoid user confusion with 'Configured' setting
 		public bool CheckForUpdate
 		{
 			get { return m_bCheckForUpdate; }
 			set { m_bCheckForUpdate = value; }
 		}
 
+		private bool m_bCheckForUpdateCfg = false;
+		[DefaultValue(false)]
+		public bool CheckForUpdateConfigured
+		{
+			get { return m_bCheckForUpdateCfg; }
+			set { m_bCheckForUpdateCfg = value; }
+		}
+
 		private bool m_bMinimizedAndLocked = false;
 		[DefaultValue(false)]
 		public bool MinimizedAndLocked
diff --git a/KeePass/App/Configuration/AceCustomConfig.cs b/KeePass/App/Configuration/AceCustomConfig.cs
index 86b5e37..5ddf01e 100644
--- a/KeePass/App/Configuration/AceCustomConfig.cs
+++ b/KeePass/App/Configuration/AceCustomConfig.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceDefaults.cs b/KeePass/App/Configuration/AceDefaults.cs
index 8d706c4..7c1c448 100644
--- a/KeePass/App/Configuration/AceDefaults.cs
+++ b/KeePass/App/Configuration/AceDefaults.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceIntegration.cs b/KeePass/App/Configuration/AceIntegration.cs
index cb108c6..e92e395 100644
--- a/KeePass/App/Configuration/AceIntegration.cs
+++ b/KeePass/App/Configuration/AceIntegration.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -124,6 +124,14 @@ namespace KeePass.App.Configuration
 			set { m_bMatchByUrlInTitle = value; }
 		}
 
+		private bool m_bMatchByUrlHostInTitle = false;
+		[DefaultValue(false)]
+		public bool AutoTypeMatchByUrlHostInTitle
+		{
+			get { return m_bMatchByUrlHostInTitle; }
+			set { m_bMatchByUrlHostInTitle = value; }
+		}
+
 		private bool m_bPrependInitSeqIE = true;
 		[DefaultValue(true)]
 		public bool AutoTypePrependInitSequenceForIE
@@ -140,6 +148,14 @@ namespace KeePass.App.Configuration
 			set { m_bSpecialReleaseAlt = value; }
 		}
 
+		private bool m_bAdjustKeybLayout = true;
+		[DefaultValue(true)]
+		public bool AutoTypeAdjustKeyboardLayout
+		{
+			get { return m_bAdjustKeybLayout; }
+			set { m_bAdjustKeybLayout = value; }
+		}
+
 		private bool m_bCancelOnWindowChange = false;
 		[DefaultValue(false)]
 		public bool AutoTypeCancelOnWindowChange
diff --git a/KeePass/App/Configuration/AceLogging.cs b/KeePass/App/Configuration/AceLogging.cs
index bcd8479..929b611 100644
--- a/KeePass/App/Configuration/AceLogging.cs
+++ b/KeePass/App/Configuration/AceLogging.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceMainWindow.cs b/KeePass/App/Configuration/AceMainWindow.cs
index 34e2b58..9b78385 100644
--- a/KeePass/App/Configuration/AceMainWindow.cs
+++ b/KeePass/App/Configuration/AceMainWindow.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -26,11 +26,12 @@ using System.Xml.Serialization;
 using System.ComponentModel;
 using System.Diagnostics;
 
-using KeePassLib;
-
 using KeePass.Resources;
 using KeePass.UI;
 
+using KeePassLib;
+using KeePassLib.Security;
+
 namespace KeePass.App.Configuration
 {
 	public enum AceMainWindowLayout
@@ -364,6 +365,11 @@ namespace KeePass.App.Configuration
 			return null;
 		}
 
+		public bool IsColumnHidden(AceColumnType t)
+		{
+			return IsColumnHidden(t, (t == AceColumnType.Password));
+		}
+
 		public bool IsColumnHidden(AceColumnType t, bool bDefault)
 		{
 			foreach(AceColumn c in m_aceColumns)
@@ -373,6 +379,19 @@ namespace KeePass.App.Configuration
 
 			return bDefault;
 		}
+
+		public bool ShouldHideCustomString(string strCustomName,
+			ProtectedString psValue)
+		{
+			foreach(AceColumn c in m_aceColumns)
+			{
+				if((c.Type == AceColumnType.CustomString) &&
+					(c.CustomName == strCustomName))
+					return c.HideWithAsterisks;
+			}
+			if(psValue != null) return psValue.IsProtected;
+			return false;
+		}
 	}
 
 	public sealed class AceEntryView
@@ -389,13 +408,13 @@ namespace KeePass.App.Configuration
 			set { m_bShow = value; }
 		}
 
-		private bool m_bHideProtectedCustomStrings = true;
-		[DefaultValue(true)]
-		public bool HideProtectedCustomStrings
-		{
-			get { return m_bHideProtectedCustomStrings; }
-			set { m_bHideProtectedCustomStrings = value; }
-		}
+		// private bool m_bHideProtectedCustomStrings = true;
+		// [DefaultValue(true)]
+		// public bool HideProtectedCustomStrings
+		// {
+		//	get { return m_bHideProtectedCustomStrings; }
+		//	set { m_bHideProtectedCustomStrings = value; }
+		// }
 	}
 
 	public sealed class AceTanView
diff --git a/KeePass/App/Configuration/AceNative.cs b/KeePass/App/Configuration/AceNative.cs
index cb31272..80ce107 100644
--- a/KeePass/App/Configuration/AceNative.cs
+++ b/KeePass/App/Configuration/AceNative.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AcePasswordGenerator.cs b/KeePass/App/Configuration/AcePasswordGenerator.cs
index 0b48030..6a00da5 100644
--- a/KeePass/App/Configuration/AcePasswordGenerator.cs
+++ b/KeePass/App/Configuration/AcePasswordGenerator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceSecurity.cs b/KeePass/App/Configuration/AceSecurity.cs
index 1817531..1797d03 100644
--- a/KeePass/App/Configuration/AceSecurity.cs
+++ b/KeePass/App/Configuration/AceSecurity.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceToolBar.cs b/KeePass/App/Configuration/AceToolBar.cs
index 1c6d753..2ed69af 100644
--- a/KeePass/App/Configuration/AceToolBar.cs
+++ b/KeePass/App/Configuration/AceToolBar.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceTrayIcon.cs b/KeePass/App/Configuration/AceTrayIcon.cs
index f0b7917..9f28d34 100644
--- a/KeePass/App/Configuration/AceTrayIcon.cs
+++ b/KeePass/App/Configuration/AceTrayIcon.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AceUI.cs b/KeePass/App/Configuration/AceUI.cs
index 8eaef5c..3ef27a7 100644
--- a/KeePass/App/Configuration/AceUI.cs
+++ b/KeePass/App/Configuration/AceUI.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -56,7 +56,23 @@ namespace KeePass.App.Configuration
 		None = 0,
 		DisableOptions = 0x1,
 		DisablePlugins = 0x2,
-		DisableTriggers = 0x4
+		DisableTriggers = 0x4,
+		DisableKeyChangeDays = 0x8
+	}
+
+	[Flags]
+	public enum AceAutoTypeCtxFlags : long
+	{
+		None = 0,
+
+		ColTitle = 0x1,
+		ColUserName = 0x2,
+		ColPassword = 0x4,
+		ColUrl = 0x8,
+		ColNotes = 0x10,
+		ColSequence = 0x20,
+
+		Default = (ColTitle | ColUserName | ColUrl | ColSequence)
 	}
 
 	public sealed class AceUI
@@ -211,6 +227,14 @@ namespace KeePass.App.Configuration
 			}
 		}
 
+		private long m_lAutoTypeCtxFlags = (long)AceAutoTypeCtxFlags.Default;
+		[DefaultValue((long)AceAutoTypeCtxFlags.Default)]
+		public long AutoTypeCtxFlags
+		{
+			get { return m_lAutoTypeCtxFlags; }
+			set { m_lAutoTypeCtxFlags = value; }
+		}
+
 		private string m_strAutoTypeCtxColWidths = string.Empty;
 		[DefaultValue("")]
 		public string AutoTypeCtxColumnWidths
diff --git a/KeePass/App/Configuration/AppConfigEx.cs b/KeePass/App/Configuration/AppConfigEx.cs
index 778ab2d..e53fe2c 100644
--- a/KeePass/App/Configuration/AppConfigEx.cs
+++ b/KeePass/App/Configuration/AppConfigEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/App/Configuration/AppConfigSerializer.cs b/KeePass/App/Configuration/AppConfigSerializer.cs
index 62f58fe..b59861e 100644
--- a/KeePass/App/Configuration/AppConfigSerializer.cs
+++ b/KeePass/App/Configuration/AppConfigSerializer.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -217,6 +217,9 @@ namespace KeePass.App.Configuration
 					MemoryStream msRead = new MemoryStream(msAsm.ToArray(), false);
 
 					tConfig = (AppConfigEx)xmlSerial.Deserialize(msRead);
+
+					msRead.Close();
+					msAsm.Close();
 				}
 				catch(FileNotFoundException) { }
 				catch(Exception) { Debug.Assert(false); }
@@ -252,9 +255,12 @@ namespace KeePass.App.Configuration
 						MemoryStream msEnf = new MemoryStream();
 						xdEnforced.Save(msEnf);
 						MemoryStream msRead = new MemoryStream(msEnf.ToArray(), false);
-						
+
 						AppConfigEx cfgEnf = (AppConfigEx)xmlSerial.Deserialize(msRead);
 						cfgEnf.OnLoad();
+
+						msRead.Close();
+						msEnf.Close();
 						return cfgEnf;
 					}
 					catch(Exception) { Debug.Assert(false); }
diff --git a/KeePass/DataExchange/CsvStreamReader.cs b/KeePass/DataExchange/CsvStreamReader.cs
index a118c5f..b0de60b 100644
--- a/KeePass/DataExchange/CsvStreamReader.cs
+++ b/KeePass/DataExchange/CsvStreamReader.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/ExportUtil.cs b/KeePass/DataExchange/ExportUtil.cs
index 6353c49..a466c6b 100644
--- a/KeePass/DataExchange/ExportUtil.cs
+++ b/KeePass/DataExchange/ExportUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/FileFormatPool.cs b/KeePass/DataExchange/FileFormatPool.cs
index 9f999de..1ee310a 100644
--- a/KeePass/DataExchange/FileFormatPool.cs
+++ b/KeePass/DataExchange/FileFormatPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/FileFormatProvider.cs b/KeePass/DataExchange/FileFormatProvider.cs
index ab94805..0eaae9b 100644
--- a/KeePass/DataExchange/FileFormatProvider.cs
+++ b/KeePass/DataExchange/FileFormatProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/AmpXml250.cs b/KeePass/DataExchange/Formats/AmpXml250.cs
index 314549d..0170fe5 100644
--- a/KeePass/DataExchange/Formats/AmpXml250.cs
+++ b/KeePass/DataExchange/Formats/AmpXml250.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/AnyPwCsv144.cs b/KeePass/DataExchange/Formats/AnyPwCsv144.cs
index c14dd7f..5f50b66 100644
--- a/KeePass/DataExchange/Formats/AnyPwCsv144.cs
+++ b/KeePass/DataExchange/Formats/AnyPwCsv144.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/CodeWalletTxt605.cs b/KeePass/DataExchange/Formats/CodeWalletTxt605.cs
index be8120f..63ca1f9 100644
--- a/KeePass/DataExchange/Formats/CodeWalletTxt605.cs
+++ b/KeePass/DataExchange/Formats/CodeWalletTxt605.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/DataVaultCsv47.cs b/KeePass/DataExchange/Formats/DataVaultCsv47.cs
index 7ea0fab..873c01a 100644
--- a/KeePass/DataExchange/Formats/DataVaultCsv47.cs
+++ b/KeePass/DataExchange/Formats/DataVaultCsv47.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/FlexWalletXml17.cs b/KeePass/DataExchange/Formats/FlexWalletXml17.cs
index 97d3d36..7238407 100644
--- a/KeePass/DataExchange/Formats/FlexWalletXml17.cs
+++ b/KeePass/DataExchange/Formats/FlexWalletXml17.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/GenericCsv.cs b/KeePass/DataExchange/Formats/GenericCsv.cs
index 1c48d05..06f3dec 100644
--- a/KeePass/DataExchange/Formats/GenericCsv.cs
+++ b/KeePass/DataExchange/Formats/GenericCsv.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/HandySafeProXml12.cs b/KeePass/DataExchange/Formats/HandySafeProXml12.cs
index b7156ce..ab73a88 100644
--- a/KeePass/DataExchange/Formats/HandySafeProXml12.cs
+++ b/KeePass/DataExchange/Formats/HandySafeProXml12.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/HandySafeTxt512.cs b/KeePass/DataExchange/Formats/HandySafeTxt512.cs
index 21338d6..bdf71ea 100644
--- a/KeePass/DataExchange/Formats/HandySafeTxt512.cs
+++ b/KeePass/DataExchange/Formats/HandySafeTxt512.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KasperskyPwMgrXml50.cs b/KeePass/DataExchange/Formats/KasperskyPwMgrXml50.cs
index 3ad05a5..1c75d89 100644
--- a/KeePass/DataExchange/Formats/KasperskyPwMgrXml50.cs
+++ b/KeePass/DataExchange/Formats/KasperskyPwMgrXml50.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassCsv1x.cs b/KeePass/DataExchange/Formats/KeePassCsv1x.cs
index 4033eb2..1cbde91 100644
--- a/KeePass/DataExchange/Formats/KeePassCsv1x.cs
+++ b/KeePass/DataExchange/Formats/KeePassCsv1x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassHtml2x.cs b/KeePass/DataExchange/Formats/KeePassHtml2x.cs
index 821e625..8a106db 100644
--- a/KeePass/DataExchange/Formats/KeePassHtml2x.cs
+++ b/KeePass/DataExchange/Formats/KeePassHtml2x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassKdb1x.cs b/KeePass/DataExchange/Formats/KeePassKdb1x.cs
index 0e97119..de1f642 100644
--- a/KeePass/DataExchange/Formats/KeePassKdb1x.cs
+++ b/KeePass/DataExchange/Formats/KeePassKdb1x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassKdb2x.cs b/KeePass/DataExchange/Formats/KeePassKdb2x.cs
index aa9434a..cc944f2 100644
--- a/KeePass/DataExchange/Formats/KeePassKdb2x.cs
+++ b/KeePass/DataExchange/Formats/KeePassKdb2x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassKdb2xRepair.cs b/KeePass/DataExchange/Formats/KeePassKdb2xRepair.cs
index 1294cfd..b5380bd 100644
--- a/KeePass/DataExchange/Formats/KeePassKdb2xRepair.cs
+++ b/KeePass/DataExchange/Formats/KeePassKdb2xRepair.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassXXml041.cs b/KeePass/DataExchange/Formats/KeePassXXml041.cs
index e857549..0889ecd 100644
--- a/KeePass/DataExchange/Formats/KeePassXXml041.cs
+++ b/KeePass/DataExchange/Formats/KeePassXXml041.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassXml1x.cs b/KeePass/DataExchange/Formats/KeePassXml1x.cs
index 6bb90bf..c20e526 100644
--- a/KeePass/DataExchange/Formats/KeePassXml1x.cs
+++ b/KeePass/DataExchange/Formats/KeePassXml1x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/KeePassXml2x.cs b/KeePass/DataExchange/Formats/KeePassXml2x.cs
index 2ef0b42..9311afb 100644
--- a/KeePass/DataExchange/Formats/KeePassXml2x.cs
+++ b/KeePass/DataExchange/Formats/KeePassXml2x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/MozillaBookmarksHtml100.cs b/KeePass/DataExchange/Formats/MozillaBookmarksHtml100.cs
index c5b224a..e47064f 100644
--- a/KeePass/DataExchange/Formats/MozillaBookmarksHtml100.cs
+++ b/KeePass/DataExchange/Formats/MozillaBookmarksHtml100.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/MozillaBookmarksJson100.cs b/KeePass/DataExchange/Formats/MozillaBookmarksJson100.cs
index 1217c2a..e3bba93 100644
--- a/KeePass/DataExchange/Formats/MozillaBookmarksJson100.cs
+++ b/KeePass/DataExchange/Formats/MozillaBookmarksJson100.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/OnePwProCsv599.cs b/KeePass/DataExchange/Formats/OnePwProCsv599.cs
index d0d7bf7..e54649f 100644
--- a/KeePass/DataExchange/Formats/OnePwProCsv599.cs
+++ b/KeePass/DataExchange/Formats/OnePwProCsv599.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PVaultTxt14.cs b/KeePass/DataExchange/Formats/PVaultTxt14.cs
index 9e1960a..2dca236 100644
--- a/KeePass/DataExchange/Formats/PVaultTxt14.cs
+++ b/KeePass/DataExchange/Formats/PVaultTxt14.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PassKeeper12.cs b/KeePass/DataExchange/Formats/PassKeeper12.cs
index 50ab441..f38e6b4 100644
--- a/KeePass/DataExchange/Formats/PassKeeper12.cs
+++ b/KeePass/DataExchange/Formats/PassKeeper12.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PinsTxt450.cs b/KeePass/DataExchange/Formats/PinsTxt450.cs
index a35c72c..34304f2 100644
--- a/KeePass/DataExchange/Formats/PinsTxt450.cs
+++ b/KeePass/DataExchange/Formats/PinsTxt450.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PpKeeperHtml270.cs b/KeePass/DataExchange/Formats/PpKeeperHtml270.cs
index e7dc991..b77478d 100644
--- a/KeePass/DataExchange/Formats/PpKeeperHtml270.cs
+++ b/KeePass/DataExchange/Formats/PpKeeperHtml270.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwAgentXml234.cs b/KeePass/DataExchange/Formats/PwAgentXml234.cs
index adceac3..1c02eb7 100644
--- a/KeePass/DataExchange/Formats/PwAgentXml234.cs
+++ b/KeePass/DataExchange/Formats/PwAgentXml234.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -31,10 +31,11 @@ using KeePass.Util;
 using KeePassLib;
 using KeePassLib.Interfaces;
 using KeePassLib.Security;
+using KeePassLib.Utility;
 
 namespace KeePass.DataExchange.Formats
 {
-	// 2.3.4
+	// 2.3.4-2.6.2+
 	internal sealed class PwAgentXml234 : FileFormatProvider
 	{
 		private const string ElemGroup = "group";
@@ -66,8 +67,11 @@ namespace KeePass.DataExchange.Formats
 		public override void Import(PwDatabase pwStorage, Stream sInput,
 			IStatusLogger slLogger)
 		{
+			StreamReader sr = new StreamReader(sInput, Encoding.Default);
 			XmlDocument xmlDoc = new XmlDocument();
-			xmlDoc.Load(sInput);
+			xmlDoc.Load(sr);
+			sr.Close();
+			sInput.Close();
 
 			XmlNode xmlRoot = xmlDoc.DocumentElement;
 
@@ -109,8 +113,8 @@ namespace KeePass.DataExchange.Formats
 						pwStorage.MemoryProtection.ProtectTitle,
 						XmlUtil.SafeInnerText(xmlChild)));
 				else if(xmlChild.Name == ElemEntryType)
-					pe.IconId = (XmlUtil.SafeInnerText(xmlChild) != "1") ?
-						PwIcon.Key : PwIcon.PaperNew;
+					pe.IconId = ((XmlUtil.SafeInnerText(xmlChild) != "1") ?
+						PwIcon.Key : PwIcon.PaperNew);
 				else if(xmlChild.Name == ElemEntryUser)
 					pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
 						pwStorage.MemoryProtection.ProtectUserName,
@@ -129,21 +133,40 @@ namespace KeePass.DataExchange.Formats
 						XmlUtil.SafeInnerText(xmlChild)));
 				else if(xmlChild.Name == ElemEntryCreationTime)
 				{
-					if(DateTime.TryParse(XmlUtil.SafeInnerText(xmlChild), out dt))
+					if(ParseDate(xmlChild, out dt))
 						pe.CreationTime = dt;
 				}
 				else if(xmlChild.Name == ElemEntryLastModTime)
 				{
-					if(DateTime.TryParse(XmlUtil.SafeInnerText(xmlChild), out dt))
+					if(ParseDate(xmlChild, out dt))
 						pe.LastModificationTime = dt;
 				}
 				else if(xmlChild.Name == ElemEntryExpireTime)
 				{
-					if(DateTime.TryParse(XmlUtil.SafeInnerText(xmlChild), out dt))
+					if(ParseDate(xmlChild, out dt))
+					{
 						pe.ExpiryTime = dt;
+						pe.Expires = true;
+					}
 				}
 				else { Debug.Assert(false); }
 			}
 		}
+
+		private static bool ParseDate(XmlNode xn, out DateTime dtOut)
+		{
+			string strDate = XmlUtil.SafeInnerText(xn);
+			if(strDate.Length == 0)
+			{
+				dtOut = DateTime.Now;
+				return false;
+			}
+
+			if(DateTime.TryParse(strDate, out dtOut)) return true;
+
+			Debug.Assert(false);
+			dtOut = DateTime.Now;
+			return false;
+		}
 	}
 }
diff --git a/KeePass/DataExchange/Formats/PwDepotXml26.cs b/KeePass/DataExchange/Formats/PwDepotXml26.cs
index 2179b37..ec57bd9 100644
--- a/KeePass/DataExchange/Formats/PwDepotXml26.cs
+++ b/KeePass/DataExchange/Formats/PwDepotXml26.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwExporterXml105.cs b/KeePass/DataExchange/Formats/PwExporterXml105.cs
index 126b5ba..4822b95 100644
--- a/KeePass/DataExchange/Formats/PwExporterXml105.cs
+++ b/KeePass/DataExchange/Formats/PwExporterXml105.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -105,7 +105,6 @@ namespace KeePass.DataExchange.Formats
 			}
 
 			MemoryStream msXml = new MemoryStream(StrUtil.Utf8.GetBytes(strDoc), false);
-
 			XmlDocument xmlDoc = new XmlDocument();
 			xmlDoc.Load(msXml);
 			msXml.Close();
diff --git a/KeePass/DataExchange/Formats/PwGorillaCsv142.cs b/KeePass/DataExchange/Formats/PwGorillaCsv142.cs
index 1926627..4113b7d 100644
--- a/KeePass/DataExchange/Formats/PwGorillaCsv142.cs
+++ b/KeePass/DataExchange/Formats/PwGorillaCsv142.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwKeeperCsv70.cs b/KeePass/DataExchange/Formats/PwKeeperCsv70.cs
index cf19ca5..07ba879 100644
--- a/KeePass/DataExchange/Formats/PwKeeperCsv70.cs
+++ b/KeePass/DataExchange/Formats/PwKeeperCsv70.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwMemory2008Xml104.cs b/KeePass/DataExchange/Formats/PwMemory2008Xml104.cs
index cff7893..e9f4588 100644
--- a/KeePass/DataExchange/Formats/PwMemory2008Xml104.cs
+++ b/KeePass/DataExchange/Formats/PwMemory2008Xml104.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -57,6 +57,7 @@ namespace KeePass.DataExchange.Formats
 
 			XmlSerializer xs = new XmlSerializer(typeof(Priv_PwMem2008XmlFile));
 			Priv_PwMem2008XmlFile f = (Priv_PwMem2008XmlFile)xs.Deserialize(ms);
+			ms.Close();
 
 			if((f == null) || (f.Cells == null)) return;
 
diff --git a/KeePass/DataExchange/Formats/PwPrompterDat12.cs b/KeePass/DataExchange/Formats/PwPrompterDat12.cs
index 6efee44..a55ce92 100644
--- a/KeePass/DataExchange/Formats/PwPrompterDat12.cs
+++ b/KeePass/DataExchange/Formats/PwPrompterDat12.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwSafeXml302.cs b/KeePass/DataExchange/Formats/PwSafeXml302.cs
index 33d3b2b..cf0d18f 100644
--- a/KeePass/DataExchange/Formats/PwSafeXml302.cs
+++ b/KeePass/DataExchange/Formats/PwSafeXml302.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwTresorXml100.cs b/KeePass/DataExchange/Formats/PwTresorXml100.cs
index b1e55f6..5ececa4 100644
--- a/KeePass/DataExchange/Formats/PwTresorXml100.cs
+++ b/KeePass/DataExchange/Formats/PwTresorXml100.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/PwsPlusCsv1007.cs b/KeePass/DataExchange/Formats/PwsPlusCsv1007.cs
index 7da6265..4002e94 100644
--- a/KeePass/DataExchange/Formats/PwsPlusCsv1007.cs
+++ b/KeePass/DataExchange/Formats/PwsPlusCsv1007.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/RevelationXml04.cs b/KeePass/DataExchange/Formats/RevelationXml04.cs
index a5e1216..716943b 100644
--- a/KeePass/DataExchange/Formats/RevelationXml04.cs
+++ b/KeePass/DataExchange/Formats/RevelationXml04.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/RoboFormHtml69.cs b/KeePass/DataExchange/Formats/RoboFormHtml69.cs
index 09693fb..1eb1eee 100644
--- a/KeePass/DataExchange/Formats/RoboFormHtml69.cs
+++ b/KeePass/DataExchange/Formats/RoboFormHtml69.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/SecurityTxt12.cs b/KeePass/DataExchange/Formats/SecurityTxt12.cs
index c5e1d4d..770099f 100644
--- a/KeePass/DataExchange/Formats/SecurityTxt12.cs
+++ b/KeePass/DataExchange/Formats/SecurityTxt12.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/Spamex20070328.cs b/KeePass/DataExchange/Formats/Spamex20070328.cs
index a1294b8..1dfb9a9 100644
--- a/KeePass/DataExchange/Formats/Spamex20070328.cs
+++ b/KeePass/DataExchange/Formats/Spamex20070328.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -94,7 +94,6 @@ namespace KeePass.DataExchange.Formats
 
 			RemoteCertificateValidationCallback pPrevCertCb =
 				ServicePointManager.ServerCertificateValidationCallback;
-
 			ServicePointManager.ServerCertificateValidationCallback =
 				delegate(object sender, X509Certificate certificate, X509Chain chain,
 					SslPolicyErrors sslPolicyErrors)
@@ -145,13 +144,10 @@ namespace KeePass.DataExchange.Formats
 					ImportIndex(pwStorage, strSubPage, vCookies, slLogger);
 				}
 			}
-			catch
+			finally
 			{
 				ServicePointManager.ServerCertificateValidationCallback = pPrevCertCb;
-				throw;
 			}
-
-			ServicePointManager.ServerCertificateValidationCallback = pPrevCertCb;
 		}
 
 		private static void ImportIndex(PwDatabase pwStorage, string strIndexPage,
diff --git a/KeePass/DataExchange/Formats/SplashIdCsv402.cs b/KeePass/DataExchange/Formats/SplashIdCsv402.cs
index 6cf9298..bb21721 100644
--- a/KeePass/DataExchange/Formats/SplashIdCsv402.cs
+++ b/KeePass/DataExchange/Formats/SplashIdCsv402.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -29,10 +29,11 @@ using KeePass.Resources;
 using KeePassLib;
 using KeePassLib.Interfaces;
 using KeePassLib.Security;
+using KeePassLib.Utility;
 
 namespace KeePass.DataExchange.Formats
 {
-	// 4.02
+	// 4.02-5.3+
 	internal sealed class SplashIdCsv402 : FileFormatProvider
 	{
 		public override bool SupportsImport { get { return true; } }
@@ -51,58 +52,68 @@ namespace KeePass.DataExchange.Formats
 
 		private const string StrHeader = "SplashID Export File";
 
-		private static readonly SplashIdMapping[] SplashIdMappings = {
-			new SplashIdMapping("Bank Accts", PwIcon.Homebanking,
-				new string[]{ PwDefs.TitleField, "Account #", PwDefs.PasswordField,
-					PwDefs.UserNameField, "Branch", "Phone #" }),
-			new SplashIdMapping("Birthdays", PwIcon.UserCommunication,
-				new string[]{ PwDefs.TitleField, "Date" }),
-			new SplashIdMapping("Calling Cards", PwIcon.EMail,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
-					PwDefs.PasswordField }),
-			new SplashIdMapping("Clothes Size", PwIcon.UserCommunication,
-				new string[]{ PwDefs.TitleField, "Shirt Size", "Pant Size",
-					"Shoe Size", "Dress Size" }),
-			new SplashIdMapping("Combinations", PwIcon.Key,
-				new string[]{ PwDefs.TitleField, PwDefs.PasswordField }),
-			new SplashIdMapping("Credit Cards", PwIcon.UserKey,
-				new string[]{ PwDefs.TitleField, "Card #", "Expiration Date",
-					PwDefs.UserNameField, PwDefs.PasswordField, "Bank" }),
-			new SplashIdMapping("Email Accts", PwIcon.EMail,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
-					PwDefs.PasswordField, "POP3 Host", "SMTP Host" }),
-			new SplashIdMapping("Emergency Info", PwIcon.UserCommunication,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField }),
-			new SplashIdMapping("Frequent Flyer", PwIcon.PaperQ,
-				new string[]{ PwDefs.TitleField, "Number",
-					PwDefs.UserNameField, "Date" }),
-			new SplashIdMapping("Identification", PwIcon.UserKey,
-				new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
-					PwDefs.UserNameField, "Date" }),
-			new SplashIdMapping("Insurance", PwIcon.ClipboardReady,
-				new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
-					PwDefs.UserNameField, "Insured", "Date" }),
-			new SplashIdMapping("Memberships", PwIcon.UserKey,
-				new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
-					PwDefs.UserNameField, "Date" }),
-			new SplashIdMapping("Phone Numbers", PwIcon.UserCommunication,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField }),
-			new SplashIdMapping("Prescriptions", PwIcon.ClipboardReady,
-				new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
-					PwDefs.UserNameField, "Doctor", "Pharmacy", "Phone #" }),
-			new SplashIdMapping("Serial Numbers", PwIcon.Key,
-				new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
-					"Purchase Date", "Reseller" }),
-			new SplashIdMapping("Vehicle Info", PwIcon.PaperReady,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
-					PwDefs.PasswordField }),
-			new SplashIdMapping("Voice Mail", PwIcon.IRCommunication,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
-					PwDefs.PasswordField }),
-			new SplashIdMapping("Web Logins", PwIcon.UserKey,
-				new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
-					PwDefs.PasswordField, PwDefs.UrlField })
-		};
+		private static SplashIdMapping[] m_vMappings = null;
+		private static SplashIdMapping[] SplashIdMappings
+		{
+			get
+			{
+				if(m_vMappings != null) return m_vMappings;
+
+				m_vMappings = new SplashIdMapping[]{
+					new SplashIdMapping("Bank Accts", PwIcon.Homebanking,
+						new string[]{ PwDefs.TitleField, "Account #", PwDefs.PasswordField,
+							PwDefs.UserNameField, "Branch", "Phone #" }),
+					new SplashIdMapping("Birthdays", PwIcon.UserCommunication,
+						new string[]{ PwDefs.TitleField, "Date" }),
+					new SplashIdMapping("Calling Cards", PwIcon.EMail,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
+							PwDefs.PasswordField }),
+					new SplashIdMapping("Clothes Size", PwIcon.UserCommunication,
+						new string[]{ PwDefs.TitleField, "Shirt Size", "Pant Size",
+							"Shoe Size", "Dress Size" }),
+					new SplashIdMapping("Combinations", PwIcon.Key,
+						new string[]{ PwDefs.TitleField, PwDefs.PasswordField }),
+					new SplashIdMapping("Credit Cards", PwIcon.UserKey,
+						new string[]{ PwDefs.TitleField, "Card #", "Expiration Date",
+							PwDefs.UserNameField, PwDefs.PasswordField, "Bank" }),
+					new SplashIdMapping("Email Accts", PwIcon.EMail,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
+							PwDefs.PasswordField, "POP3 Host", "SMTP Host" }),
+					new SplashIdMapping("Emergency Info", PwIcon.UserCommunication,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField }),
+					new SplashIdMapping("Frequent Flyer", PwIcon.PaperQ,
+						new string[]{ PwDefs.TitleField, "Number",
+							PwDefs.UserNameField, "Date" }),
+					new SplashIdMapping("Identification", PwIcon.UserKey,
+						new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
+							PwDefs.UserNameField, "Date" }),
+					new SplashIdMapping("Insurance", PwIcon.ClipboardReady,
+						new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
+							PwDefs.UserNameField, "Insured", "Date" }),
+					new SplashIdMapping("Memberships", PwIcon.UserKey,
+						new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
+							PwDefs.UserNameField, "Date" }),
+					new SplashIdMapping("Phone Numbers", PwIcon.UserCommunication,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField }),
+					new SplashIdMapping("Prescriptions", PwIcon.ClipboardReady,
+						new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
+							PwDefs.UserNameField, "Doctor", "Pharmacy", "Phone #" }),
+					new SplashIdMapping("Serial Numbers", PwIcon.Key,
+						new string[]{ PwDefs.TitleField, PwDefs.PasswordField,
+							"Purchase Date", "Reseller" }),
+					new SplashIdMapping("Vehicle Info", PwIcon.PaperReady,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
+							PwDefs.PasswordField }),
+					new SplashIdMapping("Voice Mail", PwIcon.IRCommunication,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
+							PwDefs.PasswordField }),
+					new SplashIdMapping("Web Logins", PwIcon.UserKey,
+						new string[]{ PwDefs.TitleField, PwDefs.UserNameField,
+							PwDefs.PasswordField, PwDefs.UrlField })
+				};
+				return m_vMappings;
+			}
+		}
 
 		public override void Import(PwDatabase pwStorage, Stream sInput,
 			IStatusLogger slLogger)
@@ -135,7 +146,7 @@ namespace KeePass.DataExchange.Formats
 			string strGroupName = ParseCsvWord(list[12]) + " - " + strType;
 
 			SplashIdMapping mp = null;
-			foreach(SplashIdMapping mpFind in SplashIdMappings)
+			foreach(SplashIdMapping mpFind in SplashIdCsv402.SplashIdMappings)
 			{
 				if(mpFind.TypeName == strType)
 				{
@@ -180,6 +191,13 @@ namespace KeePass.DataExchange.Formats
 			pe.Strings.Set(PwDefs.NotesField, new ProtectedString(
 				pwStorage.MemoryProtection.ProtectNotes,
 				ParseCsvWord(list[11])));
+
+			DateTime? dt = TimeUtil.ParseUSTextDate(ParseCsvWord(list[10]));
+			if(dt.HasValue)
+			{
+				pe.LastAccessTime = dt.Value;
+				pe.LastModificationTime = dt.Value;
+			}
 		}
 
 		private static string ParseCsvWord(string strWord)
diff --git a/KeePass/DataExchange/Formats/SteganosPwManager2007.cs b/KeePass/DataExchange/Formats/SteganosPwManager2007.cs
index 736fdf8..e9701ab 100644
--- a/KeePass/DataExchange/Formats/SteganosPwManager2007.cs
+++ b/KeePass/DataExchange/Formats/SteganosPwManager2007.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/StickyPwXml50.cs b/KeePass/DataExchange/Formats/StickyPwXml50.cs
index 0eb1188..a09f087 100644
--- a/KeePass/DataExchange/Formats/StickyPwXml50.cs
+++ b/KeePass/DataExchange/Formats/StickyPwXml50.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/Whisper32Csv116.cs b/KeePass/DataExchange/Formats/Whisper32Csv116.cs
index 3c5e86e..3d63599 100644
--- a/KeePass/DataExchange/Formats/Whisper32Csv116.cs
+++ b/KeePass/DataExchange/Formats/Whisper32Csv116.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/WinFavorites10.cs b/KeePass/DataExchange/Formats/WinFavorites10.cs
index af83d58..0b37137 100644
--- a/KeePass/DataExchange/Formats/WinFavorites10.cs
+++ b/KeePass/DataExchange/Formats/WinFavorites10.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Formats/XslTransform2x.cs b/KeePass/DataExchange/Formats/XslTransform2x.cs
index c29ac54..90133b5 100644
--- a/KeePass/DataExchange/Formats/XslTransform2x.cs
+++ b/KeePass/DataExchange/Formats/XslTransform2x.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -76,6 +76,7 @@ namespace KeePass.DataExchange.Formats
 			kdb.Save(msDataXml, pwExportInfo.DataGroup, Kdb4Format.PlainXml, slLogger);
 
 			byte[] pbData = msDataXml.ToArray();
+			msDataXml.Close();
 			MemoryStream msDataRead = new MemoryStream(pbData, false);
 			XmlReader xmlDataReader = XmlReader.Create(msDataRead);
 
@@ -90,6 +91,8 @@ namespace KeePass.DataExchange.Formats
 			XmlWriter xmlWriter = XmlWriter.Create(sOutput, xws);
 			xsl.Transform(xmlDataReader, xmlWriter);
 			xmlWriter.Close();
+			xmlDataReader.Close();
+			msDataRead.Close();
 
 			Array.Clear(pbData, 0, pbData.Length);
 			return true;
diff --git a/KeePass/DataExchange/Formats/ZdnPwProTxt314.cs b/KeePass/DataExchange/Formats/ZdnPwProTxt314.cs
index ea06cd8..eca8768 100644
--- a/KeePass/DataExchange/Formats/ZdnPwProTxt314.cs
+++ b/KeePass/DataExchange/Formats/ZdnPwProTxt314.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/ImportUtil.cs b/KeePass/DataExchange/ImportUtil.cs
index b95a27a..b1386ab 100644
--- a/KeePass/DataExchange/ImportUtil.cs
+++ b/KeePass/DataExchange/ImportUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -482,10 +482,14 @@ namespace KeePass.DataExchange
 			bool bProtect = ((pdContext == null) ? false :
 				pdContext.MemoryProtection.GetProtection(strName));
 
-			string strPrev = pe.Strings.ReadSafe(strName);
+			ProtectedString ps = pe.Strings.Get(strName);
+			string strPrev = ((ps != null) ? ps.ReadString() : null);
+			if(ps != null) bProtect = ps.IsProtected;
+
+			strValue = (strValue ?? string.Empty);
 			if(string.IsNullOrEmpty(strPrev))
 				pe.Strings.Set(strName, new ProtectedString(bProtect, strValue));
-			else if(!string.IsNullOrEmpty(strValue))
+			else if(strValue.Length > 0)
 				pe.Strings.Set(strName, new ProtectedString(bProtect,
 					strPrev + @", " + strValue));
 		}
diff --git a/KeePass/DataExchange/Json.cs b/KeePass/DataExchange/Json.cs
index b7a6deb..e706168 100644
--- a/KeePass/DataExchange/Json.cs
+++ b/KeePass/DataExchange/Json.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/Kdb3File.cs b/KeePass/DataExchange/Kdb3File.cs
index 61873f1..d3e41f2 100644
--- a/KeePass/DataExchange/Kdb3File.cs
+++ b/KeePass/DataExchange/Kdb3File.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -245,8 +245,10 @@ namespace KeePass.DataExchange
 				}
 
 				if(m_slLogger != null)
+				{
 					if(!m_slLogger.SetProgress((100 * uEntry) / uEntryCount))
 						throw new Exception(KPRes.Cancel);
+				}
 			}
 		}
 
diff --git a/KeePass/DataExchange/Kdb3Manager.cs b/KeePass/DataExchange/Kdb3Manager.cs
index 4da3a93..bc5e597 100644
--- a/KeePass/DataExchange/Kdb3Manager.cs
+++ b/KeePass/DataExchange/Kdb3Manager.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/DataExchange/PwExportInfo.cs b/KeePass/DataExchange/PwExportInfo.cs
index 7983c27..57bdad4 100644
--- a/KeePass/DataExchange/PwExportInfo.cs
+++ b/KeePass/DataExchange/PwExportInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasAction.cs b/KeePass/Ecas/EcasAction.cs
index 71d1c04..da2b136 100644
--- a/KeePass/Ecas/EcasAction.cs
+++ b/KeePass/Ecas/EcasAction.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasActionProvider.cs b/KeePass/Ecas/EcasActionProvider.cs
index 4f729e6..4e05faf 100644
--- a/KeePass/Ecas/EcasActionProvider.cs
+++ b/KeePass/Ecas/EcasActionProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasActionType.cs b/KeePass/Ecas/EcasActionType.cs
index 104144e..262296e 100644
--- a/KeePass/Ecas/EcasActionType.cs
+++ b/KeePass/Ecas/EcasActionType.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasCondition.cs b/KeePass/Ecas/EcasCondition.cs
index b99277a..bf69306 100644
--- a/KeePass/Ecas/EcasCondition.cs
+++ b/KeePass/Ecas/EcasCondition.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasConditionProvider.cs b/KeePass/Ecas/EcasConditionProvider.cs
index 8dbeab7..05c63b6 100644
--- a/KeePass/Ecas/EcasConditionProvider.cs
+++ b/KeePass/Ecas/EcasConditionProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasConditionType.cs b/KeePass/Ecas/EcasConditionType.cs
index faa95b9..7de5eaf 100644
--- a/KeePass/Ecas/EcasConditionType.cs
+++ b/KeePass/Ecas/EcasConditionType.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasContext.cs b/KeePass/Ecas/EcasContext.cs
index 7fcebd9..61335f8 100644
--- a/KeePass/Ecas/EcasContext.cs
+++ b/KeePass/Ecas/EcasContext.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasDefaultActionProvider.cs b/KeePass/Ecas/EcasDefaultActionProvider.cs
index 8446825..a9b07c8 100644
--- a/KeePass/Ecas/EcasDefaultActionProvider.cs
+++ b/KeePass/Ecas/EcasDefaultActionProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -255,22 +255,7 @@ namespace KeePass.Ecas
 			if(!string.IsNullOrEmpty(iocBase.Password))
 				iocBase.CredSaveMode = IOCredSaveMode.SaveCred;
 
-			if(string.IsNullOrEmpty(iocBase.UserName) && string.IsNullOrEmpty(iocBase.Password))
-			{
-				MruList mru = Program.MainForm.FileMruList;
-				for(uint u = 0; u < mru.ItemCount; ++u)
-				{
-					IOConnectionInfo iocMru = (mru.GetItem(u).Value as IOConnectionInfo);
-					if(iocMru == null) { Debug.Assert(false); continue; }
-
-					if(iocMru.Path == iocBase.Path)
-					{
-						iocBase = iocMru.CloneDeep();
-						break;
-					}
-				}
-			}
-
+			iocBase = Program.MainForm.CompleteConnectionInfoUsingMru(iocBase);
 			return MainForm.CompleteConnectionInfo(iocBase, false, true, true, false);
 		}
 
diff --git a/KeePass/Ecas/EcasDefaultConditionProvider.cs b/KeePass/Ecas/EcasDefaultConditionProvider.cs
index e85c7f6..ed7d571 100644
--- a/KeePass/Ecas/EcasDefaultConditionProvider.cs
+++ b/KeePass/Ecas/EcasDefaultConditionProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasDefaultEventProvider.cs b/KeePass/Ecas/EcasDefaultEventProvider.cs
index e279964..01194ed 100644
--- a/KeePass/Ecas/EcasDefaultEventProvider.cs
+++ b/KeePass/Ecas/EcasDefaultEventProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasEnum.cs b/KeePass/Ecas/EcasEnum.cs
index 145803a..62f14ad 100644
--- a/KeePass/Ecas/EcasEnum.cs
+++ b/KeePass/Ecas/EcasEnum.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasEvent.cs b/KeePass/Ecas/EcasEvent.cs
index 79e553a..407c8a9 100644
--- a/KeePass/Ecas/EcasEvent.cs
+++ b/KeePass/Ecas/EcasEvent.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasEventProvider.cs b/KeePass/Ecas/EcasEventProvider.cs
index 219b12d..ad3d179 100644
--- a/KeePass/Ecas/EcasEventProvider.cs
+++ b/KeePass/Ecas/EcasEventProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasEventType.cs b/KeePass/Ecas/EcasEventType.cs
index bbb81b6..16eff09 100644
--- a/KeePass/Ecas/EcasEventType.cs
+++ b/KeePass/Ecas/EcasEventType.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasParameter.cs b/KeePass/Ecas/EcasParameter.cs
index 8b34a09..3279481 100644
--- a/KeePass/Ecas/EcasParameter.cs
+++ b/KeePass/Ecas/EcasParameter.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasPool.cs b/KeePass/Ecas/EcasPool.cs
index 870c6ca..f995e72 100644
--- a/KeePass/Ecas/EcasPool.cs
+++ b/KeePass/Ecas/EcasPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasSystemEvents.cs b/KeePass/Ecas/EcasSystemEvents.cs
index e2fb0ae..4a2d1d3 100644
--- a/KeePass/Ecas/EcasSystemEvents.cs
+++ b/KeePass/Ecas/EcasSystemEvents.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasTrigger.cs b/KeePass/Ecas/EcasTrigger.cs
index bce0ac9..9853764 100644
--- a/KeePass/Ecas/EcasTrigger.cs
+++ b/KeePass/Ecas/EcasTrigger.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasTriggerSystem.cs b/KeePass/Ecas/EcasTriggerSystem.cs
index 1ed5e68..730fba9 100644
--- a/KeePass/Ecas/EcasTriggerSystem.cs
+++ b/KeePass/Ecas/EcasTriggerSystem.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasUtil.cs b/KeePass/Ecas/EcasUtil.cs
index a875133..4f1933c 100644
--- a/KeePass/Ecas/EcasUtil.cs
+++ b/KeePass/Ecas/EcasUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/EcasValueType.cs b/KeePass/Ecas/EcasValueType.cs
index 0665981..0f010c0 100644
--- a/KeePass/Ecas/EcasValueType.cs
+++ b/KeePass/Ecas/EcasValueType.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/IEcasObject.cs b/KeePass/Ecas/IEcasObject.cs
index 3041482..c4a2e2a 100644
--- a/KeePass/Ecas/IEcasObject.cs
+++ b/KeePass/Ecas/IEcasObject.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Ecas/IEcasParameterized.cs b/KeePass/Ecas/IEcasParameterized.cs
index 58fb4ca..4d8ca3c 100644
--- a/KeePass/Ecas/IEcasParameterized.cs
+++ b/KeePass/Ecas/IEcasParameterized.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/AboutForm.cs b/KeePass/Forms/AboutForm.cs
index cb405c7..60fc343 100644
--- a/KeePass/Forms/AboutForm.cs
+++ b/KeePass/Forms/AboutForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ namespace KeePass.Forms
 				strTitle, strDesc);
 			this.Icon = Properties.Resources.KeePass;
 
-			m_lvComponents.Columns.Add(KPRes.Components, 100, HorizontalAlignment.Left);
+			m_lvComponents.Columns.Add(KPRes.Component, 100, HorizontalAlignment.Left);
 			m_lvComponents.Columns.Add(KPRes.Version, 100, HorizontalAlignment.Left);
 
 			try { GetAppComponents(); }
diff --git a/KeePass/Forms/AutoTypeCtxForm.Designer.cs b/KeePass/Forms/AutoTypeCtxForm.Designer.cs
index d49407f..a01d80f 100644
--- a/KeePass/Forms/AutoTypeCtxForm.Designer.cs
+++ b/KeePass/Forms/AutoTypeCtxForm.Designer.cs
@@ -35,6 +35,7 @@
 			this.m_pnlTop = new System.Windows.Forms.Panel();
 			this.m_pnlBottom = new System.Windows.Forms.Panel();
 			this.m_pnlMiddle = new System.Windows.Forms.Panel();
+			this.m_btnTools = new System.Windows.Forms.Button();
 			((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit();
 			this.m_pnlTop.SuspendLayout();
 			this.m_pnlBottom.SuspendLayout();
@@ -56,7 +57,7 @@
 			this.m_lblText.Location = new System.Drawing.Point(9, 11);
 			this.m_lblText.Name = "m_lblText";
 			this.m_lblText.Size = new System.Drawing.Size(561, 30);
-			this.m_lblText.TabIndex = 2;
+			this.m_lblText.TabIndex = 0;
 			this.m_lblText.Text = "<>";
 			// 
 			// m_btnCancel
@@ -66,7 +67,7 @@
 			this.m_btnCancel.Location = new System.Drawing.Point(492, 6);
 			this.m_btnCancel.Name = "m_btnCancel";
 			this.m_btnCancel.Size = new System.Drawing.Size(75, 23);
-			this.m_btnCancel.TabIndex = 1;
+			this.m_btnCancel.TabIndex = 0;
 			this.m_btnCancel.Text = "&Cancel";
 			this.m_btnCancel.UseVisualStyleBackColor = true;
 			// 
@@ -98,17 +99,18 @@
 			this.m_pnlTop.Name = "m_pnlTop";
 			this.m_pnlTop.Padding = new System.Windows.Forms.Padding(9, 11, 9, 3);
 			this.m_pnlTop.Size = new System.Drawing.Size(579, 44);
-			this.m_pnlTop.TabIndex = 3;
+			this.m_pnlTop.TabIndex = 1;
 			// 
 			// m_pnlBottom
 			// 
+			this.m_pnlBottom.Controls.Add(this.m_btnTools);
 			this.m_pnlBottom.Controls.Add(this.m_btnCancel);
 			this.m_pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
 			this.m_pnlBottom.Location = new System.Drawing.Point(0, 323);
 			this.m_pnlBottom.Name = "m_pnlBottom";
 			this.m_pnlBottom.Padding = new System.Windows.Forms.Padding(12, 6, 12, 12);
 			this.m_pnlBottom.Size = new System.Drawing.Size(579, 41);
-			this.m_pnlBottom.TabIndex = 4;
+			this.m_pnlBottom.TabIndex = 2;
 			// 
 			// m_pnlMiddle
 			// 
@@ -118,7 +120,18 @@
 			this.m_pnlMiddle.Name = "m_pnlMiddle";
 			this.m_pnlMiddle.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
 			this.m_pnlMiddle.Size = new System.Drawing.Size(579, 219);
-			this.m_pnlMiddle.TabIndex = 5;
+			this.m_pnlMiddle.TabIndex = 0;
+			// 
+			// m_btnTools
+			// 
+			this.m_btnTools.Dock = System.Windows.Forms.DockStyle.Left;
+			this.m_btnTools.Location = new System.Drawing.Point(12, 6);
+			this.m_btnTools.Name = "m_btnTools";
+			this.m_btnTools.Size = new System.Drawing.Size(75, 23);
+			this.m_btnTools.TabIndex = 1;
+			this.m_btnTools.Text = "&Options";
+			this.m_btnTools.UseVisualStyleBackColor = true;
+			this.m_btnTools.Click += new System.EventHandler(this.OnBtnTools);
 			// 
 			// AutoTypeCtxForm
 			// 
@@ -155,5 +168,6 @@
 		private System.Windows.Forms.Panel m_pnlTop;
 		private System.Windows.Forms.Panel m_pnlBottom;
 		private System.Windows.Forms.Panel m_pnlMiddle;
+		private System.Windows.Forms.Button m_btnTools;
 	}
 }
\ No newline at end of file
diff --git a/KeePass/Forms/AutoTypeCtxForm.cs b/KeePass/Forms/AutoTypeCtxForm.cs
index 02030de..79a2eb2 100644
--- a/KeePass/Forms/AutoTypeCtxForm.cs
+++ b/KeePass/Forms/AutoTypeCtxForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@ using System.Text;
 using System.Windows.Forms;
 using System.Diagnostics;
 
+using KeePass.App.Configuration;
 using KeePass.Resources;
 using KeePass.UI;
 using KeePass.Util;
@@ -40,9 +41,11 @@ namespace KeePass.Forms
 
 		private string m_strInitialFormRect = string.Empty;
 		private string m_strInitialColWidths = string.Empty;
-
 		private int m_nBannerWidth = -1;
 
+		private ContextMenuStrip m_ctxTools = null;
+		private ToolStripMenuItem m_tsmiColumns = null;
+
 		private AutoTypeCtx m_atcSel = null;
 		public AutoTypeCtx SelectedCtx
 		{
@@ -76,18 +79,13 @@ namespace KeePass.Forms
 			this.MinimumSize = new Size(550, 300);
 
 			UIUtil.SetExplorerTheme(m_lvItems.Handle);
-
 			if(UISystemFonts.ListFont != null)
 				m_lvItems.Font = UISystemFonts.ListFont;
 
 			if(m_ilIcons != null) m_lvItems.SmallImageList = m_ilIcons;
 			else { Debug.Assert(false); m_ilIcons = new ImageList(); }
 
-			UIUtil.CreateEntryList(m_lvItems, m_lCtxs, m_ilIcons);
-
-			int nWidth = m_lvItems.ClientRectangle.Width / m_lvItems.Columns.Count;
-			for(int i = 0; i < m_lvItems.Columns.Count; ++i)
-				m_lvItems.Columns[i].Width = nWidth;
+			RecreateEntryList();
 
 			string strColWidths = Program.Config.UI.AutoTypeCtxColumnWidths;
 			if(strColWidths.Length > 0) UIUtil.SetColumnWidths(m_lvItems, strColWidths);
@@ -99,6 +97,13 @@ namespace KeePass.Forms
 			UIUtil.SetFocus(m_lvItems, this);
 		}
 
+		private void RecreateEntryList()
+		{
+			long lFlags = Program.Config.UI.AutoTypeCtxFlags;
+			UIUtil.CreateEntryList(m_lvItems, m_lCtxs, (AceAutoTypeCtxFlags)lFlags,
+				m_ilIcons);
+		}
+
 		private void OnFormClosed(object sender, FormClosedEventArgs e)
 		{
 			CleanUpEx();
@@ -115,6 +120,8 @@ namespace KeePass.Forms
 			if(strRect != m_strInitialFormRect)
 				Program.Config.UI.AutoTypeCtxRect = strRect;
 
+			DestroyToolsContextMenu();
+
 			if(m_ilIcons != null)
 			{
 				m_ilIcons.Dispose();
@@ -162,5 +169,86 @@ namespace KeePass.Forms
 		{
 			ProcessResize();
 		}
+
+		private void DestroyToolsContextMenu()
+		{
+			if(m_ctxTools == null) return;
+
+			foreach(ToolStripItem tsi in m_tsmiColumns.DropDownItems)
+				tsi.Click -= this.OnToggleColumn;
+
+			m_tsmiColumns = null;
+			m_ctxTools.Dispose();
+			m_ctxTools = null;
+		}
+
+		private void RecreateToolsContextMenu()
+		{
+			DestroyToolsContextMenu();
+
+			m_ctxTools = new ContextMenuStrip();
+			m_tsmiColumns = new ToolStripMenuItem(KPRes.Columns);
+			m_ctxTools.Items.Add(m_tsmiColumns);
+
+			long lFlags = Program.Config.UI.AutoTypeCtxFlags;
+
+			ToolStripMenuItem tsmi = new ToolStripMenuItem(KPRes.Title);
+			tsmi.Checked = true;
+			tsmi.Tag = AceAutoTypeCtxFlags.ColTitle;
+			tsmi.Click += this.OnToggleColumn;
+			tsmi.Enabled = false;
+			m_tsmiColumns.DropDownItems.Add(tsmi);
+
+			tsmi = new ToolStripMenuItem(KPRes.UserName);
+			tsmi.Checked = ((lFlags & (long)AceAutoTypeCtxFlags.ColUserName) != 0);
+			tsmi.Tag = AceAutoTypeCtxFlags.ColUserName;
+			tsmi.Click += this.OnToggleColumn;
+			m_tsmiColumns.DropDownItems.Add(tsmi);
+
+			tsmi = new ToolStripMenuItem(KPRes.Password);
+			tsmi.Checked = ((lFlags & (long)AceAutoTypeCtxFlags.ColPassword) != 0);
+			tsmi.Tag = AceAutoTypeCtxFlags.ColPassword;
+			tsmi.Click += this.OnToggleColumn;
+			m_tsmiColumns.DropDownItems.Add(tsmi);
+
+			tsmi = new ToolStripMenuItem(KPRes.Url);
+			tsmi.Checked = ((lFlags & (long)AceAutoTypeCtxFlags.ColUrl) != 0);
+			tsmi.Tag = AceAutoTypeCtxFlags.ColUrl;
+			tsmi.Click += this.OnToggleColumn;
+			m_tsmiColumns.DropDownItems.Add(tsmi);
+
+			tsmi = new ToolStripMenuItem(KPRes.Notes);
+			tsmi.Checked = ((lFlags & (long)AceAutoTypeCtxFlags.ColNotes) != 0);
+			tsmi.Tag = AceAutoTypeCtxFlags.ColNotes;
+			tsmi.Click += this.OnToggleColumn;
+			m_tsmiColumns.DropDownItems.Add(tsmi);
+
+			tsmi = new ToolStripMenuItem(KPRes.Sequence);
+			tsmi.Checked = ((lFlags & (long)AceAutoTypeCtxFlags.ColSequence) != 0);
+			tsmi.Tag = AceAutoTypeCtxFlags.ColSequence;
+			tsmi.Click += this.OnToggleColumn;
+			m_tsmiColumns.DropDownItems.Add(tsmi);
+		}
+
+		private void OnToggleColumn(object sender, EventArgs e)
+		{
+			ToolStripMenuItem tsmi = (sender as ToolStripMenuItem);
+			if(tsmi == null) { Debug.Assert(false); return; }
+
+			AceAutoTypeCtxFlags f = (AceAutoTypeCtxFlags)tsmi.Tag;
+			long lFlags = Program.Config.UI.AutoTypeCtxFlags;
+
+			lFlags ^= (long)f;
+			lFlags |= (long)AceAutoTypeCtxFlags.ColTitle; // Enforce title
+
+			Program.Config.UI.AutoTypeCtxFlags = lFlags;
+			RecreateEntryList();
+		}
+
+		private void OnBtnTools(object sender, EventArgs e)
+		{
+			RecreateToolsContextMenu();
+			m_ctxTools.Show(m_btnTools, 0, m_btnTools.Height);
+		}
 	}
 }
diff --git a/KeePass/Forms/CharPickerForm.cs b/KeePass/Forms/CharPickerForm.cs
index fecd0df..b86b998 100644
--- a/KeePass/Forms/CharPickerForm.cs
+++ b/KeePass/Forms/CharPickerForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ namespace KeePass.Forms
 	public partial class CharPickerForm : Form
 	{
 		private ProtectedString m_psWord = null;
-		private ProtectedString m_psSelected = new ProtectedString(false);
+		private ProtectedString m_psSelected = ProtectedString.Empty;
 
 		private SecureEdit m_secWord = new SecureEdit();
 		private List<Button> m_lButtons = new List<Button>();
diff --git a/KeePass/Forms/ColumnsForm.Designer.cs b/KeePass/Forms/ColumnsForm.Designer.cs
index 20c3365..d0975dd 100644
--- a/KeePass/Forms/ColumnsForm.Designer.cs
+++ b/KeePass/Forms/ColumnsForm.Designer.cs
@@ -32,11 +32,13 @@
 			this.m_btnCancel = new System.Windows.Forms.Button();
 			this.m_lblChoose = new System.Windows.Forms.Label();
 			this.m_lblReorderHint = new System.Windows.Forms.Label();
-			this.m_btnAsterisks = new System.Windows.Forms.Button();
 			this.m_lvColumns = new KeePass.UI.CustomListViewEx();
 			this.m_bannerImage = new System.Windows.Forms.PictureBox();
 			this.m_lblSortHint = new System.Windows.Forms.Label();
+			this.m_grpColumn = new System.Windows.Forms.GroupBox();
+			this.m_cbHide = new System.Windows.Forms.CheckBox();
 			((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit();
+			this.m_grpColumn.SuspendLayout();
 			this.SuspendLayout();
 			// 
 			// m_btnOK
@@ -64,40 +66,31 @@
 			// m_lblChoose
 			// 
 			this.m_lblChoose.AutoSize = true;
-			this.m_lblChoose.Location = new System.Drawing.Point(9, 70);
+			this.m_lblChoose.Location = new System.Drawing.Point(9, 72);
 			this.m_lblChoose.Name = "m_lblChoose";
 			this.m_lblChoose.Size = new System.Drawing.Size(239, 13);
-			this.m_lblChoose.TabIndex = 5;
+			this.m_lblChoose.TabIndex = 2;
 			this.m_lblChoose.Text = "Choose the columns to show in the main window:";
 			// 
 			// m_lblReorderHint
 			// 
 			this.m_lblReorderHint.AutoSize = true;
-			this.m_lblReorderHint.Location = new System.Drawing.Point(9, 423);
+			this.m_lblReorderHint.Location = new System.Drawing.Point(9, 447);
 			this.m_lblReorderHint.Name = "m_lblReorderHint";
 			this.m_lblReorderHint.Size = new System.Drawing.Size(344, 13);
-			this.m_lblReorderHint.TabIndex = 3;
+			this.m_lblReorderHint.TabIndex = 5;
 			this.m_lblReorderHint.Text = "To reorder columns, drag&&drop the column headers in the main window.";
 			// 
-			// m_btnAsterisks
-			// 
-			this.m_btnAsterisks.Location = new System.Drawing.Point(518, 395);
-			this.m_btnAsterisks.Name = "m_btnAsterisks";
-			this.m_btnAsterisks.Size = new System.Drawing.Size(75, 23);
-			this.m_btnAsterisks.TabIndex = 2;
-			this.m_btnAsterisks.Text = "&Asterisks";
-			this.m_btnAsterisks.UseVisualStyleBackColor = true;
-			this.m_btnAsterisks.Click += new System.EventHandler(this.OnBtnAsterisks);
-			// 
 			// m_lvColumns
 			// 
 			this.m_lvColumns.CheckBoxes = true;
 			this.m_lvColumns.FullRowSelect = true;
 			this.m_lvColumns.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
-			this.m_lvColumns.Location = new System.Drawing.Point(13, 88);
+			this.m_lvColumns.Location = new System.Drawing.Point(12, 88);
+			this.m_lvColumns.MultiSelect = false;
 			this.m_lvColumns.Name = "m_lvColumns";
-			this.m_lvColumns.Size = new System.Drawing.Size(499, 329);
-			this.m_lvColumns.TabIndex = 6;
+			this.m_lvColumns.Size = new System.Drawing.Size(500, 300);
+			this.m_lvColumns.TabIndex = 3;
 			this.m_lvColumns.UseCompatibleStateImageBehavior = false;
 			this.m_lvColumns.View = System.Windows.Forms.View.Details;
 			this.m_lvColumns.SelectedIndexChanged += new System.EventHandler(this.OnColumnsSelectedIndexChanged);
@@ -114,23 +107,44 @@
 			// m_lblSortHint
 			// 
 			this.m_lblSortHint.AutoSize = true;
-			this.m_lblSortHint.Location = new System.Drawing.Point(9, 440);
+			this.m_lblSortHint.Location = new System.Drawing.Point(9, 465);
 			this.m_lblSortHint.Name = "m_lblSortHint";
 			this.m_lblSortHint.Size = new System.Drawing.Size(419, 13);
-			this.m_lblSortHint.TabIndex = 4;
+			this.m_lblSortHint.TabIndex = 6;
 			this.m_lblSortHint.Text = "To sort entries by a field, click on the corresponding column header in the main " +
 				"window.";
 			// 
+			// m_grpColumn
+			// 
+			this.m_grpColumn.Controls.Add(this.m_cbHide);
+			this.m_grpColumn.Location = new System.Drawing.Point(12, 394);
+			this.m_grpColumn.Name = "m_grpColumn";
+			this.m_grpColumn.Size = new System.Drawing.Size(500, 45);
+			this.m_grpColumn.TabIndex = 4;
+			this.m_grpColumn.TabStop = false;
+			this.m_grpColumn.Text = "<>";
+			// 
+			// m_cbHide
+			// 
+			this.m_cbHide.AutoSize = true;
+			this.m_cbHide.Location = new System.Drawing.Point(10, 19);
+			this.m_cbHide.Name = "m_cbHide";
+			this.m_cbHide.Size = new System.Drawing.Size(144, 17);
+			this.m_cbHide.TabIndex = 0;
+			this.m_cbHide.Text = "Hide data using asterisks";
+			this.m_cbHide.UseVisualStyleBackColor = true;
+			this.m_cbHide.CheckedChanged += new System.EventHandler(this.OnHideCheckedChanged);
+			// 
 			// ColumnsForm
 			// 
 			this.AcceptButton = this.m_btnOK;
 			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
 			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
 			this.CancelButton = this.m_btnCancel;
-			this.ClientSize = new System.Drawing.Size(605, 461);
+			this.ClientSize = new System.Drawing.Size(605, 487);
+			this.Controls.Add(this.m_grpColumn);
 			this.Controls.Add(this.m_lblSortHint);
 			this.Controls.Add(this.m_bannerImage);
-			this.Controls.Add(this.m_btnAsterisks);
 			this.Controls.Add(this.m_lblReorderHint);
 			this.Controls.Add(this.m_lvColumns);
 			this.Controls.Add(this.m_lblChoose);
@@ -146,6 +160,8 @@
 			this.Load += new System.EventHandler(this.OnFormLoad);
 			this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed);
 			((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit();
+			this.m_grpColumn.ResumeLayout(false);
+			this.m_grpColumn.PerformLayout();
 			this.ResumeLayout(false);
 			this.PerformLayout();
 
@@ -158,8 +174,9 @@
 		private System.Windows.Forms.Label m_lblChoose;
 		private KeePass.UI.CustomListViewEx m_lvColumns;
 		private System.Windows.Forms.Label m_lblReorderHint;
-		private System.Windows.Forms.Button m_btnAsterisks;
 		private System.Windows.Forms.PictureBox m_bannerImage;
 		private System.Windows.Forms.Label m_lblSortHint;
+		private System.Windows.Forms.GroupBox m_grpColumn;
+		private System.Windows.Forms.CheckBox m_cbHide;
 	}
 }
\ No newline at end of file
diff --git a/KeePass/Forms/ColumnsForm.cs b/KeePass/Forms/ColumnsForm.cs
index e7ae02f..e6aefc3 100644
--- a/KeePass/Forms/ColumnsForm.cs
+++ b/KeePass/Forms/ColumnsForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -42,6 +42,8 @@ namespace KeePass.Forms
 
 	public partial class ColumnsForm : Form
 	{
+		private bool m_bIgnoreHideCheckEvent = false;
+
 		public ColumnsForm()
 		{
 			InitializeComponent();
@@ -68,7 +70,7 @@ namespace KeePass.Forms
 
 			ThreadPool.QueueUserWorkItem(new WaitCallback(FillColumnsList));
 
-			EnableControlsEx();
+			UpdateColumnPropInfo();
 		}
 
 		private void AddAceColumnTh(AceColumn c)
@@ -91,8 +93,9 @@ namespace KeePass.Forms
 			}
 
 			ListViewItem lvi = new ListViewItem(c.GetDisplayName());
+			lvi.Tag = c;
 
-			lvi.SubItems.Add(c.HideWithAsterisks ? KPRes.Yes : string.Empty);
+			lvi.SubItems.Add(c.HideWithAsterisks ? KPRes.Yes : KPRes.No);
 
 			if(c.Type == AceColumnType.Password)
 				lvi.SubItems.Add(KPRes.KeyboardKeyCtrl + "+H");
@@ -128,7 +131,6 @@ namespace KeePass.Forms
 			}
 			lvi.Checked = bChecked;
 
-			lvi.Tag = c;
 			lvi.Group = lvgContainer;
 			m_lvColumns.Items.Add(lvi);
 		}
@@ -250,15 +252,34 @@ namespace KeePass.Forms
 					AceColumn c = (lvi.Tag as AceColumn);
 					if(c == null) { Debug.Assert(false); continue; }
 
-					string str = (c.HideWithAsterisks ? KPRes.Yes : string.Empty);
+					string str = (c.HideWithAsterisks ? KPRes.Yes : KPRes.No);
 					lvi.SubItems[1].Text = str;
 				}
 			}
 		}
 
-		private void EnableControlsEx()
+		private void UpdateColumnPropInfo()
 		{
-			m_btnAsterisks.Enabled = (m_lvColumns.SelectedIndices.Count > 0);
+			ListView.SelectedListViewItemCollection lvsic = m_lvColumns.SelectedItems;
+			if((lvsic == null) || (lvsic.Count != 1) || (lvsic[0] == null))
+			{
+				m_grpColumn.Text = KPRes.SelectedColumn + ": (" + KPRes.None + ")";
+				m_cbHide.Checked = false;
+				m_cbHide.Enabled = false;
+			}
+			else
+			{
+				ListViewItem lvi = lvsic[0];
+				AceColumn c = (lvi.Tag as AceColumn);
+				if(c == null) { Debug.Assert(false); return; }
+
+				m_grpColumn.Text = KPRes.SelectedColumn + ": " + c.GetDisplayName();
+				m_cbHide.Enabled = true;
+
+				m_bIgnoreHideCheckEvent = true;
+				UIUtil.SetChecked(m_cbHide, c.HideWithAsterisks);
+				m_bIgnoreHideCheckEvent = false;
+			}
 		}
 
 		private void OnFormClosed(object sender, FormClosedEventArgs e)
@@ -286,8 +307,16 @@ namespace KeePass.Forms
 		{
 		}
 
-		private void OnBtnAsterisks(object sender, EventArgs e)
+		private void OnColumnsSelectedIndexChanged(object sender, EventArgs e)
 		{
+			UpdateColumnPropInfo();
+		}
+
+		private void OnHideCheckedChanged(object sender, EventArgs e)
+		{
+			if(m_bIgnoreHideCheckEvent) return;
+
+			bool bChecked = m_cbHide.Checked;
 			foreach(ListViewItem lvi in m_lvColumns.SelectedItems)
 			{
 				AceColumn c = (lvi.Tag as AceColumn);
@@ -297,15 +326,10 @@ namespace KeePass.Forms
 					!AppPolicy.Try(AppPolicyId.UnhidePasswords))
 				{
 				}
-				else c.HideWithAsterisks = !c.HideWithAsterisks;
+				else c.HideWithAsterisks = bChecked;
 			}
 
 			UpdateListEx(false);
 		}
-
-		private void OnColumnsSelectedIndexChanged(object sender, EventArgs e)
-		{
-			EnableControlsEx();
-		}
 	}
 }
diff --git a/KeePass/Forms/DataEditorForm.Designer.cs b/KeePass/Forms/DataEditorForm.Designer.cs
index 80c6eb9..0706c14 100644
--- a/KeePass/Forms/DataEditorForm.Designer.cs
+++ b/KeePass/Forms/DataEditorForm.Designer.cs
@@ -101,29 +101,27 @@
             this.m_menuFileSep0,
             this.m_menuFileExit});
 			this.m_menuFile.Name = "m_menuFile";
-			this.m_menuFile.Size = new System.Drawing.Size(35, 20);
+			this.m_menuFile.Size = new System.Drawing.Size(39, 20);
 			this.m_menuFile.Text = "&File";
 			// 
 			// m_menuFileSave
 			// 
 			this.m_menuFileSave.Image = global::KeePass.Properties.Resources.B16x16_FileSave;
 			this.m_menuFileSave.Name = "m_menuFileSave";
-			this.m_menuFileSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
-			this.m_menuFileSave.Size = new System.Drawing.Size(134, 22);
+			this.m_menuFileSave.Size = new System.Drawing.Size(152, 22);
 			this.m_menuFileSave.Text = "&Save";
 			this.m_menuFileSave.Click += new System.EventHandler(this.OnFileSave);
 			// 
 			// m_menuFileSep0
 			// 
 			this.m_menuFileSep0.Name = "m_menuFileSep0";
-			this.m_menuFileSep0.Size = new System.Drawing.Size(131, 6);
+			this.m_menuFileSep0.Size = new System.Drawing.Size(149, 6);
 			// 
 			// m_menuFileExit
 			// 
 			this.m_menuFileExit.Image = global::KeePass.Properties.Resources.B16x16_Exit;
 			this.m_menuFileExit.Name = "m_menuFileExit";
-			this.m_menuFileExit.ShortcutKeyDisplayString = "Esc";
-			this.m_menuFileExit.Size = new System.Drawing.Size(134, 22);
+			this.m_menuFileExit.Size = new System.Drawing.Size(152, 22);
 			this.m_menuFileExit.Text = "&Close";
 			this.m_menuFileExit.Click += new System.EventHandler(this.OnFileExit);
 			// 
@@ -134,25 +132,25 @@
             this.m_menuViewSep0,
             this.m_menuViewWordWrap});
 			this.m_menuView.Name = "m_menuView";
-			this.m_menuView.Size = new System.Drawing.Size(42, 20);
+			this.m_menuView.Size = new System.Drawing.Size(45, 20);
 			this.m_menuView.Text = "&View";
 			// 
 			// m_menuViewFont
 			// 
 			this.m_menuViewFont.Name = "m_menuViewFont";
-			this.m_menuViewFont.Size = new System.Drawing.Size(129, 22);
+			this.m_menuViewFont.Size = new System.Drawing.Size(135, 22);
 			this.m_menuViewFont.Text = "&Font...";
 			this.m_menuViewFont.Click += new System.EventHandler(this.OnViewFont);
 			// 
 			// m_menuViewSep0
 			// 
 			this.m_menuViewSep0.Name = "m_menuViewSep0";
-			this.m_menuViewSep0.Size = new System.Drawing.Size(126, 6);
+			this.m_menuViewSep0.Size = new System.Drawing.Size(132, 6);
 			// 
 			// m_menuViewWordWrap
 			// 
 			this.m_menuViewWordWrap.Name = "m_menuViewWordWrap";
-			this.m_menuViewWordWrap.Size = new System.Drawing.Size(129, 22);
+			this.m_menuViewWordWrap.Size = new System.Drawing.Size(135, 22);
 			this.m_menuViewWordWrap.Text = "Word &Wrap";
 			this.m_menuViewWordWrap.Click += new System.EventHandler(this.OnViewWordWrap);
 			// 
diff --git a/KeePass/Forms/DataEditorForm.cs b/KeePass/Forms/DataEditorForm.cs
index 9a43427..a5274e7 100644
--- a/KeePass/Forms/DataEditorForm.cs
+++ b/KeePass/Forms/DataEditorForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -108,7 +108,10 @@ namespace KeePass.Forms
 
 			BlockUIEvents(true);
 
-			UIUtil.ConfigureTbButton(m_tbFileSave, KPRes.Save, null);
+			UIUtil.AssignShortcut(m_menuFileSave, Keys.Control | Keys.S);
+			m_menuFileExit.ShortcutKeyDisplayString = KPRes.KeyboardKeyEsc;
+
+			UIUtil.ConfigureTbButton(m_tbFileSave, KPRes.Save, null, m_menuFileSave);
 			UIUtil.ConfigureTbButton(m_tbEditCut, KPRes.Cut, null);
 			UIUtil.ConfigureTbButton(m_tbEditCopy, KPRes.Copy, null);
 			UIUtil.ConfigureTbButton(m_tbEditPaste, KPRes.Paste, null);
@@ -166,9 +169,11 @@ namespace KeePass.Forms
 				return;
 			}
 
-			InstalledFontCollection c = new InstalledFontCollection();
-			foreach(FontFamily ff in c.Families)
-				m_tbFontCombo.Items.Add(ff.Name);
+			using(InstalledFontCollection c = new InstalledFontCollection())
+			{
+				foreach(FontFamily ff in c.Families)
+					m_tbFontCombo.Items.Add(ff.Name);
+			}
 
 			m_tbFontCombo.ToolTipText = KPRes.Font;
 
diff --git a/KeePass/Forms/DataEditorForm.resx b/KeePass/Forms/DataEditorForm.resx
index d8a74f3..e223c04 100644
--- a/KeePass/Forms/DataEditorForm.resx
+++ b/KeePass/Forms/DataEditorForm.resx
@@ -130,9 +130,8 @@
   <data name="m_tbFormatUnderline.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAADhJREFUOE9jYBgF
-        6CHwHyiAjEHy2MTwhhxMA7IibGI4DRk1ABHqAxeI2OIeFDP0AeipDhufui4BAFpWMc9YAjohAAAAAElF
-        TkSuQmCC
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVDhPY2AYBegh8B8ogIxB8tjE8IYcTAOyImxiOA0Z
+        NQAR6gMXiNjiHhQz9AHoqQ4bn7ouAQBaVjHPWAI6IQAAAABJRU5ErkJggg==
 </value>
   </data>
   <metadata name="m_statusMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
diff --git a/KeePass/Forms/DataViewerForm.cs b/KeePass/Forms/DataViewerForm.cs
index 782a381..685a73b 100644
--- a/KeePass/Forms/DataViewerForm.cs
+++ b/KeePass/Forms/DataViewerForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/DatabaseOperationsForm.cs b/KeePass/Forms/DatabaseOperationsForm.cs
index 6353158..a58d0db 100644
--- a/KeePass/Forms/DatabaseOperationsForm.cs
+++ b/KeePass/Forms/DatabaseOperationsForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/DatabaseSettingsForm.Designer.cs b/KeePass/Forms/DatabaseSettingsForm.Designer.cs
index d83a216..eebf54f 100644
--- a/KeePass/Forms/DatabaseSettingsForm.Designer.cs
+++ b/KeePass/Forms/DatabaseSettingsForm.Designer.cs
@@ -56,13 +56,6 @@
 			this.m_lblDbName = new System.Windows.Forms.Label();
 			this.m_tabSecurity = new System.Windows.Forms.TabPage();
 			this.m_lblSecIntro = new System.Windows.Forms.Label();
-			this.m_tabProtection = new System.Windows.Forms.TabPage();
-			this.m_lnkMemProtHelp = new System.Windows.Forms.LinkLabel();
-			this.m_lblMemProtEnable = new System.Windows.Forms.Label();
-			this.m_lblMemProtHint = new System.Windows.Forms.Label();
-			this.m_lblMemProtDesc = new System.Windows.Forms.Label();
-			this.m_lbMemProt = new System.Windows.Forms.CheckedListBox();
-			this.m_lblProtIntro = new System.Windows.Forms.Label();
 			this.m_tabCompression = new System.Windows.Forms.TabPage();
 			this.m_lblHeaderCpAlgo = new System.Windows.Forms.Label();
 			this.m_lblCpGZipPerf = new System.Windows.Forms.Label();
@@ -100,7 +93,6 @@
 			this.m_tabMain.SuspendLayout();
 			this.m_tabGeneral.SuspendLayout();
 			this.m_tabSecurity.SuspendLayout();
-			this.m_tabProtection.SuspendLayout();
 			this.m_tabCompression.SuspendLayout();
 			this.m_tabRecycleBin.SuspendLayout();
 			this.m_tabAdvanced.SuspendLayout();
@@ -263,7 +255,6 @@
 			// 
 			this.m_tabMain.Controls.Add(this.m_tabGeneral);
 			this.m_tabMain.Controls.Add(this.m_tabSecurity);
-			this.m_tabMain.Controls.Add(this.m_tabProtection);
 			this.m_tabMain.Controls.Add(this.m_tabCompression);
 			this.m_tabMain.Controls.Add(this.m_tabRecycleBin);
 			this.m_tabMain.Controls.Add(this.m_tabAdvanced);
@@ -386,79 +377,6 @@
 			this.m_lblSecIntro.TabIndex = 0;
 			this.m_lblSecIntro.Text = "On this page you can configure file-level security settings.";
 			// 
-			// m_tabProtection
-			// 
-			this.m_tabProtection.Controls.Add(this.m_lnkMemProtHelp);
-			this.m_tabProtection.Controls.Add(this.m_lblMemProtEnable);
-			this.m_tabProtection.Controls.Add(this.m_lblMemProtHint);
-			this.m_tabProtection.Controls.Add(this.m_lblMemProtDesc);
-			this.m_tabProtection.Controls.Add(this.m_lbMemProt);
-			this.m_tabProtection.Controls.Add(this.m_lblProtIntro);
-			this.m_tabProtection.Location = new System.Drawing.Point(4, 22);
-			this.m_tabProtection.Name = "m_tabProtection";
-			this.m_tabProtection.Size = new System.Drawing.Size(455, 294);
-			this.m_tabProtection.TabIndex = 3;
-			this.m_tabProtection.Text = "Protection";
-			this.m_tabProtection.UseVisualStyleBackColor = true;
-			// 
-			// m_lnkMemProtHelp
-			// 
-			this.m_lnkMemProtHelp.AutoSize = true;
-			this.m_lnkMemProtHelp.Location = new System.Drawing.Point(3, 271);
-			this.m_lnkMemProtHelp.Name = "m_lnkMemProtHelp";
-			this.m_lnkMemProtHelp.Size = new System.Drawing.Size(257, 13);
-			this.m_lnkMemProtHelp.TabIndex = 5;
-			this.m_lnkMemProtHelp.TabStop = true;
-			this.m_lnkMemProtHelp.Text = "Help: Automatic reset of in-memory protection options";
-			this.m_lnkMemProtHelp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClickedMemProtHelp);
-			// 
-			// m_lblMemProtEnable
-			// 
-			this.m_lblMemProtEnable.AutoSize = true;
-			this.m_lblMemProtEnable.Location = new System.Drawing.Point(3, 119);
-			this.m_lblMemProtEnable.Name = "m_lblMemProtEnable";
-			this.m_lblMemProtEnable.Size = new System.Drawing.Size(247, 13);
-			this.m_lblMemProtEnable.TabIndex = 3;
-			this.m_lblMemProtEnable.Text = "Enable in-memory protection for the following fields:";
-			// 
-			// m_lblMemProtHint
-			// 
-			this.m_lblMemProtHint.Location = new System.Drawing.Point(3, 71);
-			this.m_lblMemProtHint.Name = "m_lblMemProtHint";
-			this.m_lblMemProtHint.Size = new System.Drawing.Size(443, 27);
-			this.m_lblMemProtHint.TabIndex = 2;
-			this.m_lblMemProtHint.Text = "It is recommended to turn on memory protection for password fields and leave it d" +
-				"isabled for all others. Process memory protection slows down all operations a bi" +
-				"t.";
-			// 
-			// m_lblMemProtDesc
-			// 
-			this.m_lblMemProtDesc.Location = new System.Drawing.Point(3, 34);
-			this.m_lblMemProtDesc.Name = "m_lblMemProtDesc";
-			this.m_lblMemProtDesc.Size = new System.Drawing.Size(443, 28);
-			this.m_lblMemProtDesc.TabIndex = 1;
-			this.m_lblMemProtDesc.Text = "Fields can be stored encrypted in the process memory. This ensures that no other " +
-				"application can read your data by dumping the memory.";
-			// 
-			// m_lbMemProt
-			// 
-			this.m_lbMemProt.CheckOnClick = true;
-			this.m_lbMemProt.FormattingEnabled = true;
-			this.m_lbMemProt.Location = new System.Drawing.Point(6, 135);
-			this.m_lbMemProt.Name = "m_lbMemProt";
-			this.m_lbMemProt.ScrollAlwaysVisible = true;
-			this.m_lbMemProt.Size = new System.Drawing.Size(440, 124);
-			this.m_lbMemProt.TabIndex = 4;
-			// 
-			// m_lblProtIntro
-			// 
-			this.m_lblProtIntro.Location = new System.Drawing.Point(3, 12);
-			this.m_lblProtIntro.Name = "m_lblProtIntro";
-			this.m_lblProtIntro.Size = new System.Drawing.Size(443, 13);
-			this.m_lblProtIntro.TabIndex = 0;
-			this.m_lblProtIntro.Text = "On this page you can configure run-time memory protection settings for this datab" +
-				"ase.";
-			// 
 			// m_tabCompression
 			// 
 			this.m_tabCompression.Controls.Add(this.m_lblHeaderCpAlgo);
@@ -800,8 +718,6 @@
 			this.m_tabGeneral.PerformLayout();
 			this.m_tabSecurity.ResumeLayout(false);
 			this.m_tabSecurity.PerformLayout();
-			this.m_tabProtection.ResumeLayout(false);
-			this.m_tabProtection.PerformLayout();
 			this.m_tabCompression.ResumeLayout(false);
 			this.m_tabCompression.PerformLayout();
 			this.m_tabRecycleBin.ResumeLayout(false);
@@ -841,18 +757,12 @@
 		private System.Windows.Forms.TabControl m_tabMain;
 		private System.Windows.Forms.TabPage m_tabGeneral;
 		private System.Windows.Forms.TabPage m_tabSecurity;
-		private System.Windows.Forms.TabPage m_tabProtection;
 		private System.Windows.Forms.TabPage m_tabCompression;
 		private KeePass.UI.PromptedTextBox m_tbDbDesc;
 		private System.Windows.Forms.Label m_lblDbDesc;
 		private KeePass.UI.PromptedTextBox m_tbDbName;
 		private System.Windows.Forms.Label m_lblDbName;
 		private System.Windows.Forms.Label m_lblSecIntro;
-		private System.Windows.Forms.Label m_lblProtIntro;
-		private System.Windows.Forms.Label m_lblMemProtHint;
-		private System.Windows.Forms.Label m_lblMemProtDesc;
-		private System.Windows.Forms.CheckedListBox m_lbMemProt;
-		private System.Windows.Forms.Label m_lblMemProtEnable;
 		private System.Windows.Forms.RadioButton m_rbGZip;
 		private System.Windows.Forms.RadioButton m_rbNone;
 		private System.Windows.Forms.Label m_lblCpNonePerf;
@@ -879,7 +789,6 @@
 		private System.Windows.Forms.CheckBox m_cbKeyRec;
 		private System.Windows.Forms.NumericUpDown m_numKeyForceDays;
 		private System.Windows.Forms.NumericUpDown m_numKeyRecDays;
-		private System.Windows.Forms.LinkLabel m_lnkMemProtHelp;
 		private System.Windows.Forms.GroupBox m_grpHistory;
 		private System.Windows.Forms.CheckBox m_cbHistoryMaxItems;
 		private System.Windows.Forms.NumericUpDown m_numHistoryMaxSize;
diff --git a/KeePass/Forms/DatabaseSettingsForm.cs b/KeePass/Forms/DatabaseSettingsForm.cs
index c386771..a890b26 100644
--- a/KeePass/Forms/DatabaseSettingsForm.cs
+++ b/KeePass/Forms/DatabaseSettingsForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@ using System.Windows.Forms;
 using System.Diagnostics;
 
 using KeePass.App;
+using KeePass.App.Configuration;
 using KeePass.UI;
 using KeePass.Resources;
 
@@ -119,11 +120,11 @@ namespace KeePass.Forms
 			m_numEncRounds.Maximum = ulong.MaxValue;
 			m_numEncRounds.Value = m_pwDatabase.KeyEncryptionRounds;
 
-			m_lbMemProt.Items.Add(KPRes.Title, m_pwDatabase.MemoryProtection.ProtectTitle);
-			m_lbMemProt.Items.Add(KPRes.UserName, m_pwDatabase.MemoryProtection.ProtectUserName);
-			m_lbMemProt.Items.Add(KPRes.Password, m_pwDatabase.MemoryProtection.ProtectPassword);
-			m_lbMemProt.Items.Add(KPRes.Url, m_pwDatabase.MemoryProtection.ProtectUrl);
-			m_lbMemProt.Items.Add(KPRes.Notes, m_pwDatabase.MemoryProtection.ProtectNotes);
+			// m_lbMemProt.Items.Add(KPRes.Title, m_pwDatabase.MemoryProtection.ProtectTitle);
+			// m_lbMemProt.Items.Add(KPRes.UserName, m_pwDatabase.MemoryProtection.ProtectUserName);
+			// m_lbMemProt.Items.Add(KPRes.Password, m_pwDatabase.MemoryProtection.ProtectPassword);
+			// m_lbMemProt.Items.Add(KPRes.Url, m_pwDatabase.MemoryProtection.ProtectUrl);
+			// m_lbMemProt.Items.Add(KPRes.Notes, m_pwDatabase.MemoryProtection.ProtectNotes);
 
 			// m_cbAutoEnableHiding.Checked = m_pwDatabase.MemoryProtection.AutoEnableVisualHiding;
 			// m_cbAutoEnableHiding.Checked = false;
@@ -201,8 +202,13 @@ namespace KeePass.Forms
 
 			m_numHistoryMaxItems.Enabled = m_cbHistoryMaxItems.Checked;
 			m_numHistoryMaxSize.Enabled = m_cbHistoryMaxSize.Checked;
-			m_numKeyRecDays.Enabled = m_cbKeyRec.Checked;
-			m_numKeyForceDays.Enabled = m_cbKeyForce.Checked;
+
+			bool bEnableDays = ((Program.Config.UI.UIFlags &
+				(ulong)AceUIFlags.DisableKeyChangeDays) == 0);
+			m_numKeyRecDays.Enabled = (bEnableDays && m_cbKeyRec.Checked);
+			m_numKeyForceDays.Enabled = (bEnableDays && m_cbKeyForce.Checked);
+			m_cbKeyRec.Enabled = bEnableDays;
+			m_cbKeyForce.Enabled = bEnableDays;
 		}
 
 		private void OnBtnOK(object sender, EventArgs e)
@@ -241,16 +247,16 @@ namespace KeePass.Forms
 			else if(m_rbGZip.Checked) m_pwDatabase.Compression = PwCompressionAlgorithm.GZip;
 			else { Debug.Assert(false); }
 
-			m_pwDatabase.MemoryProtection.ProtectTitle = UpdateMemoryProtection(0,
-				m_pwDatabase.MemoryProtection.ProtectTitle, PwDefs.TitleField);
-			m_pwDatabase.MemoryProtection.ProtectUserName = UpdateMemoryProtection(1,
-				m_pwDatabase.MemoryProtection.ProtectUserName, PwDefs.UserNameField);
-			m_pwDatabase.MemoryProtection.ProtectPassword = UpdateMemoryProtection(2,
-				m_pwDatabase.MemoryProtection.ProtectPassword, PwDefs.PasswordField);
-			m_pwDatabase.MemoryProtection.ProtectUrl = UpdateMemoryProtection(3,
-				m_pwDatabase.MemoryProtection.ProtectUrl, PwDefs.UrlField);
-			m_pwDatabase.MemoryProtection.ProtectNotes = UpdateMemoryProtection(4,
-				m_pwDatabase.MemoryProtection.ProtectNotes, PwDefs.NotesField);
+			// m_pwDatabase.MemoryProtection.ProtectTitle = UpdateMemoryProtection(0,
+			//	m_pwDatabase.MemoryProtection.ProtectTitle, PwDefs.TitleField);
+			// m_pwDatabase.MemoryProtection.ProtectUserName = UpdateMemoryProtection(1,
+			//	m_pwDatabase.MemoryProtection.ProtectUserName, PwDefs.UserNameField);
+			// m_pwDatabase.MemoryProtection.ProtectPassword = UpdateMemoryProtection(2,
+			//	m_pwDatabase.MemoryProtection.ProtectPassword, PwDefs.PasswordField);
+			// m_pwDatabase.MemoryProtection.ProtectUrl = UpdateMemoryProtection(3,
+			//	m_pwDatabase.MemoryProtection.ProtectUrl, PwDefs.UrlField);
+			// m_pwDatabase.MemoryProtection.ProtectNotes = UpdateMemoryProtection(4,
+			//	m_pwDatabase.MemoryProtection.ProtectNotes, PwDefs.NotesField);
 
 			// m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = m_cbAutoEnableHiding.Checked;
 
@@ -312,31 +318,24 @@ namespace KeePass.Forms
 			else m_pwDatabase.MasterKeyChangeForce = (long)m_numKeyForceDays.Value;
 		}
 
-		private bool UpdateMemoryProtection(int nIndex, bool bOldSetting, string strFieldID)
-		{
-			bool bNewProt = m_lbMemProt.GetItemChecked(nIndex);
-
-			if(bNewProt != bOldSetting)
-			{
-				m_pwDatabase.RootGroup.EnableStringFieldProtection(strFieldID, bNewProt);
-			}
-
-#if DEBUG
-			GroupHandler gh = delegate(PwGroup pg)
-			{
-				return true;
-			};
-			EntryHandler eh = delegate(PwEntry pe)
-			{
-				ProtectedString ps = pe.Strings.Get(strFieldID);
-				if(ps != null) { Debug.Assert(ps.IsProtected == bNewProt); }
-				return true;
-			};
-			Debug.Assert(m_pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh));
-#endif
-
-			return bNewProt;
-		}
+		// private bool UpdateMemoryProtection(int nIndex, bool bOldSetting,
+		//	string strFieldID)
+		// {
+		//	bool bNewProt = m_lbMemProt.GetItemChecked(nIndex);
+		//	if(bNewProt != bOldSetting)
+		//		m_pwDatabase.RootGroup.EnableStringFieldProtection(strFieldID, bNewProt);
+		// #if DEBUG
+		//	EntryHandler eh = delegate(PwEntry pe)
+		//	{
+		//		ProtectedString ps = pe.Strings.Get(strFieldID);
+		//		if(ps != null) { Debug.Assert(ps.IsProtected == bNewProt); }
+		//		return true;
+		//	};
+		//	Debug.Assert(m_pwDatabase.RootGroup.TraverseTree(
+		//		TraversalMethod.PreOrder, null, eh));
+		// #endif
+		//	return bNewProt;
+		// }
 
 		private void OnBtnCancel(object sender, EventArgs e)
 		{
@@ -349,8 +348,8 @@ namespace KeePass.Forms
 				strSubTopic = AppDefs.HelpTopics.DbSettingsGeneral;
 			else if(m_tabMain.SelectedTab == m_tabSecurity)
 				strSubTopic = AppDefs.HelpTopics.DbSettingsSecurity;
-			else if(m_tabMain.SelectedTab == m_tabProtection)
-				strSubTopic = AppDefs.HelpTopics.DbSettingsProtection;
+			// else if(m_tabMain.SelectedTab == m_tabProtection)
+			//	strSubTopic = AppDefs.HelpTopics.DbSettingsProtection;
 			else if(m_tabMain.SelectedTab == m_tabCompression)
 				strSubTopic = AppDefs.HelpTopics.DbSettingsCompression;
 
@@ -382,10 +381,10 @@ namespace KeePass.Forms
 			EnableControlsEx();
 		}
 
-		private void OnLinkClickedMemProtHelp(object sender, LinkLabelLinkClickedEventArgs e)
-		{
-			AppHelp.ShowHelp(AppDefs.HelpTopics.FaqTech, AppDefs.HelpTopics.FaqTechMemProt);
-		}
+		// private void OnLinkClickedMemProtHelp(object sender, LinkLabelLinkClickedEventArgs e)
+		// {
+		//	AppHelp.ShowHelp(AppDefs.HelpTopics.FaqTech, AppDefs.HelpTopics.FaqTechMemProt);
+		// }
 
 		private void OnHistoryMaxItemsCheckedChanged(object sender, EventArgs e)
 		{
diff --git a/KeePass/Forms/DuplicationForm.cs b/KeePass/Forms/DuplicationForm.cs
index 62f1f7f..bc450d6 100644
--- a/KeePass/Forms/DuplicationForm.cs
+++ b/KeePass/Forms/DuplicationForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/EcasActionForm.cs b/KeePass/Forms/EcasActionForm.cs
index 104ec18..358ae08 100644
--- a/KeePass/Forms/EcasActionForm.cs
+++ b/KeePass/Forms/EcasActionForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/EcasConditionForm.cs b/KeePass/Forms/EcasConditionForm.cs
index 6ffe883..3c92d9a 100644
--- a/KeePass/Forms/EcasConditionForm.cs
+++ b/KeePass/Forms/EcasConditionForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/EcasEventForm.cs b/KeePass/Forms/EcasEventForm.cs
index 5579f74..118fc30 100644
--- a/KeePass/Forms/EcasEventForm.cs
+++ b/KeePass/Forms/EcasEventForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/EcasTriggerForm.cs b/KeePass/Forms/EcasTriggerForm.cs
index d8bc8c4..cc2dd6f 100644
--- a/KeePass/Forms/EcasTriggerForm.cs
+++ b/KeePass/Forms/EcasTriggerForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@ namespace KeePass.Forms
 			m_lvActions.Columns.Add(string.Empty, nColWidth);
 
 			m_tbName.Text = m_trigger.Name;
-			m_tbComments.Text = StrUtil.ToWindowsString(m_trigger.Comments);
+			m_tbComments.Text = StrUtil.NormalizeNewLines(m_trigger.Comments, true);
 			m_cbEnabled.Checked = m_trigger.Enabled;
 			m_cbInitiallyOn.Checked = m_trigger.InitiallyOn;
 			m_cbTurnOffAfterAction.Checked = m_trigger.TurnOffAfterAction;
diff --git a/KeePass/Forms/EcasTriggersForm.cs b/KeePass/Forms/EcasTriggersForm.cs
index a5222b7..46d0de1 100644
--- a/KeePass/Forms/EcasTriggersForm.cs
+++ b/KeePass/Forms/EcasTriggersForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -214,6 +214,8 @@ namespace KeePass.Forms
 
 				ClipboardUtil.Copy(StrUtil.Utf8.GetString(ms.ToArray()), false,
 					false, null, null, this.Handle);
+				xw.Close();
+				ms.Close();
 			}
 			catch(Exception excp) { MessageService.ShowWarning(excp.Message); }
 		}
@@ -242,6 +244,7 @@ namespace KeePass.Forms
 				byte[] pbData = StrUtil.Utf8.GetBytes(strData);
 				MemoryStream ms = new MemoryStream(pbData, false);
 				EcasTriggerContainer c = (EcasTriggerContainer)xmls.Deserialize(ms);
+				ms.Close();
 
 				foreach(EcasTrigger t in c.Triggers)
 				{
diff --git a/KeePass/Forms/EditAutoTypeItemForm.cs b/KeePass/Forms/EditAutoTypeItemForm.cs
index 4be77cb..a6efb36 100644
--- a/KeePass/Forms/EditAutoTypeItemForm.cs
+++ b/KeePass/Forms/EditAutoTypeItemForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -469,8 +469,7 @@ namespace KeePass.Forms
 				@"search --onlyvisible --name '.+' getwindowname %@");
 			if(string.IsNullOrEmpty(strWindows)) return;
 
-			strWindows = strWindows.Replace("\r\n", "\n");
-			strWindows = strWindows.Replace("\r", string.Empty);
+			strWindows = StrUtil.NormalizeNewLines(strWindows, false);
 			string[] vWindows = strWindows.Split(new char[]{ '\n' });
 
 			List<string> vListed = new List<string>();
diff --git a/KeePass/Forms/EditStringForm.cs b/KeePass/Forms/EditStringForm.cs
index 8d15620..0e0f7a1 100644
--- a/KeePass/Forms/EditStringForm.cs
+++ b/KeePass/Forms/EditStringForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -41,8 +41,7 @@ namespace KeePass.Forms
 	{
 		private ProtectedStringDictionary m_vStringDict = null;
 		private string m_strStringName = null;
-		private ProtectedString m_psStringValue = null;
-		private Color m_clrNormalBackground;
+		private ProtectedString m_psStringInitialValue = null;
 		private RichTextBoxContextMenu m_ctxValue = new RichTextBoxContextMenu();
 		private PwDatabase m_pwContext = null;
 
@@ -59,15 +58,15 @@ namespace KeePass.Forms
 		/// </summary>
 		/// <param name="vStringDict">String container. Must not be <c>null</c>.</param>
 		/// <param name="strStringName">Initial name of the string. May be <c>null</c>.</param>
-		/// <param name="psStringValue">Initial value. May be <c>null</c>.</param>
+		/// <param name="psStringInitialValue">Initial value. May be <c>null</c>.</param>
 		public void InitEx(ProtectedStringDictionary vStringDict, string strStringName,
-			ProtectedString psStringValue, PwDatabase pwContext)
+			ProtectedString psStringInitialValue, PwDatabase pwContext)
 		{
 			Debug.Assert(vStringDict != null); if(vStringDict == null) throw new ArgumentNullException("vStringDict");
 			m_vStringDict = vStringDict;
 
 			m_strStringName = strStringName;
-			m_psStringValue = psStringValue;
+			m_psStringInitialValue = psStringInitialValue;
 
 			m_pwContext = pwContext;
 		}
@@ -96,16 +95,14 @@ namespace KeePass.Forms
 				Properties.Resources.B48x48_Font, strTitle, strDesc);
 			this.Icon = Properties.Resources.KeePass;
 
-			m_clrNormalBackground = m_cmbStringName.BackColor;
-
 			UIUtil.EnableAutoCompletion(m_cmbStringName, true);
 			UIUtil.PrepareStandardMultilineControl(m_richStringValue, true, true);
 
 			if(m_strStringName != null) m_cmbStringName.Text = m_strStringName;
-			if(m_psStringValue != null)
+			if(m_psStringInitialValue != null)
 			{
-				m_richStringValue.Text = m_psStringValue.ReadString();
-				m_cbProtect.Checked = m_psStringValue.IsProtected;
+				m_richStringValue.Text = m_psStringInitialValue.ReadString();
+				m_cbProtect.Checked = m_psStringInitialValue.IsProtected;
 			}
 
 			ValidateStringName();
@@ -147,7 +144,7 @@ namespace KeePass.Forms
 			else if(str.Length <= 0)
 			{
 				m_lblValidationInfo.Text = KPRes.FieldNamePrompt;
-				m_cmbStringName.BackColor = m_clrNormalBackground;
+				m_cmbStringName.ResetBackColor();
 				m_btnOK.Enabled = false;
 				return false;
 
@@ -169,7 +166,7 @@ namespace KeePass.Forms
 			else
 			{
 				m_lblValidationInfo.Text = string.Empty;
-				m_cmbStringName.BackColor = m_clrNormalBackground;
+				m_cmbStringName.ResetBackColor();
 				m_btnOK.Enabled = true;
 			}
 			// See ValidateStringNameEx
@@ -196,26 +193,12 @@ namespace KeePass.Forms
 			}
 			else // Edit string field
 			{
-				if(m_strStringName.Equals(strName))
-				{
-					if(m_psStringValue != null)
-					{
-						m_psStringValue.SetString(m_richStringValue.Text);
-						m_psStringValue.EnableProtection(m_cbProtect.Checked);
-					}
-					else
-					{
-						ProtectedString ps = new ProtectedString(m_cbProtect.Checked, m_richStringValue.Text);
-						m_vStringDict.Set(strName, ps);
-					}
-				}
-				else
-				{
+				if(!m_strStringName.Equals(strName))
 					m_vStringDict.Remove(m_strStringName);
 
-					ProtectedString ps = new ProtectedString(m_cbProtect.Checked, m_richStringValue.Text);
-					m_vStringDict.Set(strName, ps);
-				}
+				ProtectedString ps = new ProtectedString(m_cbProtect.Checked,
+					m_richStringValue.Text);
+				m_vStringDict.Set(strName, ps);
 			}
 		}
 
diff --git a/KeePass/Forms/EntropyForm.cs b/KeePass/Forms/EntropyForm.cs
index aa53f6b..3cb6267 100644
--- a/KeePass/Forms/EntropyForm.cs
+++ b/KeePass/Forms/EntropyForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -48,7 +48,7 @@ namespace KeePass.Forms
 
 		public static byte[] CollectEntropyIfEnabled(PwProfile pp)
 		{
-			if(pp.CollectUserEntropy == false) return null;
+			if(!pp.CollectUserEntropy) return null;
 
 			EntropyForm ef = new EntropyForm();
 			if(UIUtil.ShowDialogNotValue(ef, DialogResult.OK)) return null;
diff --git a/KeePass/Forms/EntryListForm.cs b/KeePass/Forms/EntryListForm.cs
index c9ae55c..4a3a67d 100644
--- a/KeePass/Forms/EntryListForm.cs
+++ b/KeePass/Forms/EntryListForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/EntryReportForm.cs b/KeePass/Forms/EntryReportForm.cs
index 469b413..fe76e9a 100644
--- a/KeePass/Forms/EntryReportForm.cs
+++ b/KeePass/Forms/EntryReportForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/ExchangeDataForm.cs b/KeePass/Forms/ExchangeDataForm.cs
index 869abc5..0f5b68b 100644
--- a/KeePass/Forms/ExchangeDataForm.cs
+++ b/KeePass/Forms/ExchangeDataForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/FieldRefForm.cs b/KeePass/Forms/FieldRefForm.cs
index 2bbbe2c..4e791fd 100644
--- a/KeePass/Forms/FieldRefForm.cs
+++ b/KeePass/Forms/FieldRefForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -71,7 +71,6 @@ namespace KeePass.Forms
 			this.Icon = Properties.Resources.KeePass;
 
 			UIUtil.SetExplorerTheme(m_lvEntries.Handle);
-
 			if(UISystemFonts.ListFont != null)
 				m_lvEntries.Font = UISystemFonts.ListFont;
 
diff --git a/KeePass/Forms/FileBrowserForm.cs b/KeePass/Forms/FileBrowserForm.cs
index a75cf76..757452f 100644
--- a/KeePass/Forms/FileBrowserForm.cs
+++ b/KeePass/Forms/FileBrowserForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -105,7 +105,6 @@ namespace KeePass.Forms
 				UIUtil.SetExplorerTheme(m_tvFolders.Handle);
 				UIUtil.SetExplorerTheme(m_lvFiles.Handle);
 			}
-
 			if(UISystemFonts.ListFont != null)
 			{
 				m_tvFolders.Font = UISystemFonts.ListFont;
diff --git a/KeePass/Forms/GroupForm.cs b/KeePass/Forms/GroupForm.cs
index b3234a5..d78454d 100644
--- a/KeePass/Forms/GroupForm.cs
+++ b/KeePass/Forms/GroupForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/HelpSourceForm.cs b/KeePass/Forms/HelpSourceForm.cs
index 85265b4..ee56311 100644
--- a/KeePass/Forms/HelpSourceForm.cs
+++ b/KeePass/Forms/HelpSourceForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/IOConnectionForm.Designer.cs b/KeePass/Forms/IOConnectionForm.Designer.cs
index 5d2b200..cf4aec3 100644
--- a/KeePass/Forms/IOConnectionForm.Designer.cs
+++ b/KeePass/Forms/IOConnectionForm.Designer.cs
@@ -28,7 +28,6 @@
 		/// </summary>
 		private void InitializeComponent()
 		{
-			this.components = new System.ComponentModel.Container();
 			this.m_bannerImage = new System.Windows.Forms.PictureBox();
 			this.m_btnOK = new System.Windows.Forms.Button();
 			this.m_btnCancel = new System.Windows.Forms.Button();
@@ -41,7 +40,6 @@
 			this.m_lblSeparator = new System.Windows.Forms.Label();
 			this.m_lblCredNote = new System.Windows.Forms.Label();
 			this.m_btnHelp = new System.Windows.Forms.Button();
-			this.m_ttInvalidUrl = new System.Windows.Forms.ToolTip(this.components);
 			this.m_cmbCredSaveMode = new System.Windows.Forms.ComboBox();
 			this.m_lblRemember = new System.Windows.Forms.Label();
 			this.m_lblUrlExamples = new System.Windows.Forms.Label();
@@ -64,7 +62,7 @@
 			this.m_btnOK.Location = new System.Drawing.Point(253, 281);
 			this.m_btnOK.Name = "m_btnOK";
 			this.m_btnOK.Size = new System.Drawing.Size(75, 23);
-			this.m_btnOK.TabIndex = 9;
+			this.m_btnOK.TabIndex = 11;
 			this.m_btnOK.Text = "&OK";
 			this.m_btnOK.UseVisualStyleBackColor = true;
 			this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK);
@@ -75,7 +73,7 @@
 			this.m_btnCancel.Location = new System.Drawing.Point(334, 281);
 			this.m_btnCancel.Name = "m_btnCancel";
 			this.m_btnCancel.Size = new System.Drawing.Size(75, 23);
-			this.m_btnCancel.TabIndex = 10;
+			this.m_btnCancel.TabIndex = 12;
 			this.m_btnCancel.Text = "&Cancel";
 			this.m_btnCancel.UseVisualStyleBackColor = true;
 			this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel);
@@ -102,7 +100,7 @@
 			this.m_lblUserName.Location = new System.Drawing.Point(12, 161);
 			this.m_lblUserName.Name = "m_lblUserName";
 			this.m_lblUserName.Size = new System.Drawing.Size(61, 13);
-			this.m_lblUserName.TabIndex = 2;
+			this.m_lblUserName.TabIndex = 4;
 			this.m_lblUserName.Text = "User name:";
 			// 
 			// m_tbUserName
@@ -110,7 +108,7 @@
 			this.m_tbUserName.Location = new System.Drawing.Point(89, 158);
 			this.m_tbUserName.Name = "m_tbUserName";
 			this.m_tbUserName.Size = new System.Drawing.Size(121, 20);
-			this.m_tbUserName.TabIndex = 3;
+			this.m_tbUserName.TabIndex = 5;
 			// 
 			// m_lblPassword
 			// 
@@ -118,7 +116,7 @@
 			this.m_lblPassword.Location = new System.Drawing.Point(216, 161);
 			this.m_lblPassword.Name = "m_lblPassword";
 			this.m_lblPassword.Size = new System.Drawing.Size(56, 13);
-			this.m_lblPassword.TabIndex = 4;
+			this.m_lblPassword.TabIndex = 6;
 			this.m_lblPassword.Text = "Password:";
 			// 
 			// m_tbPassword
@@ -126,7 +124,7 @@
 			this.m_tbPassword.Location = new System.Drawing.Point(287, 158);
 			this.m_tbPassword.Name = "m_tbPassword";
 			this.m_tbPassword.Size = new System.Drawing.Size(122, 20);
-			this.m_tbPassword.TabIndex = 5;
+			this.m_tbPassword.TabIndex = 7;
 			this.m_tbPassword.UseSystemPasswordChar = true;
 			// 
 			// m_lblSeparator
@@ -135,14 +133,14 @@
 			this.m_lblSeparator.Location = new System.Drawing.Point(0, 270);
 			this.m_lblSeparator.Name = "m_lblSeparator";
 			this.m_lblSeparator.Size = new System.Drawing.Size(421, 2);
-			this.m_lblSeparator.TabIndex = 12;
+			this.m_lblSeparator.TabIndex = 13;
 			// 
 			// m_lblCredNote
 			// 
 			this.m_lblCredNote.Location = new System.Drawing.Point(12, 190);
 			this.m_lblCredNote.Name = "m_lblCredNote";
 			this.m_lblCredNote.Size = new System.Drawing.Size(397, 26);
-			this.m_lblCredNote.TabIndex = 6;
+			this.m_lblCredNote.TabIndex = 8;
 			this.m_lblCredNote.Text = "The credentials you enter here are used to authenticate you against the server. D" +
 				"o not enter your KeePass database master password.";
 			// 
@@ -151,18 +149,11 @@
 			this.m_btnHelp.Location = new System.Drawing.Point(12, 281);
 			this.m_btnHelp.Name = "m_btnHelp";
 			this.m_btnHelp.Size = new System.Drawing.Size(75, 23);
-			this.m_btnHelp.TabIndex = 11;
+			this.m_btnHelp.TabIndex = 14;
 			this.m_btnHelp.Text = "&Help";
 			this.m_btnHelp.UseVisualStyleBackColor = true;
 			this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp);
 			// 
-			// m_ttInvalidUrl
-			// 
-			this.m_ttInvalidUrl.AutoPopDelay = 32000;
-			this.m_ttInvalidUrl.InitialDelay = 250;
-			this.m_ttInvalidUrl.IsBalloon = true;
-			this.m_ttInvalidUrl.ReshowDelay = 100;
-			// 
 			// m_cmbCredSaveMode
 			// 
 			this.m_cmbCredSaveMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@@ -170,7 +161,7 @@
 			this.m_cmbCredSaveMode.Location = new System.Drawing.Point(91, 228);
 			this.m_cmbCredSaveMode.Name = "m_cmbCredSaveMode";
 			this.m_cmbCredSaveMode.Size = new System.Drawing.Size(318, 21);
-			this.m_cmbCredSaveMode.TabIndex = 8;
+			this.m_cmbCredSaveMode.TabIndex = 10;
 			// 
 			// m_lblRemember
 			// 
@@ -178,7 +169,7 @@
 			this.m_lblRemember.Location = new System.Drawing.Point(12, 231);
 			this.m_lblRemember.Name = "m_lblRemember";
 			this.m_lblRemember.Size = new System.Drawing.Size(61, 13);
-			this.m_lblRemember.TabIndex = 7;
+			this.m_lblRemember.TabIndex = 9;
 			this.m_lblRemember.Text = "Remember:";
 			// 
 			// m_lblUrlExamples
@@ -187,7 +178,7 @@
 			this.m_lblUrlExamples.Location = new System.Drawing.Point(86, 131);
 			this.m_lblUrlExamples.Name = "m_lblUrlExamples";
 			this.m_lblUrlExamples.Size = new System.Drawing.Size(284, 13);
-			this.m_lblUrlExamples.TabIndex = 13;
+			this.m_lblUrlExamples.TabIndex = 3;
 			this.m_lblUrlExamples.Text = "Example: ftp://ftp.someserver.com/pub/MyDatabase.kdbx";
 			// 
 			// m_lblUrlHints
@@ -195,7 +186,7 @@
 			this.m_lblUrlHints.Location = new System.Drawing.Point(86, 102);
 			this.m_lblUrlHints.Name = "m_lblUrlHints";
 			this.m_lblUrlHints.Size = new System.Drawing.Size(321, 29);
-			this.m_lblUrlHints.TabIndex = 14;
+			this.m_lblUrlHints.TabIndex = 2;
 			this.m_lblUrlHints.Text = "The complete URL must be specified, including protocol, server and full path to t" +
 				"he file.";
 			// 
@@ -252,7 +243,6 @@
 		private System.Windows.Forms.Label m_lblSeparator;
 		private System.Windows.Forms.Label m_lblCredNote;
 		private System.Windows.Forms.Button m_btnHelp;
-		private System.Windows.Forms.ToolTip m_ttInvalidUrl;
 		private System.Windows.Forms.ComboBox m_cmbCredSaveMode;
 		private System.Windows.Forms.Label m_lblRemember;
 		private System.Windows.Forms.Label m_lblUrlExamples;
diff --git a/KeePass/Forms/IOConnectionForm.cs b/KeePass/Forms/IOConnectionForm.cs
index 2668a19..3143abd 100644
--- a/KeePass/Forms/IOConnectionForm.cs
+++ b/KeePass/Forms/IOConnectionForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -115,10 +115,11 @@ namespace KeePass.Forms
 		private void OnBtnOK(object sender, EventArgs e)
 		{
 			string strUrl = m_tbUrl.Text;
-
-			if(strUrl.IndexOf(@"://") < 0)
+			if(strUrl.IndexOf("://") < 0)
 			{
-				m_ttInvalidUrl.Show(KPRes.InvalidUrl, m_tbUrl);
+				// m_ttInvalidUrl.Show(KPRes.InvalidUrl, m_tbUrl);
+				MessageService.ShowWarning(strUrl, KPRes.InvalidUrl);
+				this.DialogResult = DialogResult.None;
 				return;
 			}
 
@@ -135,7 +136,7 @@ namespace KeePass.Forms
 
 			if(m_bTestConnection && !m_bSave)
 			{
-				if(this.TestConnectionEx() == false)
+				if(!TestConnectionEx())
 					this.DialogResult = DialogResult.None;
 			}
 		}
diff --git a/KeePass/Forms/IOConnectionForm.resx b/KeePass/Forms/IOConnectionForm.resx
index c3e8c64..ff31a6d 100644
--- a/KeePass/Forms/IOConnectionForm.resx
+++ b/KeePass/Forms/IOConnectionForm.resx
@@ -117,7 +117,4 @@
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <metadata name="m_ttInvalidUrl.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 17</value>
-  </metadata>
 </root>
\ No newline at end of file
diff --git a/KeePass/Forms/IconPickerForm.cs b/KeePass/Forms/IconPickerForm.cs
index 70bdafc..8d88515 100644
--- a/KeePass/Forms/IconPickerForm.cs
+++ b/KeePass/Forms/IconPickerForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -265,6 +265,8 @@ namespace KeePass.Forms
 							ms.ToArray());
 						m_pwDatabase.CustomIcons.Add(pwci);
 
+						ms.Close();
+
 						m_pwDatabase.UINeedsIconUpdate = true;
 						bSelectLastIcon = true;
 					}
diff --git a/KeePass/Forms/ImportCsvForm.cs b/KeePass/Forms/ImportCsvForm.cs
index 766c60f..3b9916f 100644
--- a/KeePass/Forms/ImportCsvForm.cs
+++ b/KeePass/Forms/ImportCsvForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/ImportMethodForm.cs b/KeePass/Forms/ImportMethodForm.cs
index 67c266a..cdbdd74 100644
--- a/KeePass/Forms/ImportMethodForm.cs
+++ b/KeePass/Forms/ImportMethodForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/InternalBrowserForm.cs b/KeePass/Forms/InternalBrowserForm.cs
index f8fc293..7a889c1 100644
--- a/KeePass/Forms/InternalBrowserForm.cs
+++ b/KeePass/Forms/InternalBrowserForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/KeyCreationForm.Designer.cs b/KeePass/Forms/KeyCreationForm.Designer.cs
index 3a2487c..819afb9 100644
--- a/KeePass/Forms/KeyCreationForm.Designer.cs
+++ b/KeePass/Forms/KeyCreationForm.Designer.cs
@@ -189,7 +189,6 @@
 			this.m_cbHidePassword.Size = new System.Drawing.Size(32, 23);
 			this.m_cbHidePassword.TabIndex = 1;
 			this.m_cbHidePassword.UseVisualStyleBackColor = true;
-			this.m_cbHidePassword.CheckedChanged += new System.EventHandler(this.OnCheckedHidePassword);
 			// 
 			// m_btnSaveKeyFile
 			// 
diff --git a/KeePass/Forms/KeyCreationForm.cs b/KeePass/Forms/KeyCreationForm.cs
index a272c58..acd5b4c 100644
--- a/KeePass/Forms/KeyCreationForm.cs
+++ b/KeePass/Forms/KeyCreationForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -47,8 +47,7 @@ namespace KeePass.Forms
 		private bool m_bCreatingNew = false;
 		private IOConnectionInfo m_ioInfo = new IOConnectionInfo();
 
-		private SecureEdit m_secPassword = new SecureEdit();
-		private SecureEdit m_secRepeat = new SecureEdit();
+		private PwInputControlGroup m_icgPassword = new PwInputControlGroup();
 
 		public CompositeKey CompositeKey
 		{
@@ -89,16 +88,14 @@ namespace KeePass.Forms
 			m_ttRect.SetToolTip(m_cbHidePassword, KPRes.TogglePasswordAsterisks);
 			m_ttRect.SetToolTip(m_btnSaveKeyFile, KPRes.KeyFileCreate);
 			m_ttRect.SetToolTip(m_btnOpenKeyFile, KPRes.KeyFileUseExisting);
+			m_ttRect.SetToolTip(m_tbRepeatPassword, KPRes.PasswordRepeatHint);
 
 			if(!m_bCreatingNew)
 				m_lblIntro.Text = KPRes.ChangeMasterKeyIntroShort;
 
-			m_secPassword.Attach(m_tbPassword, ProcessTextChangedPassword, true);
-			m_secRepeat.Attach(m_tbRepeatPassword, null, true);
-			m_cbHidePassword.Checked = true;
-
-			m_cbPassword.Checked = true;
-			ProcessTextChangedPassword(sender, e); // Update quality estimation
+			m_icgPassword.Attach(m_tbPassword, m_cbHidePassword, m_lblRepeatPassword,
+				m_tbRepeatPassword, m_lblEstimatedQuality, m_pbPasswordQuality,
+				m_lblQualityBits, this, true, false);
 
 			m_cmbKeyFile.Items.Add(KPRes.NoKeyFileSpecifiedMeta);
 			foreach(KeyProvider prov in Program.KeyProviderPool)
@@ -106,6 +103,7 @@ namespace KeePass.Forms
 
 			m_cmbKeyFile.SelectedIndex = 0;
 
+			m_cbPassword.Checked = true;
 			UIUtil.ApplyKeyUIFlags(Program.Config.UI.KeyCreationFlags,
 				m_cbPassword, m_cbKeyFile, m_cbUserAccount, m_cbHidePassword);
 
@@ -130,8 +128,7 @@ namespace KeePass.Forms
 
 		private void CleanUpEx()
 		{
-			m_secPassword.Detach();
-			m_secRepeat.Detach();
+			m_icgPassword.Release();
 		}
 
 		private bool CreateCompositeKey()
@@ -140,13 +137,10 @@ namespace KeePass.Forms
 
 			if(m_cbPassword.Checked) // Use a password
 			{
-				if(m_secPassword.ContentsEqualTo(m_secRepeat) == false)
-				{
-					MessageService.ShowWarning(KPRes.PasswordRepeatFailed);
-					return false;
-				}
+				if(!m_icgPassword.ValidateData(true)) return false;
 
-				if(m_secPassword.TextLength == 0)
+				uint uPwLen = m_icgPassword.PasswordLength;
+				if(uPwLen == 0)
 				{
 					if(!MessageService.AskYesNo(KPRes.EmptyMasterPw +
 						MessageService.NewParagraph + KPRes.EmptyMasterPwHint +
@@ -158,7 +152,7 @@ namespace KeePass.Forms
 				}
 
 				uint uMinLen = Program.Config.Security.MasterPassword.MinimumLength;
-				if(m_secPassword.TextLength < uMinLen)
+				if(uPwLen < uMinLen)
 				{
 					string strML = KPRes.MasterPasswordMinLengthFailed;
 					strML = strML.Replace(@"{PARAM}", uMinLen.ToString());
@@ -166,7 +160,7 @@ namespace KeePass.Forms
 					return false;
 				}
 
-				byte[] pb = m_secPassword.ToUtf8();
+				byte[] pb = m_icgPassword.GetPasswordUtf8();
 
 				uint uMinQual = Program.Config.Security.MasterPassword.MinimumQuality;
 				if(QualityEstimation.EstimatePasswordBits(pb) < uMinQual)
@@ -242,12 +236,7 @@ namespace KeePass.Forms
 
 		private void EnableUserControls()
 		{
-			m_tbPassword.Enabled = m_tbRepeatPassword.Enabled =
-				m_lblRepeatPassword.Enabled = m_lblQualityBits.Enabled =
-				m_lblEstimatedQuality.Enabled = m_cbPassword.Checked;
-			if((Program.Config.UI.KeyCreationFlags &
-				(ulong)AceKeyUIFlags.DisableHidePassword) == 0)
-				m_cbHidePassword.Enabled = m_cbPassword.Checked;
+			m_icgPassword.Enabled = m_cbPassword.Checked;
 
 			m_btnOpenKeyFile.Enabled = m_btnSaveKeyFile.Enabled =
 				m_cmbKeyFile.Enabled = m_cbKeyFile.Checked;
@@ -260,19 +249,9 @@ namespace KeePass.Forms
 				m_btnCreate.Enabled = false;
 			else m_btnCreate.Enabled = true;
 
-			SetHidePassword(m_cbHidePassword.Checked, false);
-
 			m_ttRect.SetToolTip(m_cmbKeyFile, strKeyFile);
 		}
 
-		private void SetHidePassword(bool bHide, bool bUpdateCheckBox)
-		{
-			if(bUpdateCheckBox) m_cbHidePassword.Checked = bHide;
-
-			m_secPassword.EnableProtection(bHide);
-			m_secRepeat.EnableProtection(bHide);
-		}
-
 		private void OnCheckedPassword(object sender, EventArgs e)
 		{
 			EnableUserControls();
@@ -285,19 +264,6 @@ namespace KeePass.Forms
 			EnableUserControls();
 		}
 
-		private void OnCheckedHidePassword(object sender, EventArgs e)
-		{
-			bool bHide = m_cbHidePassword.Checked;
-			if(!bHide && !AppPolicy.Try(AppPolicyId.UnhidePasswords))
-			{
-				m_cbHidePassword.Checked = true;
-				return;
-			}
-
-			SetHidePassword(bHide, false);
-			UIUtil.SetFocus(m_tbPassword, this);
-		}
-
 		private void OnBtnOK(object sender, EventArgs e)
 		{
 			if(!CreateCompositeKey()) this.DialogResult = DialogResult.None;
@@ -308,18 +274,6 @@ namespace KeePass.Forms
 			m_pKey = null;
 		}
 
-		private void ProcessTextChangedPassword(object sender, EventArgs e)
-		{
-			byte[] pbUTF8 = m_secPassword.ToUtf8();
-			uint uBits = QualityEstimation.EstimatePasswordBits(pbUTF8);
-			MemUtil.ZeroByteArray(pbUTF8);
-
-			m_lblQualityBits.Text = uBits.ToString() + " " + KPRes.Bits;
-			int iPos = (int)((100 * uBits) / (256 / 2));
-			if(iPos < 0) iPos = 0; else if(iPos > 100) iPos = 100;
-			m_pbPasswordQuality.Value = iPos;
-		}
-
 		private void OnClickKeyFileCreate(object sender, EventArgs e)
 		{
 			SaveFileDialog sfd = UIUtil.CreateSaveFileDialog(KPRes.KeyFileCreate,
diff --git a/KeePass/Forms/KeyPromptForm.cs b/KeePass/Forms/KeyPromptForm.cs
index ff544e9..383784a 100644
--- a/KeePass/Forms/KeyPromptForm.cs
+++ b/KeePass/Forms/KeyPromptForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -253,15 +253,10 @@ namespace KeePass.Forms
 				KeyProvider kp = Program.KeyProviderPool.Get(strKeyFile);
 				if((kp != null) && m_bSecureDesktop)
 				{
-					if(kp.GetKeyMightShowGui && !kp.SecureDesktopCompatible)
+					if(!kp.SecureDesktopCompatible)
 					{
-						MessageService.ShowWarning(KPRes.KeyProvWithGuiOnSD,
-							KPRes.KeyProvWithGuiOnSDHint);
-						return false;
-					}
-					else if(!kp.SecureDesktopCompatible)
-					{
-						MessageService.ShowWarning(KPRes.KeyProvWithGuiOnSDHint);
+						MessageService.ShowWarning(KPRes.KeyProvIncmpWithSD,
+							KPRes.KeyProvIncmpWithSDHint);
 						return false;
 					}
 				}
@@ -391,6 +386,8 @@ namespace KeePass.Forms
 			}
 
 			m_secPassword.EnableProtection(bHide);
+
+			if(!m_bInitializing) UIUtil.SetFocus(m_tbPassword, this);
 		}
 
 		private void OnBtnOK(object sender, EventArgs e)
diff --git a/KeePass/Forms/LanguageForm.cs b/KeePass/Forms/LanguageForm.cs
index 4cf052f..20fafab 100644
--- a/KeePass/Forms/LanguageForm.cs
+++ b/KeePass/Forms/LanguageForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/MainForm.cs b/KeePass/Forms/MainForm.cs
index aaeedba..45099b8 100644
--- a/KeePass/Forms/MainForm.cs
+++ b/KeePass/Forms/MainForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -121,13 +121,13 @@ namespace KeePass.Forms
 			m_splitVertical.InitEx(this.Controls, m_menuMain);
 
 			AssignMenuShortcuts();
-			AssignMenuShortcutsOpt();
 
 			if(NativeLib.IsUnix())
 			{
 				// Workaround for tab bar height bug in Mono
 				// https://sourceforge.net/projects/keepass/forums/forum/329221/topic/4519750
-				m_tabMain.Height += 3;
+				// https://bugs.launchpad.net/ubuntu/+source/keepass2/+bug/891029
+				m_tabMain.Height += 5;
 			}
 		}
 
@@ -192,29 +192,33 @@ namespace KeePass.Forms
 			InsertToolStripItem(m_menuEdit, m_ctxEntryDelete, new EventHandler(OnEntryDelete), true);
 			InsertToolStripItem(m_menuEdit, m_ctxEntryDuplicate, new EventHandler(OnEntryDuplicate), true);
 			InsertToolStripItem(m_menuEdit, m_ctxEntryEdit, new EventHandler(OnEntryEdit), true);
-			InsertToolStripItem(m_menuEdit, m_ctxEntryAdd, new EventHandler(OnEntryAdd), true);
+			ToolStripMenuItem tsmiAddEntry = InsertToolStripItem(m_menuEdit,
+				m_ctxEntryAdd, new EventHandler(OnEntryAdd), true);
 			m_menuEdit.DropDownItems.Insert(0, new ToolStripSeparator());
 			InsertToolStripItem(m_menuEdit, m_ctxGroupDelete, new EventHandler(OnGroupsDelete), true);
 			InsertToolStripItem(m_menuEdit, m_ctxGroupEdit, new EventHandler(OnGroupsEdit), true);
 			InsertToolStripItem(m_menuEdit, m_ctxGroupAdd, new EventHandler(OnGroupsAdd), true);
 
-			UIUtil.ConfigureTbButton(m_tbNewDatabase, KPRes.ToolBarNew, null);
-			UIUtil.ConfigureTbButton(m_tbOpenDatabase, KPRes.ToolBarOpen, null);
-			UIUtil.ConfigureTbButton(m_tbSaveDatabase, KPRes.Save, null);
-			UIUtil.ConfigureTbButton(m_tbSaveAll, KPRes.ToolBarSaveAll, null);
-			UIUtil.ConfigureTbButton(m_tbAddEntry, KPRes.AddEntry, null);
-			UIUtil.ConfigureTbButton(m_tbAddEntryDefault, KPRes.AddEntryBtn, null);
-			UIUtil.ConfigureTbButton(m_tbCopyUserName, KPRes.CopyUserFull, null);
-			UIUtil.ConfigureTbButton(m_tbCopyPassword, KPRes.CopyPasswordFull, null);
-			UIUtil.ConfigureTbButton(m_tbFind, KPRes.Find + "...", null);
-			UIUtil.ConfigureTbButton(m_tbEntryViewsDropDown, null, KPRes.ShowEntries);
-			UIUtil.ConfigureTbButton(m_tbViewsShowAll, KPRes.ShowAllEntries, null);
-			UIUtil.ConfigureTbButton(m_tbViewsShowExpired, KPRes.ShowExpiredEntries, null);
-			UIUtil.ConfigureTbButton(m_tbLockWorkspace, KPRes.LockMenuLock, null);
+			UIUtil.AssignShortcut(tsmiAddEntry, Keys.Control | Keys.I);
+
+			UIUtil.ConfigureTbButton(m_tbNewDatabase, KPRes.ToolBarNew, null, m_menuFileNew);
+			UIUtil.ConfigureTbButton(m_tbOpenDatabase, KPRes.ToolBarOpen, null, m_menuFileOpenLocal);
+			UIUtil.ConfigureTbButton(m_tbSaveDatabase, KPRes.Save, null, m_menuFileSave);
+			UIUtil.ConfigureTbButton(m_tbSaveAll, KPRes.ToolBarSaveAll, null, null);
+			UIUtil.ConfigureTbButton(m_tbAddEntry, KPRes.AddEntry, null, null);
+			UIUtil.ConfigureTbButton(m_tbCopyUserName, KPRes.CopyUserFull, null, m_ctxEntryCopyUserName);
+			UIUtil.ConfigureTbButton(m_tbCopyPassword, KPRes.CopyPasswordFull, null, m_ctxEntryCopyPassword);
+			UIUtil.ConfigureTbButton(m_tbFind, KPRes.Find + "...", null, m_menuEditFind);
+			UIUtil.ConfigureTbButton(m_tbEntryViewsDropDown, null, KPRes.ShowEntries, null);
+			UIUtil.ConfigureTbButton(m_tbLockWorkspace, KPRes.LockMenuLock, null, m_menuFileLock);
 			UIUtil.ConfigureTbButton(m_tbQuickFind, null, KPRes.SearchQuickPrompt +
-				" (" + KPRes.KeyboardKeyCtrl + "+E)");
+				" (" + KPRes.KeyboardKeyCtrl + "+E)", null);
 			UIUtil.ConfigureTbButton(m_tbCloseTab, StrUtil.RemoveAccelerator(
-				KPRes.CloseButton), null);
+				KPRes.CloseButton), null, m_menuFileClose);
+
+			CopyMenuItemText(m_tbAddEntryDefault, m_ctxEntryAdd);
+			CopyMenuItemText(m_tbViewsShowAll, m_menuEditShowAllEntries);
+			CopyMenuItemText(m_tbViewsShowExpired, m_menuEditShowExpired);
 
 			UIUtil.EnableAutoCompletion(m_tbQuickFind, false);
 
@@ -303,6 +307,8 @@ namespace KeePass.Forms
 				UIUtil.SetExplorerTheme(m_lvEntries.Handle);
 			}
 
+			// m_tvGroups.QueryToolTip = UIUtil.GetPwGroupToolTipTN;
+
 			m_clrAlternateItemBgColor = UIUtil.GetAlternateColor(m_lvEntries.BackColor);
 
 			m_statusPartProgress.Visible = false;
@@ -394,8 +400,10 @@ namespace KeePass.Forms
 					OpenDatabase(ioLastFile, null, false);
 			}
 
+			UpdateCheckEx.EnsureConfigured(this);
 			if(Program.Config.Application.Start.CheckForUpdate)
-				CheckForUpdate.StartAsync(PwDefs.VersionUrl, m_statusPartInfo);
+				UpdateCheckEx.Run(false, null);
+			// UpdateCheck.StartAsync(PwDefs.VersionUrl, m_statusPartInfo);
 
 			ResetDefaultFocus(null);
 
@@ -712,7 +720,8 @@ namespace KeePass.Forms
 
 		private void OnHelpCheckForUpdate(object sender, EventArgs e)
 		{
-			CheckForUpdate.StartAsync(PwDefs.VersionUrl, null);
+			// UpdateCheck.StartAsync(PwDefs.VersionUrl, null);
+			UpdateCheckEx.Run(true, this);
 		}
 
 		private void OnHelpAbout(object sender, EventArgs e)
@@ -795,13 +804,12 @@ namespace KeePass.Forms
 			PwDatabase pwDb = m_docMgr.ActiveDatabase;
 			PwEntry pwe = new PwEntry(true, true);
 			pwe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
-				pwDb.MemoryProtection.ProtectUserName,
-				pwDb.DefaultUserName));
+				pwDb.MemoryProtection.ProtectUserName, pwDb.DefaultUserName));
 
-			ProtectedString psAutoGen = new ProtectedString(
-				pwDb.MemoryProtection.ProtectPassword);
-			PwGenerator.Generate(psAutoGen, Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile,
+			ProtectedString psAutoGen;
+			PwGenerator.Generate(out psAutoGen, Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile,
 				null, Program.PwGeneratorPool);
+			psAutoGen = psAutoGen.WithProtection(pwDb.MemoryProtection.ProtectPassword);
 			pwe.Strings.Set(PwDefs.PasswordField, psAutoGen);
 
 			int nExpireDays = Program.Config.Defaults.NewEntryExpiresInDays;
@@ -946,6 +954,8 @@ namespace KeePass.Forms
 				return;
 			}
 
+			GlobalWindowManager.CloseAllWindows();
+
 			CleanUpEx(); // Saves configuration and cleans up all resources
 
 			if(m_bRestart) WinUtil.Restart();
@@ -1186,8 +1196,6 @@ namespace KeePass.Forms
 				m_mruList.MaxItemCount = Program.Config.Application.MostRecentlyUsed.MaxItemCount;
 				SetListFont(Program.Config.UI.StandardFont);
 
-				AssignMenuShortcutsOpt();
-
 				if(ofDlg.RequiresUIReinitialize) UIUtil.Initialize(true);
 
 				AppConfigSerializer.Save(Program.Config);
@@ -1667,7 +1675,11 @@ namespace KeePass.Forms
 					case Keys.C: OnEntryCopyPassword(sender, e); break;
 					case Keys.B: OnEntryCopyUserName(sender, e); break;
 					// case Keys.E: OnEntryEdit(sender, e); break;
-					case Keys.U: PerformDefaultUrlAction(null, false); break;
+					case Keys.U:
+						// PerformDefaultUrlAction(null, false);
+						if(e.Shift) OnEntryCopyURL(sender, e);
+						else OnEntryOpenUrl(sender, e);
+						break;
 					case Keys.V: OnEntryPerformAutoType(sender, e); break;
 					default: bUnhandled = true; break;
 				}
@@ -1783,9 +1795,10 @@ namespace KeePass.Forms
 
 					byte[] pbAdditionalEntropy = EntropyForm.CollectEntropyIfEnabled(
 						pgf.SelectedProfile);
-					ProtectedString psNew = new ProtectedString(pwDb.MemoryProtection.ProtectPassword);
-					PwGenerator.Generate(psNew, pgf.SelectedProfile, pbAdditionalEntropy,
-						Program.PwGeneratorPool);
+					ProtectedString psNew;
+					PwGenerator.Generate(out psNew, pgf.SelectedProfile,
+						pbAdditionalEntropy, Program.PwGeneratorPool);
+					psNew = psNew.WithProtection(pwDb.MemoryProtection.ProtectPassword);
 					pe.Strings.Set(PwDefs.PasswordField, psNew);
 
 					UpdateUI(false, null, false, null, true, null, true);
@@ -1804,7 +1817,7 @@ namespace KeePass.Forms
 
 		private void OnToolsShowExpired(object sender, EventArgs e)
 		{
-			ShowExpiredEntries(false, 0);
+			ShowExpiredEntries(false, true, false);
 		}
 
 		private void OnToolsTanWizard(object sender, EventArgs e)
@@ -2073,9 +2086,10 @@ namespace KeePass.Forms
 						PwEntry pe = new PwEntry(true, true);
 						pg.AddEntry(pe, true);
 
-						ProtectedString psNew = new ProtectedString(pwDb.MemoryProtection.ProtectPassword);
-						PwGenerator.Generate(psNew, pgf.SelectedProfile,
+						ProtectedString psNew;
+						PwGenerator.Generate(out psNew, pgf.SelectedProfile,
 							pbAdditionalEntropy, Program.PwGeneratorPool);
+						psNew = psNew.WithProtection(pwDb.MemoryProtection.ProtectPassword);
 						pe.Strings.Set(PwDefs.PasswordField, psNew);
 					}
 
@@ -2461,7 +2475,8 @@ namespace KeePass.Forms
 			if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return; }
 
 			uint uDeleted = pd.DeleteUnusedCustomIcons();
-			UpdateUIState(uDeleted > 0);
+			UpdateUI(false, null, (uDeleted > 0), null, (uDeleted > 0),
+				null, (uDeleted > 0));
 			SetObjectsDeletedStatus(uDeleted, true);
 		}
 
diff --git a/KeePass/Forms/MainForm_Events.cs b/KeePass/Forms/MainForm_Events.cs
index 00ed778..f01a0b6 100644
--- a/KeePass/Forms/MainForm_Events.cs
+++ b/KeePass/Forms/MainForm_Events.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/MainForm_Functions.cs b/KeePass/Forms/MainForm_Functions.cs
index aefaa25..968b48b 100644
--- a/KeePass/Forms/MainForm_Functions.cs
+++ b/KeePass/Forms/MainForm_Functions.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -469,9 +469,9 @@ namespace KeePass.Forms
 
 			// Main menu
 			m_menuFileSaveAs.Enabled = m_menuFileSaveAsLocal.Enabled =
-				m_menuFileSaveAsUrl.Enabled = m_menuFileDbSettings.Enabled =
-				m_menuFileChangeMasterKey.Enabled = m_menuFilePrint.Enabled =
-				s.DatabaseOpened;
+				m_menuFileSaveAsUrl.Enabled = m_menuFileSaveAsCopy.Enabled =
+				m_menuFileDbSettings.Enabled = m_menuFileChangeMasterKey.Enabled =
+				m_menuFilePrint.Enabled = s.DatabaseOpened;
 
 			m_menuFileClose.Enabled = (s.DatabaseOpened || s.FileLocked);
 
@@ -520,8 +520,10 @@ namespace KeePass.Forms
 			m_tbCopyPassword.Enabled = s.CanCopyPassword;
 
 			m_menuFileLock.Text = s.LockUnlock;
-			m_tbLockWorkspace.Text = m_tbLockWorkspace.ToolTipText =
-				m_ctxTrayLock.Text = StrUtil.RemoveAccelerator(s.LockUnlock);
+			string strLockText = StrUtil.RemoveAccelerator(s.LockUnlock);
+			m_tbLockWorkspace.Text = m_ctxTrayLock.Text = strLockText;
+			m_tbLockWorkspace.ToolTipText = strLockText + " (" +
+				m_menuFileLock.ShortcutKeyDisplayString + ")";
 
 			m_tabMain.Visible = m_tbSaveAll.Visible = m_tbCloseTab.Visible =
 				(m_docMgr.DocumentCount > 1);
@@ -1433,26 +1435,26 @@ namespace KeePass.Forms
 			PwGroup pg = pe.ParentGroup;
 			if(pg != null) rb.Append(pg.Name);
 
+			AceMainWindow mw = Program.Config.MainWindow;
 			EvAppendEntryField(rb, strItemSeparator, KPRes.Title,
-				IsColumnHidden(AceColumnType.Title) ? PwDefs.HiddenPassword :
+				mw.IsColumnHidden(AceColumnType.Title) ? PwDefs.HiddenPassword :
 				pe.Strings.ReadSafe(PwDefs.TitleField), pe);
 			EvAppendEntryField(rb, strItemSeparator, KPRes.UserName,
-				IsColumnHidden(AceColumnType.UserName) ? PwDefs.HiddenPassword :
+				mw.IsColumnHidden(AceColumnType.UserName) ? PwDefs.HiddenPassword :
 				pe.Strings.ReadSafe(PwDefs.UserNameField), pe);
 			EvAppendEntryField(rb, strItemSeparator, KPRes.Password,
-				IsColumnHidden(AceColumnType.Password) ? PwDefs.HiddenPassword :
+				mw.IsColumnHidden(AceColumnType.Password) ? PwDefs.HiddenPassword :
 				pe.Strings.ReadSafe(PwDefs.PasswordField), pe);
 			EvAppendEntryField(rb, strItemSeparator, KPRes.Url,
-				IsColumnHidden(AceColumnType.Url) ? PwDefs.HiddenPassword :
+				mw.IsColumnHidden(AceColumnType.Url) ? PwDefs.HiddenPassword :
 				pe.Strings.ReadSafe(PwDefs.UrlField), pe);
 
-			bool bHideCustom = Program.Config.MainWindow.EntryView.HideProtectedCustomStrings;
 			foreach(KeyValuePair<string, ProtectedString> kvp in pe.Strings)
 			{
 				if(PwDefs.IsStandardField(kvp.Key)) continue;
 
-				string strCustomValue = (bHideCustom ? pe.Strings.ReadSafeEx(kvp.Key) :
-					pe.Strings.ReadSafe(kvp.Key));
+				string strCustomValue = (mw.ShouldHideCustomString(kvp.Key,
+					kvp.Value) ? PwDefs.HiddenPassword : kvp.Value.ReadString());
 				EvAppendEntryField(rb, strItemSeparator, kvp.Key, strCustomValue, pe);
 			}
 
@@ -1486,7 +1488,7 @@ namespace KeePass.Forms
 			EvAppendEntryField(rb, strItemSeparator, KPRes.Tags,
 				StrUtil.TagsToString(pe.Tags, true), null);
 
-			string strNotes = (IsColumnHidden(AceColumnType.Notes) ?
+			string strNotes = (mw.IsColumnHidden(AceColumnType.Notes) ?
 				PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.NotesField));
 			if(strNotes.Length != 0)
 			{
@@ -1797,39 +1799,39 @@ namespace KeePass.Forms
 			}
 		}
 
-		private void ShowExpiredEntries(bool bOnlyIfExists, uint uSkipDays)
+		private void ShowExpiredEntries(bool bOnlyIfExists, bool bShowExpired,
+			bool bShowSoonToExpire)
 		{
-			PwGroup pg = new PwGroup(true, true, KPRes.ExpiredEntries, PwIcon.Expired);
+			if(!bShowExpired && !bShowSoonToExpire) return;
+
+			PwGroup pg = new PwGroup(true, true, string.Empty, PwIcon.Expired);
 			pg.IsVirtual = true;
 
-			DateTime dtLimit = DateTime.Now;
-			if(uSkipDays != 0)
-				dtLimit = dtLimit.Add(new TimeSpan((int)uSkipDays, 0, 0, 0));
+			const int iSkipDays = 7;
+			DateTime dtNow = DateTime.Now;
+			DateTime dtLimit = dtNow.Add(new TimeSpan(iSkipDays, 0, 0, 0));
 
 			EntryHandler eh = delegate(PwEntry pe)
 			{
+				if(!pe.Expires) return true;
 				if(PwDefs.IsTanEntry(pe)) return true; // Exclude TANs
-				if(pe.Expires && (pe.ExpiryTime <= dtLimit))
+
+				if((bShowExpired && (pe.ExpiryTime <= dtNow)) ||
+					(bShowSoonToExpire && (pe.ExpiryTime <= dtLimit) &&
+					(pe.ExpiryTime > dtNow)))
 					pg.AddEntry(pe, false);
 				return true;
 			};
 
-			m_docMgr.ActiveDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh);
-
-			if(uSkipDays != 0) pg.Name = KPRes.SoonToExpireEntries;
+			m_docMgr.ActiveDatabase.RootGroup.TraverseTree(
+				TraversalMethod.PreOrder, null, eh);
 
 			if((pg.Entries.UCount > 0) || !bOnlyIfExists)
 			{
 				UpdateEntryList(pg, false);
 				UpdateUIState(false);
+				ShowSearchResultsStatusMessage();
 			}
-			else
-			{
-				UpdateEntryList(null, false);
-				UpdateUIState(false);
-			}
-
-			ShowSearchResultsStatusMessage();
 		}
 
 		public void PerformExport(PwGroup pgDataSource, bool bExportDeleted)
@@ -1876,6 +1878,28 @@ namespace KeePass.Forms
 			return iocResult;
 		}
 
+		internal IOConnectionInfo CompleteConnectionInfoUsingMru(IOConnectionInfo ioc)
+		{
+			if(ioc == null) { Debug.Assert(false); return null; }
+
+			if(string.IsNullOrEmpty(ioc.UserName) && string.IsNullOrEmpty(ioc.Password))
+			{
+				for(uint u = 0; u < m_mruList.ItemCount; ++u)
+				{
+					IOConnectionInfo iocMru = (m_mruList.GetItem(u).Value as IOConnectionInfo);
+					if(iocMru == null) { Debug.Assert(false); continue; }
+
+					if(iocMru.Path.Equals(ioc.Path, StrUtil.CaseIgnoreCmp))
+					{
+						ioc = iocMru.CloneDeep();
+						break;
+					}
+				}
+			}
+
+			return ioc;
+		}
+
 		private sealed class OdKpfConstructParams
 		{
 			public IOConnectionInfo IOConnectionInfo = null;
@@ -2100,18 +2124,11 @@ namespace KeePass.Forms
 			Program.TriggerSystem.RaiseEvent(EcasEventIDs.OpenedDatabaseFile,
 				pwOpenedDb.IOConnectionInfo.Path);
 
-			if(bCorrectDbActive && pwOpenedDb.IsOpen &&
-				Program.Config.Application.FileOpening.ShowSoonToExpireEntries)
-			{
-				ShowExpiredEntries(true, 7);
-
-				// Avoid view being destroyed by the unlocking routine
-				pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
-			}
-			else if(bCorrectDbActive && pwOpenedDb.IsOpen &&
-				Program.Config.Application.FileOpening.ShowExpiredEntries)
+			if(bCorrectDbActive && pwOpenedDb.IsOpen)
 			{
-				ShowExpiredEntries(true, 0);
+				ShowExpiredEntries(true,
+					Program.Config.Application.FileOpening.ShowExpiredEntries,
+					Program.Config.Application.FileOpening.ShowSoonToExpireEntries);
 
 				// Avoid view being destroyed by the unlocking routine
 				pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
@@ -2188,24 +2205,23 @@ namespace KeePass.Forms
 			return false;
 		}
 
-		// private static void AutoEnableVisualHiding() // Remove static when implementing
+		// private void AutoEnableVisualHiding()
 		// {
-			// KPF 1802197
-
-			// Turn on visual hiding if option is selected
-			// if(m_docMgr.ActiveDatabase.MemoryProtection.AutoEnableVisualHiding)
-			// {
-			//	if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectTitle && !m_viewHideFields.ProtectTitle)
-			//		m_menuViewHideTitles.Checked = m_viewHideFields.ProtectTitle = true;
-			//	if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectUserName && !m_viewHideFields.ProtectUserName)
-			//		m_menuViewHideUserNames.Checked = m_viewHideFields.ProtectUserName = true;
-			//	if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectPassword && !m_viewHideFields.ProtectPassword)
-			//		m_menuViewHidePasswords.Checked = m_viewHideFields.ProtectPassword = true;
-			//	if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectUrl && !m_viewHideFields.ProtectUrl)
-			//		m_menuViewHideURLs.Checked = m_viewHideFields.ProtectUrl = true;
-			//	if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectNotes && !m_viewHideFields.ProtectNotes)
-			//		m_menuViewHideNotes.Checked = m_viewHideFields.ProtectNotes = true;
-			// }
+		//	// KPF 1802197
+		//	// Turn on visual hiding if option is selected
+		//	if(m_docMgr.ActiveDatabase.MemoryProtection.AutoEnableVisualHiding)
+		//	{
+		//		if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectTitle && !m_viewHideFields.ProtectTitle)
+		//			m_menuViewHideTitles.Checked = m_viewHideFields.ProtectTitle = true;
+		//		if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectUserName && !m_viewHideFields.ProtectUserName)
+		//			m_menuViewHideUserNames.Checked = m_viewHideFields.ProtectUserName = true;
+		//		if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectPassword && !m_viewHideFields.ProtectPassword)
+		//			m_menuViewHidePasswords.Checked = m_viewHideFields.ProtectPassword = true;
+		//		if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectUrl && !m_viewHideFields.ProtectUrl)
+		//			m_menuViewHideURLs.Checked = m_viewHideFields.ProtectUrl = true;
+		//		if(m_docMgr.ActiveDatabase.MemoryProtection.ProtectNotes && !m_viewHideFields.ProtectNotes)
+		//			m_menuViewHideNotes.Checked = m_viewHideFields.ProtectNotes = true;
+		//	}
 		// }
 
 		private TreeNode GuiFindGroup(PwUuid puSearch, TreeNode tnContainer)
@@ -2264,8 +2280,8 @@ namespace KeePass.Forms
 			UIUtil.ShowDialogAndDestroy(pf);
 		}
 
-		private void InsertToolStripItem(ToolStripMenuItem tsContainer, ToolStripMenuItem tsTemplate, EventHandler ev,
-			bool bPermanentlyLinkToTemplate)
+		private ToolStripMenuItem InsertToolStripItem(ToolStripMenuItem tsContainer,
+			ToolStripMenuItem tsTemplate, EventHandler ev, bool bPermanentlyLinkToTemplate)
 		{
 			ToolStripMenuItem tsmi = new ToolStripMenuItem(tsTemplate.Text, tsTemplate.Image);
 			tsmi.Click += ev;
@@ -2283,6 +2299,7 @@ namespace KeePass.Forms
 					tsTemplate, tsmi));
 
 			tsContainer.DropDownItems.Insert(0, tsmi);
+			return tsmi;
 		}
 
 		/// <summary>
@@ -2696,56 +2713,68 @@ namespace KeePass.Forms
 
 		private void AssignMenuShortcuts()
 		{
-			m_menuFileNew.ShortcutKeys = (Keys.Control | Keys.N);
-			m_menuFileOpenLocal.ShortcutKeys = (Keys.Control | Keys.O);
-			m_menuFileClose.ShortcutKeys = (Keys.Control | Keys.W);
-			m_menuFileSave.ShortcutKeys = (Keys.Control | Keys.S);
-			m_menuFilePrint.ShortcutKeys = (Keys.Control | Keys.P);
-			m_menuFileLock.ShortcutKeys = (Keys.Control | Keys.L);
+			UIUtil.AssignShortcut(m_menuFileNew, Keys.Control | Keys.N);
+			UIUtil.AssignShortcut(m_menuFileOpenLocal, Keys.Control | Keys.O);
+			UIUtil.AssignShortcut(m_menuFileOpenUrl, Keys.Control | Keys.Shift | Keys.O);
+			UIUtil.AssignShortcut(m_menuFileClose, Keys.Control | Keys.W);
+			UIUtil.AssignShortcut(m_menuFileSave, Keys.Control | Keys.S);
+			UIUtil.AssignShortcut(m_menuFilePrint, Keys.Control | Keys.P);
+			UIUtil.AssignShortcut(m_menuFileSyncFile, Keys.Control | Keys.R);
+			UIUtil.AssignShortcut(m_menuFileSyncUrl, Keys.Control | Keys.Shift | Keys.R);
+			UIUtil.AssignShortcut(m_menuFileLock, Keys.Control | Keys.L);
 
-			m_menuEditFind.ShortcutKeys = (Keys.Control | Keys.F);
-			// m_ctxEntryAdd.ShortcutKeys = Keys.Control | Keys.N;
+			UIUtil.AssignShortcut(m_menuEditFind, Keys.Control | Keys.F);
 
-			// m_menuViewHidePasswords.ShortcutKeys = (Keys.Control | Keys.H);
-			// m_menuViewHideUserNames.ShortcutKeys = (Keys.Control | Keys.J);
+			// UIUtil.AssignShortcut(m_menuViewHidePasswords, Keys.Control | Keys.H);
+			// UIUtil.AssignShortcut(m_menuViewHideUserNames, Keys.Control | Keys.J);
 
-			m_menuHelpContents.ShortcutKeys = Keys.F1;
+			UIUtil.AssignShortcut(m_menuHelpContents, Keys.F1);
 
-			m_ctxGroupFind.ShortcutKeys = (Keys.Control | Keys.Shift | Keys.F);
+			UIUtil.AssignShortcut(m_ctxGroupFind, Keys.Control | Keys.Shift | Keys.F);
 
-			string strCtrl = KPRes.KeyboardKeyCtrl, strAlt = KPRes.KeyboardKeyAlt;
+			string strCtrl = KPRes.KeyboardKeyCtrl + "+", strAlt = KPRes.KeyboardKeyAlt + "+",
+				strShift = KPRes.KeyboardKeyShift + "+";
+			string strCtrlShift = strCtrl + strShift;
 
-			m_ctxEntryCopyUserName.ShortcutKeyDisplayString = strCtrl + "+B";
-			m_ctxEntryCopyPassword.ShortcutKeyDisplayString = strCtrl + "+C";
-			m_ctxEntryPerformAutoType.ShortcutKeyDisplayString = strCtrl + "+V";
-			m_ctxEntryAdd.ShortcutKeyDisplayString = "Ins";
-			m_ctxEntryEdit.ShortcutKeyDisplayString = "Return";
-			m_ctxEntryDelete.ShortcutKeyDisplayString = "Del";
-			m_ctxEntrySelectAll.ShortcutKeyDisplayString = strCtrl + "+A";
+			m_ctxEntryCopyUserName.ShortcutKeyDisplayString = strCtrl + "B";
+			m_ctxEntryCopyPassword.ShortcutKeyDisplayString = strCtrl + "C";
+			m_ctxEntryOpenUrl.ShortcutKeyDisplayString = strCtrl + "U";
+			m_ctxEntryCopyUrl.ShortcutKeyDisplayString = strCtrlShift + "U";
+			m_ctxEntryPerformAutoType.ShortcutKeyDisplayString = strCtrl + "V";
+			m_ctxEntryAdd.ShortcutKeyDisplayString = strCtrl + "I";
+			m_ctxEntryEdit.ShortcutKeyDisplayString = KPRes.KeyboardKeyReturn;
+			m_ctxEntryDelete.ShortcutKeyDisplayString = UIUtil.GetKeysName(Keys.Delete); // "Del"
+			m_ctxEntrySelectAll.ShortcutKeyDisplayString = strCtrl + "A";
 
-			m_ctxEntryMoveToTop.ShortcutKeyDisplayString = strAlt + "+Home";
-			m_ctxEntryMoveOneUp.ShortcutKeyDisplayString = strAlt + "+Up";
-			m_ctxEntryMoveOneDown.ShortcutKeyDisplayString = strAlt + "+Down";
-			m_ctxEntryMoveToBottom.ShortcutKeyDisplayString = strAlt + "+End";
+			m_ctxEntryMoveToTop.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.Home); // "Home"
+			m_ctxEntryMoveOneUp.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.Up); // "Up"
+			m_ctxEntryMoveOneDown.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.Down); // "Down"
+			m_ctxEntryMoveToBottom.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.End); // "End"
 
-			m_ctxGroupDelete.ShortcutKeyDisplayString = "Del";
+			m_ctxGroupDelete.ShortcutKeyDisplayString = UIUtil.GetKeysName(Keys.Delete); // "Del"
 
-			m_ctxGroupMoveToTop.ShortcutKeyDisplayString = strAlt + "+Home";
-			m_ctxGroupMoveOneUp.ShortcutKeyDisplayString = strAlt + "+Up";
-			m_ctxGroupMoveOneDown.ShortcutKeyDisplayString = strAlt + "+Down";
-			m_ctxGroupMoveToBottom.ShortcutKeyDisplayString = strAlt + "+End";
+			m_ctxGroupMoveToTop.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.Home); // "Home"
+			m_ctxGroupMoveOneUp.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.Up); // "Up"
+			m_ctxGroupMoveOneDown.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.Down); // "Down"
+			m_ctxGroupMoveToBottom.ShortcutKeyDisplayString = strAlt +
+				UIUtil.GetKeysName(Keys.End); // "End"
 		}
 
-		private void AssignMenuShortcutsOpt()
+		private static void CopyMenuItemText(ToolStripMenuItem tsmiTarget,
+			ToolStripMenuItem tsmiCopyFrom)
 		{
-			try
-			{
-				string str = KPRes.KeyboardKeyCtrl + "+U";
-				bool b = Program.Config.MainWindow.CopyUrlsInsteadOfOpening;
-				m_ctxEntryOpenUrl.ShortcutKeyDisplayString = (b ? null : str);
-				m_ctxEntryCopyUrl.ShortcutKeyDisplayString = (b ? str : null);
-			}
-			catch(Exception) { Debug.Assert(false); }
+			tsmiTarget.Text = tsmiCopyFrom.Text;
+
+			string strSh = tsmiCopyFrom.ShortcutKeyDisplayString;
+			if(!string.IsNullOrEmpty(strSh))
+				tsmiTarget.ShortcutKeyDisplayString = strSh;
 		}
 
 		private void SaveDatabaseAs(bool bOnline, object sender, bool bCopy)
@@ -2837,19 +2866,20 @@ namespace KeePass.Forms
 			PerformSelfTest();
 
 			pwDatabase.UseFileTransactions = Program.Config.Application.UseTransactedFileWrites;
-
-			AceColumn col = Program.Config.MainWindow.FindColumn(AceColumnType.Title);
-			if((col != null) && !col.HideWithAsterisks)
-				pwDatabase.MemoryProtection.ProtectTitle = false;
-			col = Program.Config.MainWindow.FindColumn(AceColumnType.UserName);
-			if((col != null) && !col.HideWithAsterisks)
-				pwDatabase.MemoryProtection.ProtectUserName = false;
-			col = Program.Config.MainWindow.FindColumn(AceColumnType.Url);
-			if((col != null) && !col.HideWithAsterisks)
-				pwDatabase.MemoryProtection.ProtectUrl = false;
-			col = Program.Config.MainWindow.FindColumn(AceColumnType.Notes);
-			if((col != null) && !col.HideWithAsterisks)
-				pwDatabase.MemoryProtection.ProtectNotes = false;
+			pwDatabase.UseFileLocks = Program.Config.Application.UseFileLocks;
+
+			// AceColumn col = Program.Config.MainWindow.FindColumn(AceColumnType.Title);
+			// if((col != null) && !col.HideWithAsterisks)
+			//	pwDatabase.MemoryProtection.ProtectTitle = false;
+			// col = Program.Config.MainWindow.FindColumn(AceColumnType.UserName);
+			// if((col != null) && !col.HideWithAsterisks)
+			//	pwDatabase.MemoryProtection.ProtectUserName = false;
+			// col = Program.Config.MainWindow.FindColumn(AceColumnType.Url);
+			// if((col != null) && !col.HideWithAsterisks)
+			//	pwDatabase.MemoryProtection.ProtectUrl = false;
+			// col = Program.Config.MainWindow.FindColumn(AceColumnType.Notes);
+			// if((col != null) && !col.HideWithAsterisks)
+			//	pwDatabase.MemoryProtection.ProtectNotes = false;
 
 			if(pwDatabase == m_docMgr.ActiveDatabase) SaveWindowState();
 		}
@@ -3073,8 +3103,8 @@ namespace KeePass.Forms
 
 				if(def.EditedBinaryData != null) // User changed the data
 				{
-					pe.Binaries.Set(eba.Name, new ProtectedBinary(false,
-						def.EditedBinaryData));
+					pe.Binaries.Set(eba.Name, new ProtectedBinary(
+						pbData.IsProtected, def.EditedBinaryData));
 					pe.Touch(true, false);
 
 					RefreshEntriesList();
@@ -4055,23 +4085,7 @@ namespace KeePass.Forms
 					Directory.GetCurrentDirectory(), false) + "Sentinel", ioc.Path);
 
 			if(args[AppDefs.CommandLineOptions.IoCredFromRecent] != null)
-			{
-				for(uint u = 0; u < m_mruList.ItemCount; ++u)
-				{
-					KeyValuePair<string, object> kvp = m_mruList.GetItem(u);
-					if(kvp.Value == null) { Debug.Assert(false); continue; }
-					IOConnectionInfo iocMru = (kvp.Value as IOConnectionInfo);
-					if(iocMru == null) { Debug.Assert(false); continue; }
-
-					if(iocMru.Path.Equals(ioc.Path, StrUtil.CaseIgnoreCmp))
-					{
-						ioc.UserName = iocMru.UserName;
-						ioc.Password = iocMru.Password;
-						ioc.CredSaveMode = iocMru.CredSaveMode;
-						break;
-					}
-				}
-			}
+				ioc = CompleteConnectionInfoUsingMru(ioc);
 
 			string strUserName = args[AppDefs.CommandLineOptions.IoCredUserName];
 			if(strUserName != null) ioc.UserName = strUserName;
@@ -4363,19 +4377,6 @@ namespace KeePass.Forms
 			return v[nColID];
 		}
 
-		private static bool IsColumnHidden(AceColumnType t)
-		{
-			List<AceColumn> l = Program.Config.MainWindow.EntryListColumns;
-			bool bHidden = (t == AceColumnType.Password);
-
-			foreach(AceColumn c in l)
-			{
-				if(c.Type == t) { bHidden = c.HideWithAsterisks; break; }
-			}
-
-			return bHidden;
-		}
-
 		private void ToggleFieldAsterisks(AceColumnType colType)
 		{
 			List<AceColumn> l = Program.Config.MainWindow.EntryListColumns;
@@ -4580,14 +4581,14 @@ namespace KeePass.Forms
 		{
 			if(pd == null) { Debug.Assert(false); return; }
 
-			if(sp != null)
-			{
-				if(sp.SearchInTitles) pd.MemoryProtection.ProtectTitle = false;
-				if(sp.SearchInUserNames) pd.MemoryProtection.ProtectUserName = false;
-				// if(sp.SearchInPasswords) pd.MemoryProtection.ProtectPassword = false;
-				if(sp.SearchInUrls) pd.MemoryProtection.ProtectUrl = false;
-				if(sp.SearchInNotes) pd.MemoryProtection.ProtectNotes = false;
-			}
+			// if(sp != null)
+			// {
+			//	if(sp.SearchInTitles) pd.MemoryProtection.ProtectTitle = false;
+			//	if(sp.SearchInUserNames) pd.MemoryProtection.ProtectUserName = false;
+			//	// if(sp.SearchInPasswords) pd.MemoryProtection.ProtectPassword = false;
+			//	if(sp.SearchInUrls) pd.MemoryProtection.ProtectUrl = false;
+			//	if(sp.SearchInNotes) pd.MemoryProtection.ProtectNotes = false;
+			// }
 		}
 
 		private static bool? m_bCachedSelfTestResult = null;
diff --git a/KeePass/Forms/OptionsForm.cs b/KeePass/Forms/OptionsForm.cs
index 23bcaa4..588dfd0 100644
--- a/KeePass/Forms/OptionsForm.cs
+++ b/KeePass/Forms/OptionsForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -351,10 +351,10 @@ namespace KeePass.Forms
 			m_cdxGuiOptions.AddLink(lviDeref, lviDerefAsync, CheckItemLinkType.UncheckedUnchecked);
 			m_cdxGuiOptions.AddLink(lviDerefAsync, lviDeref, CheckItemLinkType.CheckedChecked);
 
-			lvg = new ListViewGroup(KPRes.EntryView);
-			m_lvGuiOptions.Groups.Add(lvg);
-			m_cdxGuiOptions.CreateItem(Program.Config.MainWindow.EntryView, "HideProtectedCustomStrings",
-				lvg, KPRes.EntryViewHideProtectedCustomStrings);
+			// lvg = new ListViewGroup(KPRes.EntryView);
+			// m_lvGuiOptions.Groups.Add(lvg);
+			// m_cdxGuiOptions.CreateItem(Program.Config.MainWindow.EntryView, "HideProtectedCustomStrings",
+			//	lvg, KPRes.EntryViewHideProtectedCustomStrings);
 
 			lvg = new ListViewGroup(KPRes.QuickSearchTb);
 			m_lvGuiOptions.Groups.Add(lvg);
@@ -448,10 +448,14 @@ namespace KeePass.Forms
 				lvg, KPRes.AutoTypeMatchByTitle);
 			m_cdxAdvanced.CreateItem(Program.Config.Integration, "AutoTypeMatchByUrlInTitle",
 				lvg, KPRes.AutoTypeMatchByUrlInTitle);
+			m_cdxAdvanced.CreateItem(Program.Config.Integration, "AutoTypeMatchByUrlHostInTitle",
+				lvg, KPRes.AutoTypeMatchByUrlHostInTitle);
 			m_cdxAdvanced.CreateItem(Program.Config.Integration, "AutoTypePrependInitSequenceForIE",
 				lvg, KPRes.AutoTypePrependInitSeqForIE);
 			m_cdxAdvanced.CreateItem(Program.Config.Integration, "AutoTypeReleaseAltWithKeyPress",
 				lvg, KPRes.AutoTypeReleaseAltWithKeyPress);
+			m_cdxAdvanced.CreateItem(Program.Config.Integration, "AutoTypeAdjustKeyboardLayout",
+				lvg, KPRes.SameKeybLayout);
 			m_cdxAdvanced.CreateItem(Program.Config.Integration, "AutoTypeCancelOnWindowChange",
 				lvg, KPRes.AutoTypeCancelOnWindowChange);
 
@@ -479,6 +483,8 @@ namespace KeePass.Forms
 				lvg, KPRes.VerifyWrittenFileAfterSave);
 			m_cdxAdvanced.CreateItem(Program.Config.Application, "UseTransactedFileWrites",
 				lvg, KPRes.UseTransactedDatabaseWrites);
+			m_cdxAdvanced.CreateItem(Program.Config.Application, "UseFileLocks",
+				lvg, KPRes.UseFileLocks + " " + KPRes.NotRecommended);
 			m_cdxAdvanced.CreateItem(Program.Config.Defaults, "TanExpiresOnUse",
 				lvg, KPRes.TanExpiresOnUse);
 			m_cdxAdvanced.CreateItem(Program.Config.Defaults, "RecycleBinCollapse",
diff --git a/KeePass/Forms/PluginsForm.cs b/KeePass/Forms/PluginsForm.cs
index 9aa6461..bded0e9 100644
--- a/KeePass/Forms/PluginsForm.cs
+++ b/KeePass/Forms/PluginsForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/PrintForm.cs b/KeePass/Forms/PrintForm.cs
index 9012952..c4a8ad4 100644
--- a/KeePass/Forms/PrintForm.cs
+++ b/KeePass/Forms/PrintForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/ProxyForm.cs b/KeePass/Forms/ProxyForm.cs
index 7c65533..406f9e1 100644
--- a/KeePass/Forms/ProxyForm.cs
+++ b/KeePass/Forms/ProxyForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/PwEntryForm.Designer.cs b/KeePass/Forms/PwEntryForm.Designer.cs
index 49d6f24..2818475 100644
--- a/KeePass/Forms/PwEntryForm.Designer.cs
+++ b/KeePass/Forms/PwEntryForm.Designer.cs
@@ -65,7 +65,6 @@
 			this.m_btnStandardExpires = new System.Windows.Forms.Button();
 			this.m_lblSeparator = new System.Windows.Forms.Label();
 			this.m_ttBalloon = new System.Windows.Forms.ToolTip(this.components);
-			this.m_ttValidationError = new System.Windows.Forms.ToolTip(this.components);
 			this.m_tabMain = new System.Windows.Forms.TabControl();
 			this.m_tabEntry = new System.Windows.Forms.TabPage();
 			this.m_rtNotes = new KeePass.UI.CustomRichTextBoxEx();
@@ -304,69 +303,69 @@
             this.m_menuExpireSep2,
             this.m_menuExpire1Year});
 			this.m_ctxDefaultTimes.Name = "m_ctxDefaultTimes";
-			this.m_ctxDefaultTimes.Size = new System.Drawing.Size(119, 176);
+			this.m_ctxDefaultTimes.Size = new System.Drawing.Size(126, 176);
 			// 
 			// m_menuExpireNow
 			// 
 			this.m_menuExpireNow.Name = "m_menuExpireNow";
-			this.m_menuExpireNow.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpireNow.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpireNow.Text = "&Now";
 			this.m_menuExpireNow.Click += new System.EventHandler(this.OnMenuExpireNow);
 			// 
 			// m_menuExpireSep0
 			// 
 			this.m_menuExpireSep0.Name = "m_menuExpireSep0";
-			this.m_menuExpireSep0.Size = new System.Drawing.Size(115, 6);
+			this.m_menuExpireSep0.Size = new System.Drawing.Size(122, 6);
 			// 
 			// m_menuExpire1Week
 			// 
 			this.m_menuExpire1Week.Name = "m_menuExpire1Week";
-			this.m_menuExpire1Week.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpire1Week.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpire1Week.Text = "&1 Week";
 			this.m_menuExpire1Week.Click += new System.EventHandler(this.OnMenuExpire1Week);
 			// 
 			// m_menuExpire2Weeks
 			// 
 			this.m_menuExpire2Weeks.Name = "m_menuExpire2Weeks";
-			this.m_menuExpire2Weeks.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpire2Weeks.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpire2Weeks.Text = "&2 Weeks";
 			this.m_menuExpire2Weeks.Click += new System.EventHandler(this.OnMenuExpire2Weeks);
 			// 
 			// m_menuExpireSep1
 			// 
 			this.m_menuExpireSep1.Name = "m_menuExpireSep1";
-			this.m_menuExpireSep1.Size = new System.Drawing.Size(115, 6);
+			this.m_menuExpireSep1.Size = new System.Drawing.Size(122, 6);
 			// 
 			// m_menuExpire1Month
 			// 
 			this.m_menuExpire1Month.Name = "m_menuExpire1Month";
-			this.m_menuExpire1Month.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpire1Month.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpire1Month.Text = "1 &Month";
 			this.m_menuExpire1Month.Click += new System.EventHandler(this.OnMenuExpire1Month);
 			// 
 			// m_menuExpire3Months
 			// 
 			this.m_menuExpire3Months.Name = "m_menuExpire3Months";
-			this.m_menuExpire3Months.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpire3Months.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpire3Months.Text = "&3 Months";
 			this.m_menuExpire3Months.Click += new System.EventHandler(this.OnMenuExpire3Months);
 			// 
 			// m_menuExpire6Months
 			// 
 			this.m_menuExpire6Months.Name = "m_menuExpire6Months";
-			this.m_menuExpire6Months.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpire6Months.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpire6Months.Text = "&6 Months";
 			this.m_menuExpire6Months.Click += new System.EventHandler(this.OnMenuExpire6Months);
 			// 
 			// m_menuExpireSep2
 			// 
 			this.m_menuExpireSep2.Name = "m_menuExpireSep2";
-			this.m_menuExpireSep2.Size = new System.Drawing.Size(115, 6);
+			this.m_menuExpireSep2.Size = new System.Drawing.Size(122, 6);
 			// 
 			// m_menuExpire1Year
 			// 
 			this.m_menuExpire1Year.Name = "m_menuExpire1Year";
-			this.m_menuExpire1Year.Size = new System.Drawing.Size(118, 22);
+			this.m_menuExpire1Year.Size = new System.Drawing.Size(125, 22);
 			this.m_menuExpire1Year.Text = "1 &Year";
 			this.m_menuExpire1Year.Click += new System.EventHandler(this.OnMenuExpire1Year);
 			// 
@@ -428,7 +427,6 @@
 			this.m_cbHidePassword.TabIndex = 8;
 			this.m_cbHidePassword.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
 			this.m_cbHidePassword.UseVisualStyleBackColor = true;
-			this.m_cbHidePassword.CheckedChanged += new System.EventHandler(this.OnCheckedHidePassword);
 			// 
 			// m_btnStandardExpires
 			// 
@@ -455,13 +453,6 @@
 			this.m_ttBalloon.IsBalloon = true;
 			this.m_ttBalloon.ReshowDelay = 100;
 			// 
-			// m_ttValidationError
-			// 
-			this.m_ttValidationError.AutoPopDelay = 32000;
-			this.m_ttValidationError.InitialDelay = 250;
-			this.m_ttValidationError.ReshowDelay = 100;
-			this.m_ttValidationError.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Warning;
-			// 
 			// m_tabMain
 			// 
 			this.m_tabMain.Controls.Add(this.m_tabEntry);
@@ -684,13 +675,13 @@
 			this.m_ctxListOperations.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.m_menuListCtxCopyFieldValue});
 			this.m_ctxListOperations.Name = "m_ctxListOperations";
-			this.m_ctxListOperations.Size = new System.Drawing.Size(213, 26);
+			this.m_ctxListOperations.Size = new System.Drawing.Size(235, 26);
 			// 
 			// m_menuListCtxCopyFieldValue
 			// 
 			this.m_menuListCtxCopyFieldValue.Image = global::KeePass.Properties.Resources.B16x16_EditCopy;
 			this.m_menuListCtxCopyFieldValue.Name = "m_menuListCtxCopyFieldValue";
-			this.m_menuListCtxCopyFieldValue.Size = new System.Drawing.Size(212, 22);
+			this.m_menuListCtxCopyFieldValue.Size = new System.Drawing.Size(234, 22);
 			this.m_menuListCtxCopyFieldValue.Text = "&Copy Field Value to Clipboard";
 			this.m_menuListCtxCopyFieldValue.Click += new System.EventHandler(this.OnCtxCopyFieldValue);
 			// 
@@ -1039,40 +1030,40 @@
             this.m_menuListCtxMoveStandardURL,
             this.m_menuListCtxMoveStandardNotes});
 			this.m_ctxStrMoveToStandard.Name = "m_ctxStrMoveToStandard";
-			this.m_ctxStrMoveToStandard.Size = new System.Drawing.Size(144, 114);
+			this.m_ctxStrMoveToStandard.Size = new System.Drawing.Size(155, 114);
 			// 
 			// m_menuListCtxMoveStandardTitle
 			// 
 			this.m_menuListCtxMoveStandardTitle.Name = "m_menuListCtxMoveStandardTitle";
-			this.m_menuListCtxMoveStandardTitle.Size = new System.Drawing.Size(143, 22);
+			this.m_menuListCtxMoveStandardTitle.Size = new System.Drawing.Size(154, 22);
 			this.m_menuListCtxMoveStandardTitle.Text = "To &Title";
 			this.m_menuListCtxMoveStandardTitle.Click += new System.EventHandler(this.OnCtxMoveToTitle);
 			// 
 			// m_menuListCtxMoveStandardUser
 			// 
 			this.m_menuListCtxMoveStandardUser.Name = "m_menuListCtxMoveStandardUser";
-			this.m_menuListCtxMoveStandardUser.Size = new System.Drawing.Size(143, 22);
+			this.m_menuListCtxMoveStandardUser.Size = new System.Drawing.Size(154, 22);
 			this.m_menuListCtxMoveStandardUser.Text = "To User &Name";
 			this.m_menuListCtxMoveStandardUser.Click += new System.EventHandler(this.OnCtxMoveToUserName);
 			// 
 			// m_menuListCtxMoveStandardPassword
 			// 
 			this.m_menuListCtxMoveStandardPassword.Name = "m_menuListCtxMoveStandardPassword";
-			this.m_menuListCtxMoveStandardPassword.Size = new System.Drawing.Size(143, 22);
+			this.m_menuListCtxMoveStandardPassword.Size = new System.Drawing.Size(154, 22);
 			this.m_menuListCtxMoveStandardPassword.Text = "To &Password";
 			this.m_menuListCtxMoveStandardPassword.Click += new System.EventHandler(this.OnCtxMoveToPassword);
 			// 
 			// m_menuListCtxMoveStandardURL
 			// 
 			this.m_menuListCtxMoveStandardURL.Name = "m_menuListCtxMoveStandardURL";
-			this.m_menuListCtxMoveStandardURL.Size = new System.Drawing.Size(143, 22);
+			this.m_menuListCtxMoveStandardURL.Size = new System.Drawing.Size(154, 22);
 			this.m_menuListCtxMoveStandardURL.Text = "To &URL";
 			this.m_menuListCtxMoveStandardURL.Click += new System.EventHandler(this.OnCtxMoveToURL);
 			// 
 			// m_menuListCtxMoveStandardNotes
 			// 
 			this.m_menuListCtxMoveStandardNotes.Name = "m_menuListCtxMoveStandardNotes";
-			this.m_menuListCtxMoveStandardNotes.Size = new System.Drawing.Size(143, 22);
+			this.m_menuListCtxMoveStandardNotes.Size = new System.Drawing.Size(154, 22);
 			this.m_menuListCtxMoveStandardNotes.Text = "To No&tes";
 			this.m_menuListCtxMoveStandardNotes.Click += new System.EventHandler(this.OnCtxMoveToNotes);
 			// 
@@ -1083,25 +1074,25 @@
             this.m_ctxPwGenSep0,
             this.m_ctxPwGenProfiles});
 			this.m_ctxPwGen.Name = "m_ctxPwGen";
-			this.m_ctxPwGen.Size = new System.Drawing.Size(209, 54);
+			this.m_ctxPwGen.Size = new System.Drawing.Size(229, 54);
 			// 
 			// m_ctxPwGenOpen
 			// 
 			this.m_ctxPwGenOpen.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Gen;
 			this.m_ctxPwGenOpen.Name = "m_ctxPwGenOpen";
-			this.m_ctxPwGenOpen.Size = new System.Drawing.Size(208, 22);
+			this.m_ctxPwGenOpen.Size = new System.Drawing.Size(228, 22);
 			this.m_ctxPwGenOpen.Text = "&Open Password Generator...";
 			this.m_ctxPwGenOpen.Click += new System.EventHandler(this.OnPwGenOpen);
 			// 
 			// m_ctxPwGenSep0
 			// 
 			this.m_ctxPwGenSep0.Name = "m_ctxPwGenSep0";
-			this.m_ctxPwGenSep0.Size = new System.Drawing.Size(205, 6);
+			this.m_ctxPwGenSep0.Size = new System.Drawing.Size(225, 6);
 			// 
 			// m_ctxPwGenProfiles
 			// 
 			this.m_ctxPwGenProfiles.Name = "m_ctxPwGenProfiles";
-			this.m_ctxPwGenProfiles.Size = new System.Drawing.Size(208, 22);
+			this.m_ctxPwGenProfiles.Size = new System.Drawing.Size(228, 22);
 			this.m_ctxPwGenProfiles.Text = "Generate Using Profile";
 			// 
 			// m_ctxTools
@@ -1115,26 +1106,26 @@
             this.m_ctxToolsSep1,
             this.m_ctxToolsFieldRefs});
 			this.m_ctxTools.Name = "m_ctxTools";
-			this.m_ctxTools.Size = new System.Drawing.Size(222, 126);
+			this.m_ctxTools.Size = new System.Drawing.Size(242, 126);
 			// 
 			// m_ctxToolsHelp
 			// 
 			this.m_ctxToolsHelp.Image = global::KeePass.Properties.Resources.B16x16_Help;
 			this.m_ctxToolsHelp.Name = "m_ctxToolsHelp";
-			this.m_ctxToolsHelp.Size = new System.Drawing.Size(221, 22);
+			this.m_ctxToolsHelp.Size = new System.Drawing.Size(241, 22);
 			this.m_ctxToolsHelp.Text = "&Help";
 			this.m_ctxToolsHelp.Click += new System.EventHandler(this.OnCtxToolsHelp);
 			// 
 			// m_ctxToolsSep0
 			// 
 			this.m_ctxToolsSep0.Name = "m_ctxToolsSep0";
-			this.m_ctxToolsSep0.Size = new System.Drawing.Size(218, 6);
+			this.m_ctxToolsSep0.Size = new System.Drawing.Size(238, 6);
 			// 
 			// m_ctxToolsUrlHelp
 			// 
 			this.m_ctxToolsUrlHelp.Image = global::KeePass.Properties.Resources.B16x16_Help;
 			this.m_ctxToolsUrlHelp.Name = "m_ctxToolsUrlHelp";
-			this.m_ctxToolsUrlHelp.Size = new System.Drawing.Size(221, 22);
+			this.m_ctxToolsUrlHelp.Size = new System.Drawing.Size(241, 22);
 			this.m_ctxToolsUrlHelp.Text = "&URL Field: Help";
 			this.m_ctxToolsUrlHelp.Click += new System.EventHandler(this.OnCtxUrlHelp);
 			// 
@@ -1142,7 +1133,7 @@
 			// 
 			this.m_ctxToolsUrlSelApp.Image = global::KeePass.Properties.Resources.B16x16_View_Detailed;
 			this.m_ctxToolsUrlSelApp.Name = "m_ctxToolsUrlSelApp";
-			this.m_ctxToolsUrlSelApp.Size = new System.Drawing.Size(221, 22);
+			this.m_ctxToolsUrlSelApp.Size = new System.Drawing.Size(241, 22);
 			this.m_ctxToolsUrlSelApp.Text = "URL Field: Select &Application...";
 			this.m_ctxToolsUrlSelApp.Click += new System.EventHandler(this.OnCtxUrlSelApp);
 			// 
@@ -1150,14 +1141,14 @@
 			// 
 			this.m_ctxToolsUrlSelDoc.Image = global::KeePass.Properties.Resources.B16x16_CompFile;
 			this.m_ctxToolsUrlSelDoc.Name = "m_ctxToolsUrlSelDoc";
-			this.m_ctxToolsUrlSelDoc.Size = new System.Drawing.Size(221, 22);
+			this.m_ctxToolsUrlSelDoc.Size = new System.Drawing.Size(241, 22);
 			this.m_ctxToolsUrlSelDoc.Text = "URL Field: Select &Document...";
 			this.m_ctxToolsUrlSelDoc.Click += new System.EventHandler(this.OnCtxUrlSelDoc);
 			// 
 			// m_ctxToolsSep1
 			// 
 			this.m_ctxToolsSep1.Name = "m_ctxToolsSep1";
-			this.m_ctxToolsSep1.Size = new System.Drawing.Size(218, 6);
+			this.m_ctxToolsSep1.Size = new System.Drawing.Size(238, 6);
 			// 
 			// m_ctxToolsFieldRefs
 			// 
@@ -1168,41 +1159,41 @@
             this.m_ctxToolsFieldRefsInUrl,
             this.m_ctxToolsFieldRefsInNotes});
 			this.m_ctxToolsFieldRefs.Name = "m_ctxToolsFieldRefs";
-			this.m_ctxToolsFieldRefs.Size = new System.Drawing.Size(221, 22);
+			this.m_ctxToolsFieldRefs.Size = new System.Drawing.Size(241, 22);
 			this.m_ctxToolsFieldRefs.Text = "Insert Field &Reference";
 			// 
 			// m_ctxToolsFieldRefsInTitle
 			// 
 			this.m_ctxToolsFieldRefsInTitle.Name = "m_ctxToolsFieldRefsInTitle";
-			this.m_ctxToolsFieldRefsInTitle.Size = new System.Drawing.Size(164, 22);
+			this.m_ctxToolsFieldRefsInTitle.Size = new System.Drawing.Size(180, 22);
 			this.m_ctxToolsFieldRefsInTitle.Text = "In &Title Field";
 			this.m_ctxToolsFieldRefsInTitle.Click += new System.EventHandler(this.OnFieldRefInTitle);
 			// 
 			// m_ctxToolsFieldRefsInUserName
 			// 
 			this.m_ctxToolsFieldRefsInUserName.Name = "m_ctxToolsFieldRefsInUserName";
-			this.m_ctxToolsFieldRefsInUserName.Size = new System.Drawing.Size(164, 22);
+			this.m_ctxToolsFieldRefsInUserName.Size = new System.Drawing.Size(180, 22);
 			this.m_ctxToolsFieldRefsInUserName.Text = "In User &Name Field";
 			this.m_ctxToolsFieldRefsInUserName.Click += new System.EventHandler(this.OnFieldRefInUserName);
 			// 
 			// m_ctxToolsFieldRefsInPassword
 			// 
 			this.m_ctxToolsFieldRefsInPassword.Name = "m_ctxToolsFieldRefsInPassword";
-			this.m_ctxToolsFieldRefsInPassword.Size = new System.Drawing.Size(164, 22);
+			this.m_ctxToolsFieldRefsInPassword.Size = new System.Drawing.Size(180, 22);
 			this.m_ctxToolsFieldRefsInPassword.Text = "In &Password Field";
 			this.m_ctxToolsFieldRefsInPassword.Click += new System.EventHandler(this.OnFieldRefInPassword);
 			// 
 			// m_ctxToolsFieldRefsInUrl
 			// 
 			this.m_ctxToolsFieldRefsInUrl.Name = "m_ctxToolsFieldRefsInUrl";
-			this.m_ctxToolsFieldRefsInUrl.Size = new System.Drawing.Size(164, 22);
+			this.m_ctxToolsFieldRefsInUrl.Size = new System.Drawing.Size(180, 22);
 			this.m_ctxToolsFieldRefsInUrl.Text = "In &URL Field";
 			this.m_ctxToolsFieldRefsInUrl.Click += new System.EventHandler(this.OnFieldRefInUrl);
 			// 
 			// m_ctxToolsFieldRefsInNotes
 			// 
 			this.m_ctxToolsFieldRefsInNotes.Name = "m_ctxToolsFieldRefsInNotes";
-			this.m_ctxToolsFieldRefsInNotes.Size = new System.Drawing.Size(164, 22);
+			this.m_ctxToolsFieldRefsInNotes.Size = new System.Drawing.Size(180, 22);
 			this.m_ctxToolsFieldRefsInNotes.Text = "In N&otes Field";
 			this.m_ctxToolsFieldRefsInNotes.Click += new System.EventHandler(this.OnFieldRefInNotes);
 			// 
@@ -1280,7 +1271,6 @@
 		private System.Windows.Forms.ToolTip m_ttRect;
 		private System.Windows.Forms.Label m_lblSeparator;
 		private System.Windows.Forms.ToolTip m_ttBalloon;
-		private System.Windows.Forms.ToolTip m_ttValidationError;
 		private System.Windows.Forms.TabControl m_tabMain;
 		private System.Windows.Forms.TabPage m_tabEntry;
 		private System.Windows.Forms.TabPage m_tabAdvanced;
diff --git a/KeePass/Forms/PwEntryForm.cs b/KeePass/Forms/PwEntryForm.cs
index 775f9df..4057d3b 100644
--- a/KeePass/Forms/PwEntryForm.cs
+++ b/KeePass/Forms/PwEntryForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -29,8 +29,9 @@ using System.IO;
 
 using KeePass.App;
 using KeePass.App.Configuration;
-using KeePass.UI;
+using KeePass.Native;
 using KeePass.Resources;
+using KeePass.UI;
 using KeePass.Util;
 
 using KeePassLib;
@@ -45,9 +46,9 @@ namespace KeePass.Forms
 	public enum PwEditMode
 	{
 		Invalid = 0,
-		AddNewEntry = 1,
-		EditExistingEntry = 2,
-		ViewReadOnlyEntry = 3
+		AddNewEntry,
+		EditExistingEntry,
+		ViewReadOnlyEntry
 	}
 
 	public partial class PwEntryForm : Form
@@ -70,14 +71,13 @@ namespace KeePass.Forms
 		private PwUuid m_pwCustomIconID = PwUuid.Zero;
 		private ImageList m_ilIcons = null;
 
-		private Color m_clrNormalBackColor = Color.White;
-		private bool m_bRepeatPasswordFailed = false;
 		private bool m_bLockEnabledState = false;
+		private bool m_bTouchedOnce = false;
 
 		private bool m_bInitializing = false;
+		private bool m_bForceClosing = false;
 
-		private SecureEdit m_secPassword = new SecureEdit();
-		private SecureEdit m_secRepeat = new SecureEdit();
+		private PwInputControlGroup m_icgPassword = new PwInputControlGroup();
 		private RichTextBoxContextMenu m_ctxNotes = new RichTextBoxContextMenu();
 
 		private readonly string DeriveFromPrevious = "(" + KPRes.GenPwBasedOnPrevious + ")";
@@ -89,6 +89,9 @@ namespace KeePass.Forms
 		public event EventHandler<CancellableOperationEventArgs> EntrySaving;
 		public event EventHandler EntrySaved;
 
+		private const PwCompareOptions m_cmpOpt = (PwCompareOptions.NullEmptyEquivStd |
+			PwCompareOptions.IgnoreTimes);
+
 		public bool HasModifiedEntry
 		{
 			get
@@ -99,8 +102,8 @@ namespace KeePass.Forms
 					return true;
 				}
 
-				return !m_pwEntry.EqualsEntry(m_pwInitialEntry, false, true,
-					true, false, false, MemProtCmpMode.CustomOnly);
+				return !m_pwEntry.EqualsEntry(m_pwInitialEntry, m_cmpOpt,
+					MemProtCmpMode.CustomOnly);
 			}
 		}
 
@@ -197,8 +200,9 @@ namespace KeePass.Forms
 			}
 
 			bool bHideInitial = m_cbHidePassword.Checked;
-			m_secPassword.Attach(m_tbPassword, ProcessTextChangedPassword, bHideInitial);
-			m_secRepeat.Attach(m_tbRepeatPassword, ProcessTextChangedRepeatPw, bHideInitial);
+			m_icgPassword.Attach(m_tbPassword, m_cbHidePassword, m_lblPasswordRepeat,
+				m_tbRepeatPassword, m_lblQuality, m_pbQuality, m_lblQualityBitsText,
+				this, bHideInitial, false);
 
 			m_dtExpireDateTime.CustomFormat = DateTimeFormatInfo.CurrentInfo.ShortDatePattern +
 				" " + DateTimeFormatInfo.CurrentInfo.LongTimePattern;
@@ -220,8 +224,7 @@ namespace KeePass.Forms
 					m_tbRepeatPassword.ReadOnly = m_tbUrl.ReadOnly =
 					m_rtNotes.ReadOnly = true;
 
-				m_btnIcon.Enabled = m_btnGenPw.Enabled =
-					m_tbRepeatPassword.Enabled = m_cbExpires.Enabled =
+				m_btnIcon.Enabled = m_btnGenPw.Enabled = m_cbExpires.Enabled =
 					m_dtExpireDateTime.Enabled =
 					m_btnStandardExpires.Enabled = false;
 
@@ -276,7 +279,7 @@ namespace KeePass.Forms
 				m_vStrings.Set(PwDefs.UserNameField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectUserName,
 					m_tbUserName.Text));
 
-				byte[] pb = m_secPassword.ToUtf8();
+				byte[] pb = m_icgPassword.GetPasswordUtf8();
 				m_vStrings.Set(PwDefs.PasswordField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectPassword,
 					pb));
 				MemUtil.ZeroByteArray(pb);
@@ -292,8 +295,7 @@ namespace KeePass.Forms
 				m_tbUserName.Text = m_vStrings.ReadSafe(PwDefs.UserNameField);
 
 				byte[] pb = m_vStrings.GetSafe(PwDefs.PasswordField).ReadUtf8();
-				m_secPassword.SetPassword(pb);
-				if(bSetRepeatPw) m_secRepeat.SetPassword(pb);
+				m_icgPassword.SetPassword(pb, bSetRepeatPw);
 				MemUtil.ZeroByteArray(pb);
 
 				m_tbUrl.Text = m_vStrings.ReadSafe(PwDefs.UrlField);
@@ -310,7 +312,7 @@ namespace KeePass.Forms
 
 						ListViewItem lvi = m_lvStrings.Items.Add(kvpStr.Key, (int)pwIcon);
 
-						if(!kvpStr.Value.IsViewable)
+						if(kvpStr.Value.IsProtected)
 							lvi.SubItems.Add(PwDefs.HiddenPassword);
 						else
 						{
@@ -339,8 +341,8 @@ namespace KeePass.Forms
 				m_lvBinaries.Items.Clear();
 				foreach(KeyValuePair<string, ProtectedBinary> kvpBin in m_vBinaries)
 				{
-					PwIcon pwIcon = (kvpBin.Value.IsProtected ? m_pwObjectProtected :
-						m_pwObjectPlainText);
+					PwIcon pwIcon = (kvpBin.Value.IsProtected ?
+						m_pwObjectProtected : m_pwObjectPlainText);
 					m_lvBinaries.Items.Add(kvpBin.Key, (int)pwIcon);
 				}
 				UIUtil.SetTopVisibleItem(m_lvBinaries, iTopVisible);
@@ -515,6 +517,7 @@ namespace KeePass.Forms
 			GlobalWindowManager.CustomizeControl(m_ctxStrMoveToStandard);
 
 			m_pwInitialEntry = m_pwEntry.CloneDeep();
+			StrUtil.NormalizeNewLines(m_pwInitialEntry.Strings, true);
 
 			m_ttRect.SetToolTip(m_btnIcon, KPRes.SelectIcon);
 			m_ttRect.SetToolTip(m_cbHidePassword, KPRes.TogglePasswordAsterisks);
@@ -523,9 +526,6 @@ namespace KeePass.Forms
 
 			m_ttBalloon.SetToolTip(m_tbRepeatPassword, KPRes.PasswordRepeatHint);
 
-			m_ttValidationError.ToolTipTitle = KPRes.ValidationFailed;
-
-			m_clrNormalBackColor = m_tbPassword.BackColor;
 			m_dynGenProfiles = new DynamicMenu(m_ctxPwGenProfiles.DropDownItems);
 			m_dynGenProfiles.MenuClick += this.OnProfilesDynamicMenuClick;
 			m_ctxNotes.Attach(m_rtNotes, this);
@@ -584,8 +584,7 @@ namespace KeePass.Forms
 			UpdateEntryStrings(false, true);
 			UpdateEntryBinaries(false, false);
 
-			if(PwDefs.IsTanEntry(m_pwEntry))
-				m_btnTools.Enabled = false;
+			if(PwDefs.IsTanEntry(m_pwEntry)) m_btnTools.Enabled = false;
 
 			CustomizeForScreenReader();
 
@@ -627,18 +626,6 @@ namespace KeePass.Forms
 		{
 			if(m_bInitializing) return;
 
-			byte[] pb = m_secPassword.ToUtf8();
-			uint uBits = QualityEstimation.EstimatePasswordBits(pb);
-			MemUtil.ZeroByteArray(pb);
-			m_lblQualityBitsText.Text = uBits.ToString() + " " + KPRes.Bits;
-			int iPos = (int)((100 * uBits) / (256 / 2));
-			if(iPos < 0) iPos = 0; else if(iPos > 100) iPos = 100;
-			m_pbQuality.Value = iPos;
-
-			bool bHidePassword = m_cbHidePassword.Checked;
-			m_secPassword.EnableProtection(bHidePassword);
-			m_secRepeat.EnableProtection(bHidePassword);
-
 			int nStringsSel = m_lvStrings.SelectedItems.Count;
 			int nBinSel = m_lvBinaries.SelectedItems.Count;
 
@@ -649,8 +636,10 @@ namespace KeePass.Forms
 				ProtectedBinary pbSel = m_vBinaries.Get(strBin);
 				if(pbSel != null)
 				{
+					byte[] pbBinData = pbSel.ReadData();
 					BinaryDataClass bdc = BinaryDataClassifier.Classify(
-						strBin, pbSel.ReadData());
+						strBin, pbBinData);
+					MemUtil.ZeroByteArray(pbBinData);
 					if(DataEditorForm.SupportsDataType(bdc) && (m_pwEditMode !=
 						PwEditMode.ViewReadOnlyEntry))
 						bBinEdit = true;
@@ -703,10 +692,12 @@ namespace KeePass.Forms
 				(nStringsSel == 1);
 		}
 
-		private bool SaveEntry()
+		private bool SaveEntry(PwEntry peTarget, bool bValidate)
 		{
 			if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return true;
 
+			if(bValidate && !m_icgPassword.ValidateData(true)) return false;
+
 			if(this.EntrySaving != null)
 			{
 				CancellableOperationEventArgs eaCancel = new CancellableOperationEventArgs();
@@ -714,33 +705,33 @@ namespace KeePass.Forms
 				if(eaCancel.Cancel) return false;
 			}
 
-			m_pwEntry.History = m_vHistory; // Must be called before CreateBackup()
+			peTarget.History = m_vHistory; // Must be called before CreateBackup()
 			bool bCreateBackup = (m_pwEditMode != PwEditMode.AddNewEntry);
-			if(bCreateBackup) m_pwEntry.CreateBackup(null);
+			if(bCreateBackup) peTarget.CreateBackup(null);
 
-			m_pwEntry.IconId = m_pwEntryIcon;
-			m_pwEntry.CustomIconUuid = m_pwCustomIconID;
+			peTarget.IconId = m_pwEntryIcon;
+			peTarget.CustomIconUuid = m_pwCustomIconID;
 
 			if(m_cbCustomForegroundColor.Checked)
-				m_pwEntry.ForegroundColor = m_clrForeground;
-			else m_pwEntry.ForegroundColor = Color.Empty;
+				peTarget.ForegroundColor = m_clrForeground;
+			else peTarget.ForegroundColor = Color.Empty;
 			if(m_cbCustomBackgroundColor.Checked)
-				m_pwEntry.BackgroundColor = m_clrBackground;
-			else m_pwEntry.BackgroundColor = Color.Empty;
+				peTarget.BackgroundColor = m_clrBackground;
+			else peTarget.BackgroundColor = Color.Empty;
 
-			m_pwEntry.OverrideUrl = m_tbOverrideUrl.Text;
+			peTarget.OverrideUrl = m_tbOverrideUrl.Text;
 
 			List<string> vNewTags = StrUtil.StringToTags(m_tbTags.Text);
-			m_pwEntry.Tags.Clear();
-			foreach(string strTag in vNewTags) m_pwEntry.AddTag(strTag);
+			peTarget.Tags.Clear();
+			foreach(string strTag in vNewTags) peTarget.AddTag(strTag);
 
-			m_pwEntry.Expires = m_cbExpires.Checked;
-			if(m_pwEntry.Expires) m_pwEntry.ExpiryTime = m_dtExpireDateTime.Value;
+			peTarget.Expires = m_cbExpires.Checked;
+			if(peTarget.Expires) peTarget.ExpiryTime = m_dtExpireDateTime.Value;
 
 			UpdateEntryStrings(true, false);
 
-			m_pwEntry.Strings = m_vStrings;
-			m_pwEntry.Binaries = m_vBinaries;
+			peTarget.Strings = m_vStrings;
+			peTarget.Binaries = m_vBinaries;
 
 			m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked;
 			m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ?
@@ -752,21 +743,26 @@ namespace KeePass.Forms
 				m_atConfig.DefaultSequence = m_tbDefaultAutoTypeSeq.Text;
 			else { Debug.Assert(false); }
 
-			m_pwEntry.AutoType = m_atConfig;
+			peTarget.AutoType = m_atConfig;
+
+			peTarget.Touch(true, false); // Touch *after* backup
+			if(object.ReferenceEquals(peTarget, m_pwEntry)) m_bTouchedOnce = true;
 
-			m_pwEntry.Touch(true, false); // Touch *after* backup
+			StrUtil.NormalizeNewLines(peTarget.Strings, true);
 
-			if(m_pwEntry.EqualsEntry(m_pwInitialEntry, false, true, true, false,
-				bCreateBackup, MemProtCmpMode.CustomOnly))
+			PwCompareOptions cmpOpt = m_cmpOpt;
+			if(bCreateBackup) cmpOpt |= PwCompareOptions.IgnoreLastBackup;
+
+			if(peTarget.EqualsEntry(m_pwInitialEntry, cmpOpt, MemProtCmpMode.CustomOnly))
 			{
-				m_pwEntry.LastModificationTime = m_pwInitialEntry.LastModificationTime;
+				peTarget.LastModificationTime = m_pwInitialEntry.LastModificationTime;
 
 				if(bCreateBackup)
-					m_pwEntry.History.Remove(m_pwEntry.History.GetAt(
-						m_pwEntry.History.UCount - 1)); // Undo backup
+					peTarget.History.Remove(peTarget.History.GetAt(
+						peTarget.History.UCount - 1)); // Undo backup
 			}
 
-			m_pwEntry.MaintainBackups(m_pwDatabase);
+			peTarget.MaintainBackups(m_pwDatabase);
 
 			if(this.EntrySaved != null) this.EntrySaved(this, EventArgs.Empty);
 
@@ -775,26 +771,20 @@ namespace KeePass.Forms
 
 		private void OnBtnOK(object sender, EventArgs e)
 		{
-			// Immediately close if we're just viewing an entry
-			if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return;
-
-			if(m_secPassword.ContentsEqualTo(m_secRepeat) == false)
-			{
-				m_bRepeatPasswordFailed = true;
-
-				m_tbRepeatPassword.BackColor = AppDefs.ColorEditError;
-				m_ttValidationError.Show(KPRes.PasswordRepeatFailed, m_tbRepeatPassword);
-
-				this.DialogResult = DialogResult.None;
-				return;
-			}
-
-			if(!SaveEntry()) this.DialogResult = DialogResult.None;
+			if(SaveEntry(m_pwEntry, true)) m_bForceClosing = true;
+			else this.DialogResult = DialogResult.None;
 		}
 
 		private void OnBtnCancel(object sender, EventArgs e)
 		{
-			m_pwEntry.Touch(false);
+			m_bForceClosing = true;
+
+			try
+			{
+				ushort usEsc = NativeMethods.GetAsyncKeyState((int)Keys.Escape);
+				if((usEsc & 0x8000) != 0) m_bForceClosing = false;
+			}
+			catch(Exception) { Debug.Assert(KeePassLib.Native.NativeLib.IsUnix()); }
 		}
 
 		private void CleanUpEx()
@@ -805,44 +795,7 @@ namespace KeePass.Forms
 				Program.Config.UI.Hiding.HideInEntryWindow = m_cbHidePassword.Checked;
 
 			m_ctxNotes.Detach();
-			m_secPassword.Detach();
-			m_secRepeat.Detach();
-		}
-
-		private void OnCheckedHidePassword(object sender, EventArgs e)
-		{
-			if(m_bInitializing) return;
-
-			if(!m_cbHidePassword.Checked && !AppPolicy.Try(AppPolicyId.UnhidePasswords))
-			{
-				m_cbHidePassword.Checked = true;
-				return;
-			}
-
-			ProcessTextChangedRepeatPw(sender, e); // Clear red warning color
-			EnableControlsEx();
-		}
-
-		private void ProcessTextChangedPassword(object sender, EventArgs e)
-		{
-			if(m_bRepeatPasswordFailed)
-			{
-				m_tbPassword.BackColor = m_clrNormalBackColor;
-				m_tbRepeatPassword.BackColor = m_clrNormalBackColor;
-				m_bRepeatPasswordFailed = false;
-			}
-
-			EnableControlsEx();
-		}
-
-		private void ProcessTextChangedRepeatPw(object sender, EventArgs e)
-		{
-			if(m_bRepeatPasswordFailed)
-			{
-				m_tbPassword.BackColor = m_clrNormalBackColor;
-				m_tbRepeatPassword.BackColor = m_clrNormalBackColor;
-				m_bRepeatPasswordFailed = false;
-			}
+			m_icgPassword.Release();
 		}
 
 		private void OnBtnStrAdd(object sender, EventArgs e)
@@ -923,7 +876,8 @@ namespace KeePass.Forms
 							MessageService.NewLine + KPRes.AttachNewRenameRemarks1 +
 							MessageService.NewLine + KPRes.AttachNewRenameRemarks2;
 
-						DialogResult dr = MessageService.Ask(strMsg, null, MessageBoxButtons.YesNoCancel);
+						DialogResult dr = MessageService.Ask(strMsg, null,
+							MessageBoxButtons.YesNoCancel);
 
 						if(dr == DialogResult.Cancel) continue;
 						else if(dr == DialogResult.Yes)
@@ -1034,11 +988,13 @@ namespace KeePass.Forms
 			ProtectedBinary pb = m_vBinaries.Get(lvi.Text);
 			Debug.Assert(pb != null); if(pb == null) throw new ArgumentException();
 
-			try { File.WriteAllBytes(strFileName, pb.ReadData()); }
+			byte[] pbData = pb.ReadData();
+			try { File.WriteAllBytes(strFileName, pbData); }
 			catch(Exception exWrite)
 			{
 				MessageService.ShowWarning(strFileName, exWrite);
 			}
+			MemUtil.ZeroByteArray(pbData);
 		}
 
 		private void OnBtnAutoTypeAdd(object sender, EventArgs e)
@@ -1134,6 +1090,7 @@ namespace KeePass.Forms
 
 			m_pwEntry.RestoreFromBackup((uint)lvsi[0], m_pwDatabase);
 			m_pwEntry.Touch(true, false);
+			m_bTouchedOnce = true;
 			this.DialogResult = DialogResult.OK; // Doesn't invoke OnBtnOK
 		}
 
@@ -1152,52 +1109,54 @@ namespace KeePass.Forms
 			EnableControlsEx();
 		}
 
-		private void SetExpireDays(int nDays)
+		private void SetExpireIn(int nYears, int nMonths, int nDays)
 		{
 			if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return;
 
-			m_cbExpires.Checked = true;
+			DateTime dt = DateTime.Now;
+			if(nYears != 0) dt = dt.AddYears(nYears);
+			if(nMonths != 0) dt = dt.AddMonths(nMonths);
+			if(nDays != 0) dt = dt.AddDays(nDays);
 
-			DateTime dtNow = DateTime.Now;
-			DateTime dtNew = dtNow.AddDays(nDays);
-			m_dtExpireDateTime.Value = m_dtExpireDateTime.Value = dtNew;
+			m_cbExpires.Checked = true;
+			m_dtExpireDateTime.Value = dt;
 
 			EnableControlsEx();
 		}
 
 		private void OnMenuExpireNow(object sender, EventArgs e)
 		{
-			SetExpireDays(0);
+			SetExpireIn(0, 0, 0);
 		}
 
 		private void OnMenuExpire1Week(object sender, EventArgs e)
 		{
-			SetExpireDays(7);
+			SetExpireIn(0, 0, 7);
 		}
 
 		private void OnMenuExpire2Weeks(object sender, EventArgs e)
 		{
-			SetExpireDays(14);
+			SetExpireIn(0, 0, 14);
 		}
 
 		private void OnMenuExpire1Month(object sender, EventArgs e)
 		{
-			SetExpireDays(30);
+			SetExpireIn(0, 1, 0);
 		}
 
 		private void OnMenuExpire3Months(object sender, EventArgs e)
 		{
-			SetExpireDays(91);
+			SetExpireIn(0, 3, 0);
 		}
 
 		private void OnMenuExpire6Months(object sender, EventArgs e)
 		{
-			SetExpireDays(182);
+			SetExpireIn(0, 6, 0);
 		}
 
 		private void OnMenuExpire1Year(object sender, EventArgs e)
 		{
-			SetExpireDays(365);
+			SetExpireIn(1, 0, 0);
 		}
 
 		private void OnBtnStandardExpiresClick(object sender, EventArgs e)
@@ -1324,15 +1283,15 @@ namespace KeePass.Forms
 			}
 			else if(strStandardField == PwDefs.PasswordField)
 			{
-				string strPw = StrUtil.Utf8.GetString(m_secPassword.ToUtf8());
-				if((strPw.Length > 0) && (strText.Length > 0))
-					strPw += ", ";
-				m_tbPassword.Text = (strPw + strText);
-
-				string strRep = StrUtil.Utf8.GetString(m_secRepeat.ToUtf8());
-				if((strRep.Length > 0) && (strText.Length > 0))
-					strRep += ", ";
-				m_tbRepeatPassword.Text = (strRep + strText);
+				string strPw = m_icgPassword.GetPassword();
+				if((strPw.Length > 0) && (strText.Length > 0)) strPw += ", ";
+				strPw += strText;
+
+				string strRep = m_icgPassword.GetRepeat();
+				if((strRep.Length > 0) && (strText.Length > 0)) strRep += ", ";
+				strRep += strText;
+
+				m_icgPassword.SetPasswords(strPw, strRep);
 			}
 			else if(strStandardField == PwDefs.UrlField)
 			{
@@ -1389,7 +1348,7 @@ namespace KeePass.Forms
 		{
 			PwGeneratorForm pgf = new PwGeneratorForm();
 
-			byte[] pbCurPassword = m_secPassword.ToUtf8();
+			byte[] pbCurPassword = m_icgPassword.GetPasswordUtf8();
 			bool bAtLeastOneChar = (pbCurPassword.Length > 0);
 			ProtectedString ps = new ProtectedString(true, pbCurPassword);
 			Array.Clear(pbCurPassword, 0, pbCurPassword.Length);
@@ -1401,14 +1360,13 @@ namespace KeePass.Forms
 			if(pgf.ShowDialog() == DialogResult.OK)
 			{
 				byte[] pbEntropy = EntropyForm.CollectEntropyIfEnabled(pgf.SelectedProfile);
-				ProtectedString psNew = new ProtectedString(true);
-				PwGenerator.Generate(psNew, pgf.SelectedProfile, pbEntropy,
+				ProtectedString psNew;
+				PwGenerator.Generate(out psNew, pgf.SelectedProfile, pbEntropy,
 					Program.PwGeneratorPool);
 
 				byte[] pbNew = psNew.ReadUtf8();
-				m_secPassword.SetPassword(pbNew);
-				m_secRepeat.SetPassword(pbNew);
-				Array.Clear(pbNew, 0, pbNew.Length);
+				m_icgPassword.SetPassword(pbNew, true);
+				MemUtil.ZeroByteArray(pbNew);
 			}
 			UIUtil.DestroyForm(pgf);
 
@@ -1420,14 +1378,14 @@ namespace KeePass.Forms
 			PwProfile pwp = null;
 			if(e.ItemName == DeriveFromPrevious)
 			{
-				byte[] pbCur = m_secPassword.ToUtf8();
+				byte[] pbCur = m_icgPassword.GetPasswordUtf8();
 				ProtectedString psCur = new ProtectedString(true, pbCur);
-				Array.Clear(pbCur, 0, pbCur.Length);
+				MemUtil.ZeroByteArray(pbCur);
 				pwp = PwProfile.DeriveFromPassword(psCur);
 			}
 			else
 			{
-				foreach(PwProfile pwgo in Program.Config.PasswordGenerator.UserProfiles)
+				foreach(PwProfile pwgo in PwGeneratorUtil.GetAllProfiles(false))
 				{
 					if(pwgo.Name == e.ItemName)
 					{
@@ -1439,12 +1397,11 @@ namespace KeePass.Forms
 
 			if(pwp != null)
 			{
-				ProtectedString psNew = new ProtectedString(true);
-				PwGenerator.Generate(psNew, pwp, null, Program.PwGeneratorPool);
+				ProtectedString psNew;
+				PwGenerator.Generate(out psNew, pwp, null, Program.PwGeneratorPool);
 				byte[] pbNew = psNew.ReadUtf8();
-				m_secPassword.SetPassword(pbNew);
-				m_secRepeat.SetPassword(pbNew);
-				Array.Clear(pbNew, 0, pbNew.Length);
+				m_icgPassword.SetPassword(pbNew, true);
+				MemUtil.ZeroByteArray(pbNew);
 			}
 			else { Debug.Assert(false); }
 		}
@@ -1454,11 +1411,8 @@ namespace KeePass.Forms
 			m_dynGenProfiles.Clear();
 			m_dynGenProfiles.AddItem(DeriveFromPrevious, Properties.Resources.B16x16_CompFile);
 
-			PwGeneratorUtil.AddStandardProfilesIfNoneAvailable();
-
-			if(Program.Config.PasswordGenerator.UserProfiles.Count > 0)
-				m_dynGenProfiles.AddSeparator();
-			foreach(PwProfile pwgo in Program.Config.PasswordGenerator.UserProfiles)
+			m_dynGenProfiles.AddSeparator();
+			foreach(PwProfile pwgo in PwGeneratorUtil.GetAllProfiles(true))
 			{
 				if(pwgo.Name != DeriveFromPrevious)
 					m_dynGenProfiles.AddItem(pwgo.Name,
@@ -1629,11 +1583,9 @@ namespace KeePass.Forms
 			string strRef = CreateFieldReference();
 			if(strRef.Length == 0) return;
 
-			string strPw = StrUtil.Utf8.GetString(m_secPassword.ToUtf8());
-			string strRep = StrUtil.Utf8.GetString(m_secRepeat.ToUtf8());
-
-			m_secPassword.SetPassword(StrUtil.Utf8.GetBytes(strPw + strRef));
-			m_secRepeat.SetPassword(StrUtil.Utf8.GetBytes(strRep + strRef));
+			string strPw = m_icgPassword.GetPassword();
+			string strRep = m_icgPassword.GetRepeat();
+			m_icgPassword.SetPasswords(strPw + strRef, strRep + strRef);
 		}
 
 		private void OnFieldRefInUrl(object sender, EventArgs e)
@@ -1659,24 +1611,36 @@ namespace KeePass.Forms
 
 		private void OnFormClosing(object sender, FormClosingEventArgs e)
 		{
-			/* VistaTaskDialog dlg = new VistaTaskDialog(this.Handle);
-			dlg.AddButton((int)DialogResult.Yes, KPRes.Yes, null);
-			dlg.AddButton((int)DialogResult.No, KPRes.No, null);
-			dlg.CommandLinks = false;
-			dlg.Content = KPRes.CloseDialogWarning;
-			dlg.MainInstruction = KPRes.CloseDialogConfirmation;
-			dlg.VerificationText = KPRes.DialogNoShowAgain;
-			dlg.WindowTitle = PwDefs.ShortProductName;
-
-			if(dlg.ShowDialog())
+			bool bCancel = false;
+			if(!m_bForceClosing && (m_pwEditMode != PwEditMode.ViewReadOnlyEntry))
 			{
-				if((dlg.Result == (int)DialogResult.No) ||
-					(dlg.Result == (int)DialogResult.Cancel))
+				PwEntry pe = m_pwInitialEntry.CloneDeep();
+				SaveEntry(pe, false);
+
+				bool bModified = !pe.EqualsEntry(m_pwInitialEntry, m_cmpOpt,
+					MemProtCmpMode.CustomOnly);
+				bModified |= !m_icgPassword.ValidateData(false);
+
+				if(bModified)
 				{
-					e.Cancel = true;
-					return;
+					DialogResult dr = MessageService.Ask(KPRes.SaveBeforeCloseQuestion,
+						PwDefs.ShortProductName, MessageBoxButtons.YesNoCancel);
+					if((dr == DialogResult.Yes) || (dr == DialogResult.OK))
+					{
+						bCancel = !SaveEntry(m_pwEntry, true);
+						if(!bCancel) this.DialogResult = DialogResult.OK;
+					}
+					else if(dr == DialogResult.Cancel) bCancel = true;
 				}
-			} */
+			}
+			if(bCancel)
+			{
+				this.DialogResult = DialogResult.None;
+				e.Cancel = true;
+				return;
+			}
+
+			if(!m_bTouchedOnce) m_pwEntry.Touch(false, false);
 
 			CleanUpEx();
 		}
diff --git a/KeePass/Forms/PwEntryForm.resx b/KeePass/Forms/PwEntryForm.resx
index 92d2cbb..72825d9 100644
--- a/KeePass/Forms/PwEntryForm.resx
+++ b/KeePass/Forms/PwEntryForm.resx
@@ -126,9 +126,6 @@
   <metadata name="m_ttBalloon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>113, 17</value>
   </metadata>
-  <metadata name="m_ttValidationError.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>224, 17</value>
-  </metadata>
   <metadata name="m_ctxListOperations.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>642, 17</value>
   </metadata>
diff --git a/KeePass/Forms/PwGeneratorForm.cs b/KeePass/Forms/PwGeneratorForm.cs
index 5f8f372..1fd6be8 100644
--- a/KeePass/Forms/PwGeneratorForm.cs
+++ b/KeePass/Forms/PwGeneratorForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -166,9 +166,7 @@ namespace KeePass.Forms
 
 			m_cmbProfiles.SelectedIndex = ((m_optInitial == null) ? 0 : 1);
 
-			PwGeneratorUtil.AddStandardProfilesIfNoneAvailable();
-
-			foreach(PwProfile ppw in Program.Config.PasswordGenerator.UserProfiles)
+			foreach(PwProfile ppw in PwGeneratorUtil.GetAllProfiles(true))
 			{
 				m_cmbProfiles.Items.Add(ppw.Name);
 
@@ -235,8 +233,8 @@ namespace KeePass.Forms
 
 			string strProfile = m_cmbProfiles.Text;
 			m_btnProfileRemove.Enabled = ((strProfile != CustomMeta) &&
-				(strProfile != DeriveFromPrevious) &&
-				(strProfile != AutoGeneratedMeta));
+				(strProfile != DeriveFromPrevious) && (strProfile != AutoGeneratedMeta) &&
+				!PwGeneratorUtil.IsBuiltInProfile(strProfile));
 
 			m_tabAdvanced.Text = ((m_cbExcludeLookAlike.Checked ||
 				m_cbNoRepeat.Checked || (m_tbExcludeChars.Text.Length > 0)) ?
@@ -373,7 +371,7 @@ namespace KeePass.Forms
 				SetGenerationOptions(Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile);
 			else
 			{
-				foreach(PwProfile pwgo in Program.Config.PasswordGenerator.UserProfiles)
+				foreach(PwProfile pwgo in PwGeneratorUtil.GetAllProfiles(false))
 				{
 					if(pwgo.Name == strProfile)
 					{
@@ -406,7 +404,7 @@ namespace KeePass.Forms
 				pwCurrent.Name = strProfile;
 
 				if(strProfile.Equals(CustomMeta) || strProfile.Equals(DeriveFromPrevious) ||
-					(strProfile.Length == 0))
+					(strProfile.Length == 0) || PwGeneratorUtil.IsBuiltInProfile(strProfile))
 				{
 					MessageService.ShowWarning(KPRes.FieldNameInvalid);
 				}
@@ -418,22 +416,53 @@ namespace KeePass.Forms
 				}
 				else
 				{
+					List<PwProfile> lUser = Program.Config.PasswordGenerator.UserProfiles;
+
 					bool bExists = false;
-					for(int i = 0; i < Program.Config.PasswordGenerator.UserProfiles.Count; ++i)
+					for(int i = 0; i < lUser.Count; ++i)
 					{
-						if(Program.Config.PasswordGenerator.UserProfiles[i].Name == strProfile)
+						if(lUser[i].Name.Equals(strProfile, StrUtil.CaseIgnoreCmp))
 						{
-							Program.Config.PasswordGenerator.UserProfiles[i] = pwCurrent;
-							m_cmbProfiles.SelectedIndex = m_cmbProfiles.FindString(strProfile);
-							bExists = true;
+							lUser[i] = pwCurrent;
+
+							for(int j = 0; j < m_cmbProfiles.Items.Count; ++j)
+							{
+								if(m_cmbProfiles.Items[j].ToString().Equals(strProfile,
+									StrUtil.CaseIgnoreCmp))
+								{
+									m_bBlockUIUpdate = true;
+									m_cmbProfiles.Items[j] = strProfile; // Fix case
+									m_bBlockUIUpdate = false;
+									m_cmbProfiles.SelectedIndex = j;
+									bExists = true;
+									break;
+								}
+							}
+
+							break;
 						}
 					}
 
-					if(bExists == false)
+					if(!bExists)
 					{
-						Program.Config.PasswordGenerator.UserProfiles.Add(pwCurrent);
-						m_cmbProfiles.Items.Add(strProfile);
-						m_cmbProfiles.SelectedIndex = m_cmbProfiles.Items.Count - 1;
+						m_bBlockUIUpdate = true;
+
+						List<PwProfile> lAll = PwGeneratorUtil.GetAllProfiles(false);
+						for(int c = 0; c < lAll.Count; ++c)
+							m_cmbProfiles.Items.RemoveAt(m_cmbProfiles.Items.Count - 1);
+
+						lUser.Add(pwCurrent);
+
+						int iNewSel = 0;
+						foreach(PwProfile pwAdd in PwGeneratorUtil.GetAllProfiles(true))
+						{
+							m_cmbProfiles.Items.Add(pwAdd.Name);
+							if(pwAdd.Name == strProfile)
+								iNewSel = m_cmbProfiles.Items.Count - 1;
+						}
+
+						m_bBlockUIUpdate = false;
+						m_cmbProfiles.SelectedIndex = iNewSel;
 					}
 				}
 			}
@@ -447,7 +476,7 @@ namespace KeePass.Forms
 			string strProfile = m_cmbProfiles.Text;
 
 			if((strProfile == CustomMeta) || (strProfile == DeriveFromPrevious) ||
-				(strProfile == AutoGeneratedMeta))
+				(strProfile == AutoGeneratedMeta) || PwGeneratorUtil.IsBuiltInProfile(strProfile))
 				return;
 
 			m_cmbProfiles.SelectedIndex = 0;
@@ -457,12 +486,12 @@ namespace KeePass.Forms
 				{
 					m_cmbProfiles.Items.RemoveAt(i);
 
-					List<PwProfile> lProfiles = Program.Config.PasswordGenerator.UserProfiles;
-					for(int j = 0; j < lProfiles.Count; ++j)
+					List<PwProfile> lUser = Program.Config.PasswordGenerator.UserProfiles;
+					for(int j = 0; j < lUser.Count; ++j)
 					{
-						if(lProfiles[j].Name == strProfile)
+						if(lUser[j].Name == strProfile)
 						{
-							lProfiles.RemoveAt(j);
+							lUser.RemoveAt(j);
 							break;
 						}
 					}
@@ -500,8 +529,8 @@ namespace KeePass.Forms
 			{
 				Application.DoEvents();
 
-				ProtectedString psNew = new ProtectedString(false);
-				PwGenerator.Generate(psNew, pwOpt, null, Program.PwGeneratorPool);
+				ProtectedString psNew;
+				PwGenerator.Generate(out psNew, pwOpt, null, Program.PwGeneratorPool);
 				sbList.AppendLine(psNew.ReadString());
 				m_pbPreview.Value = (int)((100 * i) / MaxPreviewPasswords);
 			}
diff --git a/KeePass/Forms/SearchForm.cs b/KeePass/Forms/SearchForm.cs
index 56f4e1f..4e8e30d 100644
--- a/KeePass/Forms/SearchForm.cs
+++ b/KeePass/Forms/SearchForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/SingleLineEditForm.cs b/KeePass/Forms/SingleLineEditForm.cs
index 58b7802..93b5fea 100644
--- a/KeePass/Forms/SingleLineEditForm.cs
+++ b/KeePass/Forms/SingleLineEditForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/StatusLoggerForm.cs b/KeePass/Forms/StatusLoggerForm.cs
index 86e9e95..2f7bd06 100644
--- a/KeePass/Forms/StatusLoggerForm.cs
+++ b/KeePass/Forms/StatusLoggerForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/StatusProgressForm.cs b/KeePass/Forms/StatusProgressForm.cs
index 786046d..c0f14cf 100644
--- a/KeePass/Forms/StatusProgressForm.cs
+++ b/KeePass/Forms/StatusProgressForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/TanWizardForm.cs b/KeePass/Forms/TanWizardForm.cs
index 5e5f8ab..38a70e0 100644
--- a/KeePass/Forms/TanWizardForm.cs
+++ b/KeePass/Forms/TanWizardForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/TextEncodingForm.cs b/KeePass/Forms/TextEncodingForm.cs
index a10adf2..96be9d0 100644
--- a/KeePass/Forms/TextEncodingForm.cs
+++ b/KeePass/Forms/TextEncodingForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/UpdateCheckForm.Designer.cs b/KeePass/Forms/UpdateCheckForm.Designer.cs
new file mode 100644
index 0000000..ac9d945
--- /dev/null
+++ b/KeePass/Forms/UpdateCheckForm.Designer.cs
@@ -0,0 +1,129 @@
+namespace KeePass.Forms
+{
+	partial class UpdateCheckForm
+	{
+		/// <summary>
+		/// Required designer variable.
+		/// </summary>
+		private System.ComponentModel.IContainer components = null;
+
+		/// <summary>
+		/// Clean up any resources being used.
+		/// </summary>
+		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+		protected override void Dispose(bool disposing)
+		{
+			if(disposing && (components != null))
+			{
+				components.Dispose();
+			}
+			base.Dispose(disposing);
+		}
+
+		#region Windows Form Designer generated code
+
+		/// <summary>
+		/// Required method for Designer support - do not modify
+		/// the contents of this method with the code editor.
+		/// </summary>
+		private void InitializeComponent()
+		{
+			this.m_btnClose = new System.Windows.Forms.Button();
+			this.m_bannerImage = new System.Windows.Forms.PictureBox();
+			this.m_lvInfo = new KeePass.UI.CustomListViewEx();
+			this.m_linkWeb = new System.Windows.Forms.LinkLabel();
+			this.m_linkPlugins = new System.Windows.Forms.LinkLabel();
+			((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit();
+			this.SuspendLayout();
+			// 
+			// m_btnClose
+			// 
+			this.m_btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+			this.m_btnClose.Location = new System.Drawing.Point(509, 310);
+			this.m_btnClose.Name = "m_btnClose";
+			this.m_btnClose.Size = new System.Drawing.Size(75, 23);
+			this.m_btnClose.TabIndex = 0;
+			this.m_btnClose.Text = "&Close";
+			this.m_btnClose.UseVisualStyleBackColor = true;
+			// 
+			// m_bannerImage
+			// 
+			this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top;
+			this.m_bannerImage.Location = new System.Drawing.Point(0, 0);
+			this.m_bannerImage.Name = "m_bannerImage";
+			this.m_bannerImage.Size = new System.Drawing.Size(596, 60);
+			this.m_bannerImage.TabIndex = 1;
+			this.m_bannerImage.TabStop = false;
+			// 
+			// m_lvInfo
+			// 
+			this.m_lvInfo.FullRowSelect = true;
+			this.m_lvInfo.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
+			this.m_lvInfo.Location = new System.Drawing.Point(12, 71);
+			this.m_lvInfo.MultiSelect = false;
+			this.m_lvInfo.Name = "m_lvInfo";
+			this.m_lvInfo.ShowItemToolTips = true;
+			this.m_lvInfo.Size = new System.Drawing.Size(572, 233);
+			this.m_lvInfo.TabIndex = 1;
+			this.m_lvInfo.UseCompatibleStateImageBehavior = false;
+			this.m_lvInfo.View = System.Windows.Forms.View.Details;
+			this.m_lvInfo.ItemActivate += new System.EventHandler(this.OnInfoItemActivate);
+			// 
+			// m_linkWeb
+			// 
+			this.m_linkWeb.AutoSize = true;
+			this.m_linkWeb.Location = new System.Drawing.Point(9, 315);
+			this.m_linkWeb.Name = "m_linkWeb";
+			this.m_linkWeb.Size = new System.Drawing.Size(91, 13);
+			this.m_linkWeb.TabIndex = 2;
+			this.m_linkWeb.TabStop = true;
+			this.m_linkWeb.Text = "KeePass Website";
+			this.m_linkWeb.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkWeb);
+			// 
+			// m_linkPlugins
+			// 
+			this.m_linkPlugins.AutoSize = true;
+			this.m_linkPlugins.Location = new System.Drawing.Point(106, 315);
+			this.m_linkPlugins.Name = "m_linkPlugins";
+			this.m_linkPlugins.Size = new System.Drawing.Size(69, 13);
+			this.m_linkPlugins.TabIndex = 3;
+			this.m_linkPlugins.TabStop = true;
+			this.m_linkPlugins.Text = "Plugins Page";
+			this.m_linkPlugins.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkPlugins);
+			// 
+			// UpdateCheckForm
+			// 
+			this.AcceptButton = this.m_btnClose;
+			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+			this.CancelButton = this.m_btnClose;
+			this.ClientSize = new System.Drawing.Size(596, 345);
+			this.Controls.Add(this.m_linkPlugins);
+			this.Controls.Add(this.m_linkWeb);
+			this.Controls.Add(this.m_lvInfo);
+			this.Controls.Add(this.m_bannerImage);
+			this.Controls.Add(this.m_btnClose);
+			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+			this.MaximizeBox = false;
+			this.MinimizeBox = false;
+			this.Name = "UpdateCheckForm";
+			this.ShowInTaskbar = false;
+			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+			this.Text = "<>";
+			this.Load += new System.EventHandler(this.OnFormLoad);
+			this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed);
+			((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit();
+			this.ResumeLayout(false);
+			this.PerformLayout();
+
+		}
+
+		#endregion
+
+		private System.Windows.Forms.Button m_btnClose;
+		private System.Windows.Forms.PictureBox m_bannerImage;
+		private KeePass.UI.CustomListViewEx m_lvInfo;
+		private System.Windows.Forms.LinkLabel m_linkWeb;
+		private System.Windows.Forms.LinkLabel m_linkPlugins;
+	}
+}
\ No newline at end of file
diff --git a/KeePass/Forms/UpdateCheckForm.cs b/KeePass/Forms/UpdateCheckForm.cs
new file mode 100644
index 0000000..2088a86
--- /dev/null
+++ b/KeePass/Forms/UpdateCheckForm.cs
@@ -0,0 +1,202 @@
+/*
+  KeePass Password Safe - The Open-Source Password Manager
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Diagnostics;
+
+using KeePass.Native;
+using KeePass.Resources;
+using KeePass.UI;
+using KeePass.Util;
+
+using KeePassLib;
+using KeePassLib.Utility;
+
+namespace KeePass.Forms
+{
+	public partial class UpdateCheckForm : Form, IGwmWindow
+	{
+		private List<UpdateComponentInfo> m_lInfo = null;
+		private ImageList m_ilIcons = null;
+
+		public bool CanCloseWithoutDataLoss { get { return true; } }
+
+		public void InitEx(List<UpdateComponentInfo> lInfo, bool bModal)
+		{
+			m_lInfo = lInfo;
+
+			if(!bModal) this.ShowInTaskbar = true;
+		}
+
+		public UpdateCheckForm()
+		{
+			InitializeComponent();
+			Program.Translation.ApplyTo(this);
+		}
+
+		private void OnFormLoad(object sender, EventArgs e)
+		{
+			if(m_lInfo == null) throw new InvalidOperationException();
+
+			GlobalWindowManager.AddWindow(this, this);
+
+			BannerFactory.CreateBannerEx(this, m_bannerImage,
+				Properties.Resources.B48x48_WWW, KPRes.UpdateCheck,
+				KPRes.UpdateCheckResults);
+			this.Icon = Properties.Resources.KeePass;
+			this.Text = KPRes.UpdateCheck + " - " + PwDefs.ShortProductName;
+
+			// UIUtil.SetExplorerTheme(m_lvInfo.Handle);
+
+			int nWidth = m_lvInfo.ClientRectangle.Width - UIUtil.GetVScrollBarWidth();
+			m_lvInfo.Columns.Add(KPRes.Component, (nWidth * 2) / 6);
+			m_lvInfo.Columns.Add(KPRes.Status, (nWidth * 2) / 6);
+			m_lvInfo.Columns.Add(KPRes.Installed, nWidth / 6);
+			m_lvInfo.Columns.Add(KPRes.Available, nWidth / 6);
+
+			List<Image> lImages = new List<Image>();
+			lImages.Add(Properties.Resources.B16x16_Help);
+			lImages.Add(Properties.Resources.B16x16_Apply);
+			lImages.Add(Properties.Resources.B16x16_Redo);
+			lImages.Add(Properties.Resources.B16x16_History);
+			lImages.Add(Properties.Resources.B16x16_Error);
+			m_ilIcons = UIUtil.BuildImageListUnscaled(lImages, 16, 16);
+
+			m_lvInfo.SmallImageList = m_ilIcons;
+
+			string strCat = string.Empty;
+			ListViewGroup lvg = null;
+
+			foreach(UpdateComponentInfo uc in m_lInfo)
+			{
+				if(uc.Category != strCat)
+				{
+					lvg = new ListViewGroup(uc.Category);
+					m_lvInfo.Groups.Add(lvg);
+					strCat = uc.Category;
+				}
+
+				ListViewItem lvi = new ListViewItem(uc.Name);
+
+				string strStatus = KPRes.Unknown + ".";
+				if(uc.Status == UpdateComponentStatus.UpToDate)
+				{
+					strStatus = KPRes.UpToDate + ".";
+					lvi.ImageIndex = 1;
+				}
+				else if(uc.Status == UpdateComponentStatus.NewVerAvailable)
+				{
+					strStatus = KPRes.NewVersionAvailable + "!";
+					lvi.ImageIndex = 2;
+				}
+				else if(uc.Status == UpdateComponentStatus.PreRelease)
+				{
+					strStatus = KPRes.PreReleaseVersion + ".";
+					lvi.ImageIndex = 3;
+				}
+				else if(uc.Status == UpdateComponentStatus.DownloadFailed)
+				{
+					strStatus = KPRes.UpdateCheckFailedNoDl;
+					lvi.ImageIndex = 4;
+				}
+				else lvi.ImageIndex = 0;
+
+				lvi.SubItems.Add(strStatus);
+				lvi.SubItems.Add(StrUtil.VersionToString(uc.VerInstalled));
+
+				if((uc.Status == UpdateComponentStatus.UpToDate) ||
+					(uc.Status == UpdateComponentStatus.NewVerAvailable) ||
+					(uc.Status == UpdateComponentStatus.PreRelease))
+					lvi.SubItems.Add(StrUtil.VersionToString(uc.VerAvailable));
+				else lvi.SubItems.Add("?");
+
+				if(lvg != null) lvi.Group = lvg;
+				m_lvInfo.Items.Add(lvi);
+			}
+		}
+
+		private void CleanUpEx()
+		{
+			if(m_ilIcons != null)
+			{
+				m_lvInfo.SmallImageList = null;
+				m_ilIcons.Dispose();
+				m_ilIcons = null;
+			}
+		}
+
+		private void OnFormClosed(object sender, FormClosedEventArgs e)
+		{
+			CleanUpEx();
+			GlobalWindowManager.RemoveWindow(this);
+		}
+
+		private void OnLinkWeb(object sender, LinkLabelLinkClickedEventArgs e)
+		{
+			OpenUrl(PwDefs.HomepageUrl);
+		}
+
+		private void OnLinkPlugins(object sender, LinkLabelLinkClickedEventArgs e)
+		{
+			OpenUrl(PwDefs.PluginsUrl);
+		}
+
+		private void OpenUrl(string strUrl)
+		{
+			if(!KeePassLib.Native.NativeLib.IsUnix())
+			{
+				// Process.Start has a considerable delay when opening URLs
+				// here (different thread, etc.), therefore try the native
+				// ShellExecute first (which doesn't have any delay)
+				try
+				{
+					IntPtr h = NativeMethods.ShellExecute(this.Handle,
+						null, strUrl, null, null, NativeMethods.SW_SHOW);
+					long l = h.ToInt64();
+					if((l < 0) || (l > 32)) return;
+					else { Debug.Assert(false); }
+				}
+				catch(Exception) { Debug.Assert(false); }
+			}
+
+			try { Process.Start(strUrl); }
+			catch(Exception) { Debug.Assert(false); }
+		}
+
+		private void OnInfoItemActivate(object sender, EventArgs e)
+		{
+			ListView.SelectedListViewItemCollection lvsic = m_lvInfo.SelectedItems;
+			if((lvsic == null) || (lvsic.Count != 1)) { Debug.Assert(false); return; }
+			ListViewItem lvi = lvsic[0];
+			if((lvi == null) || (lvi.Group == null)) { Debug.Assert(false); return; }
+
+			string strGroup = (lvi.Group.Header ?? string.Empty);
+			if(strGroup == PwDefs.ShortProductName)
+				OpenUrl(PwDefs.HomepageUrl);
+			else if(strGroup == KPRes.Plugins)
+				OpenUrl(PwDefs.PluginsUrl);
+			else { Debug.Assert(false); }
+		}
+	}
+}
diff --git a/KeePass/Forms/AboutForm.resx b/KeePass/Forms/UpdateCheckForm.resx
similarity index 100%
copy from KeePass/Forms/AboutForm.resx
copy to KeePass/Forms/UpdateCheckForm.resx
diff --git a/KeePass/Forms/UrlSchemeForm.cs b/KeePass/Forms/UrlSchemeForm.cs
index 4ff62a8..12917dd 100644
--- a/KeePass/Forms/UrlSchemeForm.cs
+++ b/KeePass/Forms/UrlSchemeForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Forms/UrlSchemesForm.cs b/KeePass/Forms/UrlSchemesForm.cs
index d0e87ae..469d6b6 100644
--- a/KeePass/Forms/UrlSchemesForm.cs
+++ b/KeePass/Forms/UrlSchemesForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/KeePass.csproj b/KeePass/KeePass.csproj
index 2175f7c..1b60651 100644
--- a/KeePass/KeePass.csproj
+++ b/KeePass/KeePass.csproj
@@ -221,6 +221,9 @@
     <Compile Include="..\KeePassLib\Serialization\BinaryReaderEx.cs">
       <Link>KeePassLib\Serialization\BinaryReaderEx.cs</Link>
     </Compile>
+    <Compile Include="..\KeePassLib\Serialization\FileLock.cs">
+      <Link>KeePassLib\Serialization\FileLock.cs</Link>
+    </Compile>
     <Compile Include="..\KeePassLib\Serialization\FileTransactionEx.cs">
       <Link>KeePassLib\Serialization\FileTransactionEx.cs</Link>
     </Compile>
@@ -638,6 +641,12 @@
     <Compile Include="Forms\TextEncodingForm.Designer.cs">
       <DependentUpon>TextEncodingForm.cs</DependentUpon>
     </Compile>
+    <Compile Include="Forms\UpdateCheckForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\UpdateCheckForm.Designer.cs">
+      <DependentUpon>UpdateCheckForm.cs</DependentUpon>
+    </Compile>
     <Compile Include="Forms\UrlSchemeForm.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -705,6 +714,7 @@
       <SubType>Component</SubType>
     </Compile>
     <Compile Include="UI\ProtectedDialog.cs" />
+    <Compile Include="UI\PwInputControlGroup.cs" />
     <Compile Include="UI\RichTextBuilder.cs" />
     <Compile Include="UI\StatusUtil.cs" />
     <Compile Include="UI\TabControlEx.cs">
@@ -905,6 +915,9 @@
     <EmbeddedResource Include="Forms\TextEncodingForm.resx">
       <DependentUpon>TextEncodingForm.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="Forms\UpdateCheckForm.resx">
+      <DependentUpon>UpdateCheckForm.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Forms\UrlSchemeForm.resx">
       <DependentUpon>UrlSchemeForm.cs</DependentUpon>
     </EmbeddedResource>
@@ -929,7 +942,6 @@
     <Compile Include="UI\UIUtil.cs" />
     <Compile Include="Util\AppLocator.cs" />
     <Compile Include="Util\AutoType.cs" />
-    <Compile Include="Util\CheckForUpdate.cs" />
     <Compile Include="Util\ClipboardContents.cs" />
     <Compile Include="Util\ClipboardEventChainBlocker.cs" />
     <Compile Include="Util\ClipboardUtil.cs" />
@@ -976,6 +988,7 @@
     <Compile Include="Util\Spr\SprEngine.PickChars.cs" />
     <Compile Include="Util\TempFilesPool.cs" />
     <Compile Include="Util\TextSimilarity.cs" />
+    <Compile Include="Util\UpdateCheckEx.cs" />
     <Compile Include="Util\WinUtil.cs" />
     <Compile Include="Util\XmlUtil.cs" />
   </ItemGroup>
diff --git a/KeePass/Native/NativeMethods.Defs.cs b/KeePass/Native/NativeMethods.Defs.cs
index 1fa6b1f..46b33c6 100644
--- a/KeePass/Native/NativeMethods.Defs.cs
+++ b/KeePass/Native/NativeMethods.Defs.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -89,6 +89,8 @@ namespace KeePass.Native
 
 		internal const int WS_VISIBLE = 0x10000000;
 
+		internal const int SW_SHOW = 5;
+
 		internal const int GCLP_HICON = -14;
 		internal const int GCLP_HICONSM = -34;
 
@@ -215,6 +217,10 @@ namespace KeePass.Native
 		// internal const uint LVGS_SUBSETED = 0x00000040;
 		// internal const uint LVGS_SUBSETLINKFOCUSED = 0x00000080;
 
+		// private const int TTN_FIRST = -520;
+		// internal const int TTN_NEEDTEXTA = TTN_FIRST;
+		// internal const int TTN_NEEDTEXTW = TTN_FIRST - 10;
+
 		[return: MarshalAs(UnmanagedType.Bool)]
 		internal delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
 
diff --git a/KeePass/Native/NativeMethods.New.cs b/KeePass/Native/NativeMethods.New.cs
index d7e297d..fc22ce7 100644
--- a/KeePass/Native/NativeMethods.New.cs
+++ b/KeePass/Native/NativeMethods.New.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Native/NativeMethods.Structs.cs b/KeePass/Native/NativeMethods.Structs.cs
index 74a81fc..a5eea28 100644
--- a/KeePass/Native/NativeMethods.Structs.cs
+++ b/KeePass/Native/NativeMethods.Structs.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -189,6 +189,14 @@ namespace KeePass.Native
 			public Int32 iOrder;
 		}
 
+		// [StructLayout(LayoutKind.Sequential)]
+		// internal struct NMHDR
+		// {
+		//	public IntPtr hwndFrom;
+		//	public IntPtr idFrom;
+		//	public int code;
+		// }
+
 		[StructLayout(LayoutKind.Sequential)]
 		private struct LASTINPUTINFO
 		{
diff --git a/KeePass/Native/NativeMethods.Unix.cs b/KeePass/Native/NativeMethods.Unix.cs
index 31be498..1a59394 100644
--- a/KeePass/Native/NativeMethods.Unix.cs
+++ b/KeePass/Native/NativeMethods.Unix.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Native/NativeMethods.cs b/KeePass/Native/NativeMethods.cs
index 32ab2db..e0ce628 100644
--- a/KeePass/Native/NativeMethods.cs
+++ b/KeePass/Native/NativeMethods.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -378,5 +378,10 @@ namespace KeePass.Native
 		[return: MarshalAs(UnmanagedType.Bool)]
 		internal static extern bool PlaySound(string pszSound, IntPtr hmod,
 			uint fdwSound);
+
+		[DllImport("Shell32.dll", CharSet = CharSet.Auto)]
+		internal static extern IntPtr ShellExecute(IntPtr hwnd,
+			string lpOperation, string lpFile, string lpParameters,
+			string lpDirectory, int nShowCmd);
 	}
 }
diff --git a/KeePass/Native/NativeProgressDialog.cs b/KeePass/Native/NativeProgressDialog.cs
index 371ab80..46dcd40 100644
--- a/KeePass/Native/NativeProgressDialog.cs
+++ b/KeePass/Native/NativeProgressDialog.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/DefaultPluginHost.cs b/KeePass/Plugins/DefaultPluginHost.cs
index 395205b..427e2e0 100644
--- a/KeePass/Plugins/DefaultPluginHost.cs
+++ b/KeePass/Plugins/DefaultPluginHost.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/IPluginHost.cs b/KeePass/Plugins/IPluginHost.cs
index 746f746..7c71610 100644
--- a/KeePass/Plugins/IPluginHost.cs
+++ b/KeePass/Plugins/IPluginHost.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/PlgxCache.cs b/KeePass/Plugins/PlgxCache.cs
index 3714833..4bc3d8e 100644
--- a/KeePass/Plugins/PlgxCache.cs
+++ b/KeePass/Plugins/PlgxCache.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/PlgxCsprojLoader.cs b/KeePass/Plugins/PlgxCsprojLoader.cs
index 16f5a1a..c1f3949 100644
--- a/KeePass/Plugins/PlgxCsprojLoader.cs
+++ b/KeePass/Plugins/PlgxCsprojLoader.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/PlgxPlugin.cs b/KeePass/Plugins/PlgxPlugin.cs
index 3e24e0f..d101514 100644
--- a/KeePass/Plugins/PlgxPlugin.cs
+++ b/KeePass/Plugins/PlgxPlugin.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -524,11 +524,24 @@ namespace KeePass.Plugins
 			CompileEmbeddedRes(plgx);
 			PrepareSourceFiles(plgx);
 
-			string[] vCompilers = new string[] {
-				null, "v3.5",
-				"v4", // Suggested in CodeDomProvider.CreateProvider doc
-				"v4.0" // Apparently works for most people
-			};
+			string[] vCompilers;
+			if(Environment.Version.Major >= 4)
+			{
+				vCompilers = new string[] {
+					null,
+					"v4", // Suggested in CodeDomProvider.CreateProvider doc
+					"v4.0", // Apparently works for most people
+					"v3.5"
+				};
+			}
+			else // <= 3.5
+			{
+				vCompilers = new string[] {
+					null, "v3.5",
+					"v4", // Suggested in CodeDomProvider.CreateProvider doc
+					"v4.0" // Apparently works for most people
+				};
+			}
 
 			CompilerResults cr = null;
 			bool bCompiled = false;
diff --git a/KeePass/Plugins/PlgxPluginInfo.cs b/KeePass/Plugins/PlgxPluginInfo.cs
index c60afab..dd5c0de 100644
--- a/KeePass/Plugins/PlgxPluginInfo.cs
+++ b/KeePass/Plugins/PlgxPluginInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/Plugin.cs b/KeePass/Plugins/Plugin.cs
index b5537ca..31f0b5c 100644
--- a/KeePass/Plugins/Plugin.cs
+++ b/KeePass/Plugins/Plugin.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -66,5 +66,14 @@ namespace KeePass.Plugins
 		{
 			get { return null; }
 		}
+
+		/// <summary>
+		/// URL of a version information file. See
+		/// http://keepass.info/help/v2_dev/plg_index.html#upd
+		/// </summary>
+		public virtual string UpdateUrl
+		{
+			get { return null; }
+		}
 	}
 }
diff --git a/KeePass/Plugins/PluginInfo.cs b/KeePass/Plugins/PluginInfo.cs
index 94eb0fe..de91877 100644
--- a/KeePass/Plugins/PluginInfo.cs
+++ b/KeePass/Plugins/PluginInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Plugins/PluginManager.cs b/KeePass/Plugins/PluginManager.cs
index b724c3d..d4afafe 100644
--- a/KeePass/Plugins/PluginManager.cs
+++ b/KeePass/Plugins/PluginManager.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@ namespace KeePass.Plugins
 		{
 			return m_vPlugins.GetEnumerator();
 		}
-
+		
 		public IEnumerator<PluginInfo> GetEnumerator()
 		{
 			return m_vPlugins.GetEnumerator();
diff --git a/KeePass/Program.cs b/KeePass/Program.cs
index 39e2d7c..97c674c 100644
--- a/KeePass/Program.cs
+++ b/KeePass/Program.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Properties/AssemblyInfo.cs b/KeePass/Properties/AssemblyInfo.cs
index e08401f..e822870 100644
--- a/KeePass/Properties/AssemblyInfo.cs
+++ b/KeePass/Properties/AssemblyInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Dominik Reichl")]
 [assembly: AssemblyProduct("KeePass")]
-[assembly: AssemblyCopyright("Copyright © 2003-2011 Dominik Reichl")]
+[assembly: AssemblyCopyright("Copyright © 2003-2012 Dominik Reichl")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -38,5 +38,5 @@ using System.Runtime.InteropServices;
 [assembly: Guid("02020c52-c0da-47c0-9f3f-a6fe76cee400")]
 
 // Assembly version information
-[assembly: AssemblyVersion("2.1.7.*")]
-[assembly: AssemblyFileVersion("2.1.7.0")]
+[assembly: AssemblyVersion("2.1.8.*")]
+[assembly: AssemblyFileVersion("2.1.8.0")]
diff --git a/KeePass/Resources/KPRes.Generated.cs b/KeePass/Resources/KPRes.Generated.cs
index 07cf926..181a09b 100644
--- a/KeePass/Resources/KPRes.Generated.cs
+++ b/KeePass/Resources/KPRes.Generated.cs
@@ -29,7 +29,6 @@ namespace KeePass.Resources
 			m_strAction = TryGetEx(dictNew, "Action", m_strAction);
 			m_strActivateDatabaseTab = TryGetEx(dictNew, "ActivateDatabaseTab", m_strActivateDatabaseTab);
 			m_strAddEntry = TryGetEx(dictNew, "AddEntry", m_strAddEntry);
-			m_strAddEntryBtn = TryGetEx(dictNew, "AddEntryBtn", m_strAddEntryBtn);
 			m_strAddEntryDesc = TryGetEx(dictNew, "AddEntryDesc", m_strAddEntryDesc);
 			m_strAddStringField = TryGetEx(dictNew, "AddStringField", m_strAddStringField);
 			m_strAddStringFieldDesc = TryGetEx(dictNew, "AddStringFieldDesc", m_strAddStringFieldDesc);
@@ -74,6 +73,7 @@ namespace KeePass.Resources
 			m_strAutoTypeEntrySelectionDescShort = TryGetEx(dictNew, "AutoTypeEntrySelectionDescShort", m_strAutoTypeEntrySelectionDescShort);
 			m_strAutoTypeGlobalHint = TryGetEx(dictNew, "AutoTypeGlobalHint", m_strAutoTypeGlobalHint);
 			m_strAutoTypeMatchByTitle = TryGetEx(dictNew, "AutoTypeMatchByTitle", m_strAutoTypeMatchByTitle);
+			m_strAutoTypeMatchByUrlHostInTitle = TryGetEx(dictNew, "AutoTypeMatchByUrlHostInTitle", m_strAutoTypeMatchByUrlHostInTitle);
 			m_strAutoTypeMatchByUrlInTitle = TryGetEx(dictNew, "AutoTypeMatchByUrlInTitle", m_strAutoTypeMatchByUrlInTitle);
 			m_strAutoTypeObfuscationHint = TryGetEx(dictNew, "AutoTypeObfuscationHint", m_strAutoTypeObfuscationHint);
 			m_strAutoTypePrependInitSeqForIE = TryGetEx(dictNew, "AutoTypePrependInitSeqForIE", m_strAutoTypePrependInitSeqForIE);
@@ -83,12 +83,14 @@ namespace KeePass.Resources
 			m_strAutoTypeUnknownPlaceholder = TryGetEx(dictNew, "AutoTypeUnknownPlaceholder", m_strAutoTypeUnknownPlaceholder);
 			m_strAutoTypeXDoToolRequired = TryGetEx(dictNew, "AutoTypeXDoToolRequired", m_strAutoTypeXDoToolRequired);
 			m_strAutoTypeXDoToolRequiredGlobalVer = TryGetEx(dictNew, "AutoTypeXDoToolRequiredGlobalVer", m_strAutoTypeXDoToolRequiredGlobalVer);
+			m_strAvailable = TryGetEx(dictNew, "Available", m_strAvailable);
 			m_strAvailableLanguages = TryGetEx(dictNew, "AvailableLanguages", m_strAvailableLanguages);
 			m_strBackgroundColor = TryGetEx(dictNew, "BackgroundColor", m_strBackgroundColor);
 			m_strBinaryNoConv = TryGetEx(dictNew, "BinaryNoConv", m_strBinaryNoConv);
 			m_strBits = TryGetEx(dictNew, "Bits", m_strBits);
 			m_strBold = TryGetEx(dictNew, "Bold", m_strBold);
 			m_strBrowser = TryGetEx(dictNew, "Browser", m_strBrowser);
+			m_strBuiltIn = TryGetEx(dictNew, "BuiltIn", m_strBuiltIn);
 			m_strButtonBack = TryGetEx(dictNew, "ButtonBack", m_strButtonBack);
 			m_strButtonFinish = TryGetEx(dictNew, "ButtonFinish", m_strButtonFinish);
 			m_strButtonNext = TryGetEx(dictNew, "ButtonNext", m_strButtonNext);
@@ -98,8 +100,7 @@ namespace KeePass.Resources
 			m_strChangeMasterKey = TryGetEx(dictNew, "ChangeMasterKey", m_strChangeMasterKey);
 			m_strChangeMasterKeyIntroShort = TryGetEx(dictNew, "ChangeMasterKeyIntroShort", m_strChangeMasterKeyIntroShort);
 			m_strCheckForUpdAtStart = TryGetEx(dictNew, "CheckForUpdAtStart", m_strCheckForUpdAtStart);
-			m_strChkForUpdGotLatest = TryGetEx(dictNew, "ChkForUpdGotLatest", m_strChkForUpdGotLatest);
-			m_strChkForUpdNewVersion = TryGetEx(dictNew, "ChkForUpdNewVersion", m_strChkForUpdNewVersion);
+			m_strCheckingForUpd = TryGetEx(dictNew, "CheckingForUpd", m_strCheckingForUpd);
 			m_strClearKeyCmdLineParams = TryGetEx(dictNew, "ClearKeyCmdLineParams", m_strClearKeyCmdLineParams);
 			m_strClearMru = TryGetEx(dictNew, "ClearMru", m_strClearMru);
 			m_strClipboard = TryGetEx(dictNew, "Clipboard", m_strClipboard);
@@ -110,9 +111,10 @@ namespace KeePass.Resources
 			m_strCloseButton = TryGetEx(dictNew, "CloseButton", m_strCloseButton);
 			m_strCloseButtonMinimizes = TryGetEx(dictNew, "CloseButtonMinimizes", m_strCloseButtonMinimizes);
 			m_strColumn = TryGetEx(dictNew, "Column", m_strColumn);
+			m_strColumns = TryGetEx(dictNew, "Columns", m_strColumns);
 			m_strCompany = TryGetEx(dictNew, "Company", m_strCompany);
 			m_strComparison = TryGetEx(dictNew, "Comparison", m_strComparison);
-			m_strComponents = TryGetEx(dictNew, "Components", m_strComponents);
+			m_strComponent = TryGetEx(dictNew, "Component", m_strComponent);
 			m_strCondition = TryGetEx(dictNew, "Condition", m_strCondition);
 			m_strConfigAffectAdmin = TryGetEx(dictNew, "ConfigAffectAdmin", m_strConfigAffectAdmin);
 			m_strConfigAffectUser = TryGetEx(dictNew, "ConfigAffectUser", m_strConfigAffectUser);
@@ -181,6 +183,7 @@ namespace KeePass.Resources
 			m_strDescription = TryGetEx(dictNew, "Description", m_strDescription);
 			m_strDetails = TryGetEx(dictNew, "Details", m_strDetails);
 			m_strDialogNoShowAgain = TryGetEx(dictNew, "DialogNoShowAgain", m_strDialogNoShowAgain);
+			m_strDisable = TryGetEx(dictNew, "Disable", m_strDisable);
 			m_strDisabled = TryGetEx(dictNew, "Disabled", m_strDisabled);
 			m_strDisableSaveIfNotModified = TryGetEx(dictNew, "DisableSaveIfNotModified", m_strDisableSaveIfNotModified);
 			m_strDiscardChangesCmd = TryGetEx(dictNew, "DiscardChangesCmd", m_strDiscardChangesCmd);
@@ -202,6 +205,7 @@ namespace KeePass.Resources
 			m_strEmptyMasterPwHint = TryGetEx(dictNew, "EmptyMasterPwHint", m_strEmptyMasterPwHint);
 			m_strEmptyMasterPwQuestion = TryGetEx(dictNew, "EmptyMasterPwQuestion", m_strEmptyMasterPwQuestion);
 			m_strEmptyRecycleBinQuestion = TryGetEx(dictNew, "EmptyRecycleBinQuestion", m_strEmptyRecycleBinQuestion);
+			m_strEnable = TryGetEx(dictNew, "Enable", m_strEnable);
 			m_strEnabled = TryGetEx(dictNew, "Enabled", m_strEnabled);
 			m_strEncoding = TryGetEx(dictNew, "Encoding", m_strEncoding);
 			m_strEncodingAnsi = TryGetEx(dictNew, "EncodingAnsi", m_strEncodingAnsi);
@@ -214,8 +218,6 @@ namespace KeePass.Resources
 			m_strEntry = TryGetEx(dictNew, "Entry", m_strEntry);
 			m_strEntryList = TryGetEx(dictNew, "EntryList", m_strEntryList);
 			m_strEntryListAutoResizeColumns = TryGetEx(dictNew, "EntryListAutoResizeColumns", m_strEntryListAutoResizeColumns);
-			m_strEntryView = TryGetEx(dictNew, "EntryView", m_strEntryView);
-			m_strEntryViewHideProtectedCustomStrings = TryGetEx(dictNew, "EntryViewHideProtectedCustomStrings", m_strEntryViewHideProtectedCustomStrings);
 			m_strEnvironmentVariable = TryGetEx(dictNew, "EnvironmentVariable", m_strEnvironmentVariable);
 			m_strEqualsOp = TryGetEx(dictNew, "EqualsOp", m_strEqualsOp);
 			m_strErrorCode = TryGetEx(dictNew, "ErrorCode", m_strErrorCode);
@@ -333,8 +335,8 @@ namespace KeePass.Resources
 			m_strImportMustReadQuestion = TryGetEx(dictNew, "ImportMustReadQuestion", m_strImportMustReadQuestion);
 			m_strIncompatibleWithSorting = TryGetEx(dictNew, "IncompatibleWithSorting", m_strIncompatibleWithSorting);
 			m_strInheritSettingFromParent = TryGetEx(dictNew, "InheritSettingFromParent", m_strInheritSettingFromParent);
+			m_strInstalled = TryGetEx(dictNew, "Installed", m_strInstalled);
 			m_strInternet = TryGetEx(dictNew, "Internet", m_strInternet);
-			m_strInvalidFileStructure = TryGetEx(dictNew, "InvalidFileStructure", m_strInvalidFileStructure);
 			m_strInvalidKey = TryGetEx(dictNew, "InvalidKey", m_strInvalidKey);
 			m_strInvalidUrl = TryGetEx(dictNew, "InvalidUrl", m_strInvalidUrl);
 			m_strInvalidUserPassword = TryGetEx(dictNew, "InvalidUserPassword", m_strInvalidUserPassword);
@@ -350,7 +352,9 @@ namespace KeePass.Resources
 			m_strKeyboardKeyAlt = TryGetEx(dictNew, "KeyboardKeyAlt", m_strKeyboardKeyAlt);
 			m_strKeyboardKeyCtrl = TryGetEx(dictNew, "KeyboardKeyCtrl", m_strKeyboardKeyCtrl);
 			m_strKeyboardKeyCtrlLeft = TryGetEx(dictNew, "KeyboardKeyCtrlLeft", m_strKeyboardKeyCtrlLeft);
+			m_strKeyboardKeyEsc = TryGetEx(dictNew, "KeyboardKeyEsc", m_strKeyboardKeyEsc);
 			m_strKeyboardKeyModifiers = TryGetEx(dictNew, "KeyboardKeyModifiers", m_strKeyboardKeyModifiers);
+			m_strKeyboardKeyReturn = TryGetEx(dictNew, "KeyboardKeyReturn", m_strKeyboardKeyReturn);
 			m_strKeyboardKeyShift = TryGetEx(dictNew, "KeyboardKeyShift", m_strKeyboardKeyShift);
 			m_strKeyboardKeyShiftLeft = TryGetEx(dictNew, "KeyboardKeyShiftLeft", m_strKeyboardKeyShiftLeft);
 			m_strKeyChanged = TryGetEx(dictNew, "KeyChanged", m_strKeyChanged);
@@ -360,8 +364,8 @@ namespace KeePass.Resources
 			m_strKeyFiles = TryGetEx(dictNew, "KeyFiles", m_strKeyFiles);
 			m_strKeyFileSelect = TryGetEx(dictNew, "KeyFileSelect", m_strKeyFileSelect);
 			m_strKeyFileUseExisting = TryGetEx(dictNew, "KeyFileUseExisting", m_strKeyFileUseExisting);
-			m_strKeyProvWithGuiOnSD = TryGetEx(dictNew, "KeyProvWithGuiOnSD", m_strKeyProvWithGuiOnSD);
-			m_strKeyProvWithGuiOnSDHint = TryGetEx(dictNew, "KeyProvWithGuiOnSDHint", m_strKeyProvWithGuiOnSDHint);
+			m_strKeyProvIncmpWithSD = TryGetEx(dictNew, "KeyProvIncmpWithSD", m_strKeyProvIncmpWithSD);
+			m_strKeyProvIncmpWithSDHint = TryGetEx(dictNew, "KeyProvIncmpWithSDHint", m_strKeyProvIncmpWithSDHint);
 			m_strLanguageSelected = TryGetEx(dictNew, "LanguageSelected", m_strLanguageSelected);
 			m_strLastAccessTime = TryGetEx(dictNew, "LastAccessTime", m_strLastAccessTime);
 			m_strLastModificationTime = TryGetEx(dictNew, "LastModificationTime", m_strLastModificationTime);
@@ -401,6 +405,7 @@ namespace KeePass.Resources
 			m_strNewerNetRequired = TryGetEx(dictNew, "NewerNetRequired", m_strNewerNetRequired);
 			m_strNewGroup = TryGetEx(dictNew, "NewGroup", m_strNewGroup);
 			m_strNewState = TryGetEx(dictNew, "NewState", m_strNewState);
+			m_strNewVersionAvailable = TryGetEx(dictNew, "NewVersionAvailable", m_strNewVersionAvailable);
 			m_strNo = TryGetEx(dictNew, "No", m_strNo);
 			m_strNoFileAccessRead = TryGetEx(dictNew, "NoFileAccessRead", m_strNoFileAccessRead);
 			m_strNoKeyFileSpecifiedMeta = TryGetEx(dictNew, "NoKeyFileSpecifiedMeta", m_strNoKeyFileSpecifiedMeta);
@@ -475,6 +480,7 @@ namespace KeePass.Resources
 			m_strPolicyRequiredFlag = TryGetEx(dictNew, "PolicyRequiredFlag", m_strPolicyRequiredFlag);
 			m_strPolicySaveDatabaseDesc = TryGetEx(dictNew, "PolicySaveDatabaseDesc", m_strPolicySaveDatabaseDesc);
 			m_strPolicyTriggersEditDesc = TryGetEx(dictNew, "PolicyTriggersEditDesc", m_strPolicyTriggersEditDesc);
+			m_strPreReleaseVersion = TryGetEx(dictNew, "PreReleaseVersion", m_strPreReleaseVersion);
 			m_strPrint = TryGetEx(dictNew, "Print", m_strPrint);
 			m_strPrintDesc = TryGetEx(dictNew, "PrintDesc", m_strPrintDesc);
 			m_strQuickSearchExclExpired = TryGetEx(dictNew, "QuickSearchExclExpired", m_strQuickSearchExclExpired);
@@ -483,6 +489,7 @@ namespace KeePass.Resources
 			m_strQuickSearchTb = TryGetEx(dictNew, "QuickSearchTb", m_strQuickSearchTb);
 			m_strRandomMacAddress = TryGetEx(dictNew, "RandomMacAddress", m_strRandomMacAddress);
 			m_strReady = TryGetEx(dictNew, "Ready", m_strReady);
+			m_strRecommended = TryGetEx(dictNew, "Recommended", m_strRecommended);
 			m_strRecycleBin = TryGetEx(dictNew, "RecycleBin", m_strRecycleBin);
 			m_strRecycleBinCollapse = TryGetEx(dictNew, "RecycleBinCollapse", m_strRecycleBinCollapse);
 			m_strRedo = TryGetEx(dictNew, "Redo", m_strRedo);
@@ -492,6 +499,7 @@ namespace KeePass.Resources
 			m_strRepairMode = TryGetEx(dictNew, "RepairMode", m_strRepairMode);
 			m_strRestartKeePassQuestion = TryGetEx(dictNew, "RestartKeePassQuestion", m_strRestartKeePassQuestion);
 			m_strRootDirectory = TryGetEx(dictNew, "RootDirectory", m_strRootDirectory);
+			m_strSameKeybLayout = TryGetEx(dictNew, "SameKeybLayout", m_strSameKeybLayout);
 			m_strSampleEntry = TryGetEx(dictNew, "SampleEntry", m_strSampleEntry);
 			m_strSave = TryGetEx(dictNew, "Save", m_strSave);
 			m_strSaveBeforeCloseQuestion = TryGetEx(dictNew, "SaveBeforeCloseQuestion", m_strSaveBeforeCloseQuestion);
@@ -518,6 +526,7 @@ namespace KeePass.Resources
 			m_strSelectAll = TryGetEx(dictNew, "SelectAll", m_strSelectAll);
 			m_strSelectColor = TryGetEx(dictNew, "SelectColor", m_strSelectColor);
 			m_strSelectDifferentGroup = TryGetEx(dictNew, "SelectDifferentGroup", m_strSelectDifferentGroup);
+			m_strSelectedColumn = TryGetEx(dictNew, "SelectedColumn", m_strSelectedColumn);
 			m_strSelectedLower = TryGetEx(dictNew, "SelectedLower", m_strSelectedLower);
 			m_strSelectFile = TryGetEx(dictNew, "SelectFile", m_strSelectFile);
 			m_strSelectIcon = TryGetEx(dictNew, "SelectIcon", m_strSelectIcon);
@@ -525,11 +534,9 @@ namespace KeePass.Resources
 			m_strSelectLanguageDesc = TryGetEx(dictNew, "SelectLanguageDesc", m_strSelectLanguageDesc);
 			m_strSelfTestFailed = TryGetEx(dictNew, "SelfTestFailed", m_strSelfTestFailed);
 			m_strSequence = TryGetEx(dictNew, "Sequence", m_strSequence);
-			m_strShowAllEntries = TryGetEx(dictNew, "ShowAllEntries", m_strShowAllEntries);
 			m_strShowDerefData = TryGetEx(dictNew, "ShowDerefData", m_strShowDerefData);
 			m_strShowDerefDataAsync = TryGetEx(dictNew, "ShowDerefDataAsync", m_strShowDerefDataAsync);
 			m_strShowEntries = TryGetEx(dictNew, "ShowEntries", m_strShowEntries);
-			m_strShowExpiredEntries = TryGetEx(dictNew, "ShowExpiredEntries", m_strShowExpiredEntries);
 			m_strShowFullPathInTitleBar = TryGetEx(dictNew, "ShowFullPathInTitleBar", m_strShowFullPathInTitleBar);
 			m_strShowIn = TryGetEx(dictNew, "ShowIn", m_strShowIn);
 			m_strShowTrayOnlyIfTrayed = TryGetEx(dictNew, "ShowTrayOnlyIfTrayed", m_strShowTrayOnlyIfTrayed);
@@ -542,6 +549,7 @@ namespace KeePass.Resources
 			m_strStartAndExit = TryGetEx(dictNew, "StartAndExit", m_strStartAndExit);
 			m_strStartMinimizedAndLocked = TryGetEx(dictNew, "StartMinimizedAndLocked", m_strStartMinimizedAndLocked);
 			m_strStartsWith = TryGetEx(dictNew, "StartsWith", m_strStartsWith);
+			m_strStatus = TryGetEx(dictNew, "Status", m_strStatus);
 			m_strStrikeout = TryGetEx(dictNew, "Strikeout", m_strStrikeout);
 			m_strString = TryGetEx(dictNew, "String", m_strString);
 			m_strSuccess = TryGetEx(dictNew, "Success", m_strSuccess);
@@ -595,9 +603,15 @@ namespace KeePass.Resources
 			m_strUnhideSourceCharactersToo = TryGetEx(dictNew, "UnhideSourceCharactersToo", m_strUnhideSourceCharactersToo);
 			m_strUnknown = TryGetEx(dictNew, "Unknown", m_strUnknown);
 			m_strUnknownError = TryGetEx(dictNew, "UnknownError", m_strUnknownError);
-			m_strUnknownFileVersion = TryGetEx(dictNew, "UnknownFileVersion", m_strUnknownFileVersion);
-			m_strUpdateCheckingFailed = TryGetEx(dictNew, "UpdateCheckingFailed", m_strUpdateCheckingFailed);
+			m_strUpdateCheck = TryGetEx(dictNew, "UpdateCheck", m_strUpdateCheck);
+			m_strUpdateCheckEnableQ = TryGetEx(dictNew, "UpdateCheckEnableQ", m_strUpdateCheckEnableQ);
+			m_strUpdateCheckFailedNoDl = TryGetEx(dictNew, "UpdateCheckFailedNoDl", m_strUpdateCheckFailedNoDl);
+			m_strUpdateCheckInfo = TryGetEx(dictNew, "UpdateCheckInfo", m_strUpdateCheckInfo);
+			m_strUpdateCheckInfoPriv = TryGetEx(dictNew, "UpdateCheckInfoPriv", m_strUpdateCheckInfoPriv);
+			m_strUpdateCheckInfoRes = TryGetEx(dictNew, "UpdateCheckInfoRes", m_strUpdateCheckInfoRes);
+			m_strUpdateCheckResults = TryGetEx(dictNew, "UpdateCheckResults", m_strUpdateCheckResults);
 			m_strUpdatedUIState = TryGetEx(dictNew, "UpdatedUIState", m_strUpdatedUIState);
+			m_strUpToDate = TryGetEx(dictNew, "UpToDate", m_strUpToDate);
 			m_strUrl = TryGetEx(dictNew, "Url", m_strUrl);
 			m_strUrlOpenDesc = TryGetEx(dictNew, "UrlOpenDesc", m_strUrlOpenDesc);
 			m_strUrlOpenTitle = TryGetEx(dictNew, "UrlOpenTitle", m_strUrlOpenTitle);
@@ -607,6 +621,7 @@ namespace KeePass.Resources
 			m_strUrlSchemeOverride = TryGetEx(dictNew, "UrlSchemeOverride", m_strUrlSchemeOverride);
 			m_strUrlSchemeOverrides = TryGetEx(dictNew, "UrlSchemeOverrides", m_strUrlSchemeOverrides);
 			m_strUseCustomToolStripRenderer = TryGetEx(dictNew, "UseCustomToolStripRenderer", m_strUseCustomToolStripRenderer);
+			m_strUseFileLocks = TryGetEx(dictNew, "UseFileLocks", m_strUseFileLocks);
 			m_strUseTransactedDatabaseWrites = TryGetEx(dictNew, "UseTransactedDatabaseWrites", m_strUseTransactedDatabaseWrites);
 			m_strUserAccount = TryGetEx(dictNew, "UserAccount", m_strUserAccount);
 			m_strUserName = TryGetEx(dictNew, "UserName", m_strUserName);
@@ -625,7 +640,6 @@ namespace KeePass.Resources
 			m_strWebBrowser = TryGetEx(dictNew, "WebBrowser", m_strWebBrowser);
 			m_strWebSiteLogin = TryGetEx(dictNew, "WebSiteLogin", m_strWebSiteLogin);
 			m_strWebSites = TryGetEx(dictNew, "WebSites", m_strWebSites);
-			m_strWebsiteVisitQuestion = TryGetEx(dictNew, "WebsiteVisitQuestion", m_strWebsiteVisitQuestion);
 			m_strWindowsFavorites = TryGetEx(dictNew, "WindowsFavorites", m_strWindowsFavorites);
 			m_strWindowsOS = TryGetEx(dictNew, "WindowsOS", m_strWindowsOS);
 			m_strWithoutContext = TryGetEx(dictNew, "WithoutContext", m_strWithoutContext);
@@ -641,7 +655,6 @@ namespace KeePass.Resources
 			"Action",
 			"ActivateDatabaseTab",
 			"AddEntry",
-			"AddEntryBtn",
 			"AddEntryDesc",
 			"AddStringField",
 			"AddStringFieldDesc",
@@ -686,6 +699,7 @@ namespace KeePass.Resources
 			"AutoTypeEntrySelectionDescShort",
 			"AutoTypeGlobalHint",
 			"AutoTypeMatchByTitle",
+			"AutoTypeMatchByUrlHostInTitle",
 			"AutoTypeMatchByUrlInTitle",
 			"AutoTypeObfuscationHint",
 			"AutoTypePrependInitSeqForIE",
@@ -695,12 +709,14 @@ namespace KeePass.Resources
 			"AutoTypeUnknownPlaceholder",
 			"AutoTypeXDoToolRequired",
 			"AutoTypeXDoToolRequiredGlobalVer",
+			"Available",
 			"AvailableLanguages",
 			"BackgroundColor",
 			"BinaryNoConv",
 			"Bits",
 			"Bold",
 			"Browser",
+			"BuiltIn",
 			"ButtonBack",
 			"ButtonFinish",
 			"ButtonNext",
@@ -710,8 +726,7 @@ namespace KeePass.Resources
 			"ChangeMasterKey",
 			"ChangeMasterKeyIntroShort",
 			"CheckForUpdAtStart",
-			"ChkForUpdGotLatest",
-			"ChkForUpdNewVersion",
+			"CheckingForUpd",
 			"ClearKeyCmdLineParams",
 			"ClearMru",
 			"Clipboard",
@@ -722,9 +737,10 @@ namespace KeePass.Resources
 			"CloseButton",
 			"CloseButtonMinimizes",
 			"Column",
+			"Columns",
 			"Company",
 			"Comparison",
-			"Components",
+			"Component",
 			"Condition",
 			"ConfigAffectAdmin",
 			"ConfigAffectUser",
@@ -793,6 +809,7 @@ namespace KeePass.Resources
 			"Description",
 			"Details",
 			"DialogNoShowAgain",
+			"Disable",
 			"Disabled",
 			"DisableSaveIfNotModified",
 			"DiscardChangesCmd",
@@ -814,6 +831,7 @@ namespace KeePass.Resources
 			"EmptyMasterPwHint",
 			"EmptyMasterPwQuestion",
 			"EmptyRecycleBinQuestion",
+			"Enable",
 			"Enabled",
 			"Encoding",
 			"EncodingAnsi",
@@ -826,8 +844,6 @@ namespace KeePass.Resources
 			"Entry",
 			"EntryList",
 			"EntryListAutoResizeColumns",
-			"EntryView",
-			"EntryViewHideProtectedCustomStrings",
 			"EnvironmentVariable",
 			"EqualsOp",
 			"ErrorCode",
@@ -945,8 +961,8 @@ namespace KeePass.Resources
 			"ImportMustReadQuestion",
 			"IncompatibleWithSorting",
 			"InheritSettingFromParent",
+			"Installed",
 			"Internet",
-			"InvalidFileStructure",
 			"InvalidKey",
 			"InvalidUrl",
 			"InvalidUserPassword",
@@ -962,7 +978,9 @@ namespace KeePass.Resources
 			"KeyboardKeyAlt",
 			"KeyboardKeyCtrl",
 			"KeyboardKeyCtrlLeft",
+			"KeyboardKeyEsc",
 			"KeyboardKeyModifiers",
+			"KeyboardKeyReturn",
 			"KeyboardKeyShift",
 			"KeyboardKeyShiftLeft",
 			"KeyChanged",
@@ -972,8 +990,8 @@ namespace KeePass.Resources
 			"KeyFiles",
 			"KeyFileSelect",
 			"KeyFileUseExisting",
-			"KeyProvWithGuiOnSD",
-			"KeyProvWithGuiOnSDHint",
+			"KeyProvIncmpWithSD",
+			"KeyProvIncmpWithSDHint",
 			"LanguageSelected",
 			"LastAccessTime",
 			"LastModificationTime",
@@ -1013,6 +1031,7 @@ namespace KeePass.Resources
 			"NewerNetRequired",
 			"NewGroup",
 			"NewState",
+			"NewVersionAvailable",
 			"No",
 			"NoFileAccessRead",
 			"NoKeyFileSpecifiedMeta",
@@ -1087,6 +1106,7 @@ namespace KeePass.Resources
 			"PolicyRequiredFlag",
 			"PolicySaveDatabaseDesc",
 			"PolicyTriggersEditDesc",
+			"PreReleaseVersion",
 			"Print",
 			"PrintDesc",
 			"QuickSearchExclExpired",
@@ -1095,6 +1115,7 @@ namespace KeePass.Resources
 			"QuickSearchTb",
 			"RandomMacAddress",
 			"Ready",
+			"Recommended",
 			"RecycleBin",
 			"RecycleBinCollapse",
 			"Redo",
@@ -1104,6 +1125,7 @@ namespace KeePass.Resources
 			"RepairMode",
 			"RestartKeePassQuestion",
 			"RootDirectory",
+			"SameKeybLayout",
 			"SampleEntry",
 			"Save",
 			"SaveBeforeCloseQuestion",
@@ -1130,6 +1152,7 @@ namespace KeePass.Resources
 			"SelectAll",
 			"SelectColor",
 			"SelectDifferentGroup",
+			"SelectedColumn",
 			"SelectedLower",
 			"SelectFile",
 			"SelectIcon",
@@ -1137,11 +1160,9 @@ namespace KeePass.Resources
 			"SelectLanguageDesc",
 			"SelfTestFailed",
 			"Sequence",
-			"ShowAllEntries",
 			"ShowDerefData",
 			"ShowDerefDataAsync",
 			"ShowEntries",
-			"ShowExpiredEntries",
 			"ShowFullPathInTitleBar",
 			"ShowIn",
 			"ShowTrayOnlyIfTrayed",
@@ -1154,6 +1175,7 @@ namespace KeePass.Resources
 			"StartAndExit",
 			"StartMinimizedAndLocked",
 			"StartsWith",
+			"Status",
 			"Strikeout",
 			"String",
 			"Success",
@@ -1207,9 +1229,15 @@ namespace KeePass.Resources
 			"UnhideSourceCharactersToo",
 			"Unknown",
 			"UnknownError",
-			"UnknownFileVersion",
-			"UpdateCheckingFailed",
+			"UpdateCheck",
+			"UpdateCheckEnableQ",
+			"UpdateCheckFailedNoDl",
+			"UpdateCheckInfo",
+			"UpdateCheckInfoPriv",
+			"UpdateCheckInfoRes",
+			"UpdateCheckResults",
 			"UpdatedUIState",
+			"UpToDate",
 			"Url",
 			"UrlOpenDesc",
 			"UrlOpenTitle",
@@ -1219,6 +1247,7 @@ namespace KeePass.Resources
 			"UrlSchemeOverride",
 			"UrlSchemeOverrides",
 			"UseCustomToolStripRenderer",
+			"UseFileLocks",
 			"UseTransactedDatabaseWrites",
 			"UserAccount",
 			"UserName",
@@ -1237,7 +1266,6 @@ namespace KeePass.Resources
 			"WebBrowser",
 			"WebSiteLogin",
 			"WebSites",
-			"WebsiteVisitQuestion",
 			"WindowsFavorites",
 			"WindowsOS",
 			"WithoutContext",
@@ -1287,17 +1315,6 @@ namespace KeePass.Resources
 			get { return m_strAddEntry; }
 		}
 
-		private static string m_strAddEntryBtn =
-			@"Add Entry...";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'Add Entry...'.
-		/// </summary>
-		public static string AddEntryBtn
-		{
-			get { return m_strAddEntryBtn; }
-		}
-
 		private static string m_strAddEntryDesc =
 			@"Create a new password entry.";
 		/// <summary>
@@ -1782,6 +1799,17 @@ namespace KeePass.Resources
 			get { return m_strAutoTypeMatchByTitle; }
 		}
 
+		private static string m_strAutoTypeMatchByUrlHostInTitle =
+			@"An entry matches if the host component of its URL is contained in the target window title";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'An entry matches if the host component of its URL is contained in the target window title'.
+		/// </summary>
+		public static string AutoTypeMatchByUrlHostInTitle
+		{
+			get { return m_strAutoTypeMatchByUrlHostInTitle; }
+		}
+
 		private static string m_strAutoTypeMatchByUrlInTitle =
 			@"An entry matches if its URL is contained in the target window title";
 		/// <summary>
@@ -1881,6 +1909,17 @@ namespace KeePass.Resources
 			get { return m_strAutoTypeXDoToolRequiredGlobalVer; }
 		}
 
+		private static string m_strAvailable =
+			@"Available";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Available'.
+		/// </summary>
+		public static string Available
+		{
+			get { return m_strAvailable; }
+		}
+
 		private static string m_strAvailableLanguages =
 			@"Available Languages";
 		/// <summary>
@@ -1947,6 +1986,17 @@ namespace KeePass.Resources
 			get { return m_strBrowser; }
 		}
 
+		private static string m_strBuiltIn =
+			@"built-in";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'built-in'.
+		/// </summary>
+		public static string BuiltIn
+		{
+			get { return m_strBuiltIn; }
+		}
+
 		private static string m_strButtonBack =
 			@"< &Back";
 		/// <summary>
@@ -2046,26 +2096,15 @@ namespace KeePass.Resources
 			get { return m_strCheckForUpdAtStart; }
 		}
 
-		private static string m_strChkForUpdGotLatest =
-			@"You have the latest version.";
+		private static string m_strCheckingForUpd =
+			@"Checking for updates";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'You have the latest version.'.
+		/// 'Checking for updates'.
 		/// </summary>
-		public static string ChkForUpdGotLatest
+		public static string CheckingForUpd
 		{
-			get { return m_strChkForUpdGotLatest; }
-		}
-
-		private static string m_strChkForUpdNewVersion =
-			@"New KeePass version available!";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'New KeePass version available!'.
-		/// </summary>
-		public static string ChkForUpdNewVersion
-		{
-			get { return m_strChkForUpdNewVersion; }
+			get { return m_strCheckingForUpd; }
 		}
 
 		private static string m_strClearKeyCmdLineParams =
@@ -2178,6 +2217,17 @@ namespace KeePass.Resources
 			get { return m_strColumn; }
 		}
 
+		private static string m_strColumns =
+			@"Columns";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Columns'.
+		/// </summary>
+		public static string Columns
+		{
+			get { return m_strColumns; }
+		}
+
 		private static string m_strCompany =
 			@"Company";
 		/// <summary>
@@ -2200,15 +2250,15 @@ namespace KeePass.Resources
 			get { return m_strComparison; }
 		}
 
-		private static string m_strComponents =
-			@"Components";
+		private static string m_strComponent =
+			@"Component";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'Components'.
+		/// 'Component'.
 		/// </summary>
-		public static string Components
+		public static string Component
 		{
-			get { return m_strComponents; }
+			get { return m_strComponent; }
 		}
 
 		private static string m_strCondition =
@@ -2959,6 +3009,17 @@ namespace KeePass.Resources
 			get { return m_strDialogNoShowAgain; }
 		}
 
+		private static string m_strDisable =
+			@"Disable";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Disable'.
+		/// </summary>
+		public static string Disable
+		{
+			get { return m_strDisable; }
+		}
+
 		private static string m_strDisabled =
 			@"Disabled";
 		/// <summary>
@@ -3190,6 +3251,17 @@ namespace KeePass.Resources
 			get { return m_strEmptyRecycleBinQuestion; }
 		}
 
+		private static string m_strEnable =
+			@"Enable";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Enable'.
+		/// </summary>
+		public static string Enable
+		{
+			get { return m_strEnable; }
+		}
+
 		private static string m_strEnabled =
 			@"Enabled";
 		/// <summary>
@@ -3322,28 +3394,6 @@ namespace KeePass.Resources
 			get { return m_strEntryListAutoResizeColumns; }
 		}
 
-		private static string m_strEntryView =
-			@"Entry View";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'Entry View'.
-		/// </summary>
-		public static string EntryView
-		{
-			get { return m_strEntryView; }
-		}
-
-		private static string m_strEntryViewHideProtectedCustomStrings =
-			@"Hide in-memory protected custom strings using asterisks";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'Hide in-memory protected custom strings using asterisks'.
-		/// </summary>
-		public static string EntryViewHideProtectedCustomStrings
-		{
-			get { return m_strEntryViewHideProtectedCustomStrings; }
-		}
-
 		private static string m_strEnvironmentVariable =
 			@"Environment variable";
 		/// <summary>
@@ -4631,26 +4681,26 @@ namespace KeePass.Resources
 			get { return m_strInheritSettingFromParent; }
 		}
 
-		private static string m_strInternet =
-			@"Internet";
+		private static string m_strInstalled =
+			@"Installed";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'Internet'.
+		/// 'Installed'.
 		/// </summary>
-		public static string Internet
+		public static string Installed
 		{
-			get { return m_strInternet; }
+			get { return m_strInstalled; }
 		}
 
-		private static string m_strInvalidFileStructure =
-			@"Invalid file structure!";
+		private static string m_strInternet =
+			@"Internet";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'Invalid file structure!'.
+		/// 'Internet'.
 		/// </summary>
-		public static string InvalidFileStructure
+		public static string Internet
 		{
-			get { return m_strInvalidFileStructure; }
+			get { return m_strInternet; }
 		}
 
 		private static string m_strInvalidKey =
@@ -4818,6 +4868,17 @@ namespace KeePass.Resources
 			get { return m_strKeyboardKeyCtrlLeft; }
 		}
 
+		private static string m_strKeyboardKeyEsc =
+			@"Esc";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Esc'.
+		/// </summary>
+		public static string KeyboardKeyEsc
+		{
+			get { return m_strKeyboardKeyEsc; }
+		}
+
 		private static string m_strKeyboardKeyModifiers =
 			@"Key Modifiers";
 		/// <summary>
@@ -4829,6 +4890,17 @@ namespace KeePass.Resources
 			get { return m_strKeyboardKeyModifiers; }
 		}
 
+		private static string m_strKeyboardKeyReturn =
+			@"Return";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Return'.
+		/// </summary>
+		public static string KeyboardKeyReturn
+		{
+			get { return m_strKeyboardKeyReturn; }
+		}
+
 		private static string m_strKeyboardKeyShift =
 			@"Shift";
 		/// <summary>
@@ -4928,26 +5000,26 @@ namespace KeePass.Resources
 			get { return m_strKeyFileUseExisting; }
 		}
 
-		private static string m_strKeyProvWithGuiOnSD =
-			@"The selected key provider cannot be used, because it might try to show a dialog and this isn't allowed on a secure desktop.";
+		private static string m_strKeyProvIncmpWithSD =
+			@"The selected key provider cannot be used, because it is incompatible with the secure desktop.";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'The selected key provider cannot be used, because it might try to show a dialog and this isn't allowed on a secure desktop.'.
+		/// 'The selected key provider cannot be used, because it is incompatible with the secure desktop.'.
 		/// </summary>
-		public static string KeyProvWithGuiOnSD
+		public static string KeyProvIncmpWithSD
 		{
-			get { return m_strKeyProvWithGuiOnSD; }
+			get { return m_strKeyProvIncmpWithSD; }
 		}
 
-		private static string m_strKeyProvWithGuiOnSDHint =
+		private static string m_strKeyProvIncmpWithSDHint =
 			@"If you want to use the selected key provider, you have to disable the secure desktop option in 'Tools' -> 'Options' -> tab 'Security'.";
 		/// <summary>
 		/// Look up a localized string similar to
 		/// 'If you want to use the selected key provider, you have to disable the secure desktop option in 'Tools' -> 'Options' -> tab 'Security'.'.
 		/// </summary>
-		public static string KeyProvWithGuiOnSDHint
+		public static string KeyProvIncmpWithSDHint
 		{
-			get { return m_strKeyProvWithGuiOnSDHint; }
+			get { return m_strKeyProvIncmpWithSDHint; }
 		}
 
 		private static string m_strLanguageSelected =
@@ -5379,6 +5451,17 @@ namespace KeePass.Resources
 			get { return m_strNewState; }
 		}
 
+		private static string m_strNewVersionAvailable =
+			@"New version available";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'New version available'.
+		/// </summary>
+		public static string NewVersionAvailable
+		{
+			get { return m_strNewVersionAvailable; }
+		}
+
 		private static string m_strNo =
 			@"No";
 		/// <summary>
@@ -6193,6 +6276,17 @@ namespace KeePass.Resources
 			get { return m_strPolicyTriggersEditDesc; }
 		}
 
+		private static string m_strPreReleaseVersion =
+			@"Pre-release version";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Pre-release version'.
+		/// </summary>
+		public static string PreReleaseVersion
+		{
+			get { return m_strPreReleaseVersion; }
+		}
+
 		private static string m_strPrint =
 			@"Print";
 		/// <summary>
@@ -6281,6 +6375,17 @@ namespace KeePass.Resources
 			get { return m_strReady; }
 		}
 
+		private static string m_strRecommended =
+			@"recommended";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'recommended'.
+		/// </summary>
+		public static string Recommended
+		{
+			get { return m_strRecommended; }
+		}
+
 		private static string m_strRecycleBin =
 			@"Recycle Bin";
 		/// <summary>
@@ -6380,6 +6485,17 @@ namespace KeePass.Resources
 			get { return m_strRootDirectory; }
 		}
 
+		private static string m_strSameKeybLayout =
+			@"Ensure same keyboard layouts during auto-type";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Ensure same keyboard layouts during auto-type'.
+		/// </summary>
+		public static string SameKeybLayout
+		{
+			get { return m_strSameKeybLayout; }
+		}
+
 		private static string m_strSampleEntry =
 			@"Sample Entry";
 		/// <summary>
@@ -6666,6 +6782,17 @@ namespace KeePass.Resources
 			get { return m_strSelectDifferentGroup; }
 		}
 
+		private static string m_strSelectedColumn =
+			@"Selected column";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Selected column'.
+		/// </summary>
+		public static string SelectedColumn
+		{
+			get { return m_strSelectedColumn; }
+		}
+
 		private static string m_strSelectedLower =
 			@"selected";
 		/// <summary>
@@ -6743,17 +6870,6 @@ namespace KeePass.Resources
 			get { return m_strSequence; }
 		}
 
-		private static string m_strShowAllEntries =
-			@"Show All Entries";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'Show All Entries'.
-		/// </summary>
-		public static string ShowAllEntries
-		{
-			get { return m_strShowAllEntries; }
-		}
-
 		private static string m_strShowDerefData =
 			@"Show dereferenced data";
 		/// <summary>
@@ -6787,17 +6903,6 @@ namespace KeePass.Resources
 			get { return m_strShowEntries; }
 		}
 
-		private static string m_strShowExpiredEntries =
-			@"Show Expired Entries";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'Show Expired Entries'.
-		/// </summary>
-		public static string ShowExpiredEntries
-		{
-			get { return m_strShowExpiredEntries; }
-		}
-
 		private static string m_strShowFullPathInTitleBar =
 			@"Show full path in title bar (instead of file name only)";
 		/// <summary>
@@ -6930,6 +7035,17 @@ namespace KeePass.Resources
 			get { return m_strStartsWith; }
 		}
 
+		private static string m_strStatus =
+			@"Status";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Status'.
+		/// </summary>
+		public static string Status
+		{
+			get { return m_strStatus; }
+		}
+
 		private static string m_strStrikeout =
 			@"Strikeout";
 		/// <summary>
@@ -7470,10 +7586,10 @@ namespace KeePass.Resources
 		}
 
 		private static string m_strUnhidePasswordsDesc =
-			@"Allow displaying passwords as plain text.";
+			@"Allow displaying passwords as plain-text.";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'Allow displaying passwords as plain text.'.
+		/// 'Allow displaying passwords as plain-text.'.
 		/// </summary>
 		public static string UnhidePasswordsDesc
 		{
@@ -7513,26 +7629,81 @@ namespace KeePass.Resources
 			get { return m_strUnknownError; }
 		}
 
-		private static string m_strUnknownFileVersion =
-			@"Unknown file version!";
+		private static string m_strUpdateCheck =
+			@"Update Check";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'Unknown file version!'.
+		/// 'Update Check'.
 		/// </summary>
-		public static string UnknownFileVersion
+		public static string UpdateCheck
 		{
-			get { return m_strUnknownFileVersion; }
+			get { return m_strUpdateCheck; }
 		}
 
-		private static string m_strUpdateCheckingFailed =
-			@"Update checking failed.";
+		private static string m_strUpdateCheckEnableQ =
+			@"Enable automatic update check?";
 		/// <summary>
 		/// Look up a localized string similar to
-		/// 'Update checking failed.'.
+		/// 'Enable automatic update check?'.
 		/// </summary>
-		public static string UpdateCheckingFailed
+		public static string UpdateCheckEnableQ
 		{
-			get { return m_strUpdateCheckingFailed; }
+			get { return m_strUpdateCheckEnableQ; }
+		}
+
+		private static string m_strUpdateCheckFailedNoDl =
+			@"Update check failed. Version information file cannot be downloaded.";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Update check failed. Version information file cannot be downloaded.'.
+		/// </summary>
+		public static string UpdateCheckFailedNoDl
+		{
+			get { return m_strUpdateCheckFailedNoDl; }
+		}
+
+		private static string m_strUpdateCheckInfo =
+			@"KeePass can automatically check for updates on each program start.";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'KeePass can automatically check for updates on each program start.'.
+		/// </summary>
+		public static string UpdateCheckInfo
+		{
+			get { return m_strUpdateCheckInfo; }
+		}
+
+		private static string m_strUpdateCheckInfoPriv =
+			@"No personal information is sent to the KeePass server. KeePass just downloads a small version information file and compares the available version with the installed version.";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'No personal information is sent to the KeePass server. KeePass just downloads a small version information file and compares the available version with the installed version.'.
+		/// </summary>
+		public static string UpdateCheckInfoPriv
+		{
+			get { return m_strUpdateCheckInfoPriv; }
+		}
+
+		private static string m_strUpdateCheckInfoRes =
+			@"Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically.";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically.'.
+		/// </summary>
+		public static string UpdateCheckInfoRes
+		{
+			get { return m_strUpdateCheckInfoRes; }
+		}
+
+		private static string m_strUpdateCheckResults =
+			@"The results of the update check.";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'The results of the update check.'.
+		/// </summary>
+		public static string UpdateCheckResults
+		{
+			get { return m_strUpdateCheckResults; }
 		}
 
 		private static string m_strUpdatedUIState =
@@ -7546,6 +7717,17 @@ namespace KeePass.Resources
 			get { return m_strUpdatedUIState; }
 		}
 
+		private static string m_strUpToDate =
+			@"Up to date";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Up to date'.
+		/// </summary>
+		public static string UpToDate
+		{
+			get { return m_strUpToDate; }
+		}
+
 		private static string m_strUrl =
 			@"URL";
 		/// <summary>
@@ -7645,6 +7827,17 @@ namespace KeePass.Resources
 			get { return m_strUseCustomToolStripRenderer; }
 		}
 
+		private static string m_strUseFileLocks =
+			@"Use database lock files";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Use database lock files'.
+		/// </summary>
+		public static string UseFileLocks
+		{
+			get { return m_strUseFileLocks; }
+		}
+
 		private static string m_strUseTransactedDatabaseWrites =
 			@"Use file transactions for writing databases";
 		/// <summary>
@@ -7843,17 +8036,6 @@ namespace KeePass.Resources
 			get { return m_strWebSites; }
 		}
 
-		private static string m_strWebsiteVisitQuestion =
-			@"Do you want to visit the KeePass website now?";
-		/// <summary>
-		/// Look up a localized string similar to
-		/// 'Do you want to visit the KeePass website now?'.
-		/// </summary>
-		public static string WebsiteVisitQuestion
-		{
-			get { return m_strWebsiteVisitQuestion; }
-		}
-
 		private static string m_strWindowsFavorites =
 			@"Windows Favorites";
 		/// <summary>
diff --git a/KeePass/UI/AsyncPwListUpdate.cs b/KeePass/UI/AsyncPwListUpdate.cs
index 8c47c15..4484f6a 100644
--- a/KeePass/UI/AsyncPwListUpdate.cs
+++ b/KeePass/UI/AsyncPwListUpdate.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/BackgroundForm.cs b/KeePass/UI/BackgroundForm.cs
index f39fa98..6e2a390 100644
--- a/KeePass/UI/BackgroundForm.cs
+++ b/KeePass/UI/BackgroundForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/BannerFactory.cs b/KeePass/UI/BannerFactory.cs
index 5494957..5a03db8 100644
--- a/KeePass/UI/BannerFactory.cs
+++ b/KeePass/UI/BannerFactory.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CheckedLVItemDXList.cs b/KeePass/UI/CheckedLVItemDXList.cs
index 54ada4a..159c65d 100644
--- a/KeePass/UI/CheckedLVItemDXList.cs
+++ b/KeePass/UI/CheckedLVItemDXList.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ColorMenuItem.cs b/KeePass/UI/ColorMenuItem.cs
index 5d1180e..2890ba9 100644
--- a/KeePass/UI/ColorMenuItem.cs
+++ b/KeePass/UI/ColorMenuItem.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ColumnProvider.cs b/KeePass/UI/ColumnProvider.cs
index f35f6d5..10a19eb 100644
--- a/KeePass/UI/ColumnProvider.cs
+++ b/KeePass/UI/ColumnProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ColumnProviderPool.cs b/KeePass/UI/ColumnProviderPool.cs
index 47e8c70..6c5f89c 100644
--- a/KeePass/UI/ColumnProviderPool.cs
+++ b/KeePass/UI/ColumnProviderPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomListViewEx.cs b/KeePass/UI/CustomListViewEx.cs
index 6a493c8..f35c87a 100644
--- a/KeePass/UI/CustomListViewEx.cs
+++ b/KeePass/UI/CustomListViewEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomMenuStripEx.cs b/KeePass/UI/CustomMenuStripEx.cs
index 68d8128..8d09963 100644
--- a/KeePass/UI/CustomMenuStripEx.cs
+++ b/KeePass/UI/CustomMenuStripEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomRichTextBoxEx.cs b/KeePass/UI/CustomRichTextBoxEx.cs
index 40a5585..72ed32c 100644
--- a/KeePass/UI/CustomRichTextBoxEx.cs
+++ b/KeePass/UI/CustomRichTextBoxEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomSplitContainerEx.cs b/KeePass/UI/CustomSplitContainerEx.cs
index 5902713..5be26d5 100644
--- a/KeePass/UI/CustomSplitContainerEx.cs
+++ b/KeePass/UI/CustomSplitContainerEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomToolStripEx.cs b/KeePass/UI/CustomToolStripEx.cs
index 4ed061f..2cfa637 100644
--- a/KeePass/UI/CustomToolStripEx.cs
+++ b/KeePass/UI/CustomToolStripEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomToolStripRendererEx.cs b/KeePass/UI/CustomToolStripRendererEx.cs
index ad78dec..3c9af22 100644
--- a/KeePass/UI/CustomToolStripRendererEx.cs
+++ b/KeePass/UI/CustomToolStripRendererEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/CustomTreeViewEx.cs b/KeePass/UI/CustomTreeViewEx.cs
index 581cad3..9eaa721 100644
--- a/KeePass/UI/CustomTreeViewEx.cs
+++ b/KeePass/UI/CustomTreeViewEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -27,8 +27,21 @@ using KeePass.Native;
 
 namespace KeePass.UI
 {
+	// public delegate string QueryToolTipDelegate(TreeNode tn);
+
 	public sealed class CustomTreeViewEx : TreeView
 	{
+		// private QueryToolTipDelegate m_fnQueryToolTip = null;
+		// /// <summary>
+		// /// This handler will be used to dynamically query tooltip
+		// /// texts for tree nodes.
+		// /// </summary>
+		// public QueryToolTipDelegate QueryToolTip
+		// {
+		//	get { return m_fnQueryToolTip; }
+		//	set { m_fnQueryToolTip = value; }
+		// }
+
 		public CustomTreeViewEx() : base()
 		{
 			// Double-buffering isn't supported by tree views
@@ -65,5 +78,28 @@ namespace KeePass.UI
 			// }
 			// catch(Exception) { }
 		}
+
+		// protected override void WndProc(ref Message m)
+		// {
+		//	if(m.Msg == NativeMethods.WM_NOTIFY)
+		//	{
+		//		NativeMethods.NMHDR nm = (NativeMethods.NMHDR)m.GetLParam(
+		//			typeof(NativeMethods.NMHDR));
+		//		if((nm.code == NativeMethods.TTN_NEEDTEXTA) ||
+		//			(nm.code == NativeMethods.TTN_NEEDTEXTW))
+		//			DynamicAssignNodeToolTip();
+		//	}
+		//	base.WndProc(ref m);
+		// }
+
+		// private void DynamicAssignNodeToolTip()
+		// {
+		//	if(m_fnQueryToolTip == null) return;
+		//	TreeViewHitTestInfo hti = HitTest(PointToClient(Cursor.Position));
+		//	if(hti == null) { Debug.Assert(false); return; }
+		//	TreeNode tn = hti.Node;
+		//	if(tn == null) return;
+		//	tn.ToolTipText = (m_fnQueryToolTip(tn) ?? string.Empty);
+		// }
 	}
 }
diff --git a/KeePass/UI/DocumentManagerEx.cs b/KeePass/UI/DocumentManagerEx.cs
index 839d1d0..0568f56 100644
--- a/KeePass/UI/DocumentManagerEx.cs
+++ b/KeePass/UI/DocumentManagerEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/DynamicMenu.cs b/KeePass/UI/DynamicMenu.cs
index de94bda..b420e83 100644
--- a/KeePass/UI/DynamicMenu.cs
+++ b/KeePass/UI/DynamicMenu.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/FileDialogsEx.cs b/KeePass/UI/FileDialogsEx.cs
index 4570209..5242fd5 100644
--- a/KeePass/UI/FileDialogsEx.cs
+++ b/KeePass/UI/FileDialogsEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/FontUtil.cs b/KeePass/UI/FontUtil.cs
index ece8c71..7c82cce 100644
--- a/KeePass/UI/FontUtil.cs
+++ b/KeePass/UI/FontUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/GlobalWindowManager.cs b/KeePass/UI/GlobalWindowManager.cs
index 1b38ab0..2788156 100644
--- a/KeePass/UI/GlobalWindowManager.cs
+++ b/KeePass/UI/GlobalWindowManager.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -177,14 +177,28 @@ namespace KeePass.UI
 				if(kvp.Value == null) continue;
 				else if(kvp.Value.CanCloseWithoutDataLoss)
 				{
-					kvp.Key.DialogResult = DialogResult.Cancel;
-					kvp.Key.Close();
+					if(kvp.Key.InvokeRequired)
+						kvp.Key.Invoke(new CloseFormDelegate(
+							GlobalWindowManager.CloseForm), kvp.Key);
+					else CloseForm(kvp.Key);
 
 					Application.DoEvents();
 				}
 			}
 		}
 
+		private delegate void CloseFormDelegate(Form f);
+
+		private static void CloseForm(Form f)
+		{
+			try
+			{
+				f.DialogResult = DialogResult.Cancel;
+				f.Close();
+			}
+			catch(Exception) { Debug.Assert(false); }
+		}
+
 		public static bool HasWindow(IntPtr hWindow)
 		{
 			foreach(KeyValuePair<Form, IGwmWindow> kvp in m_vWindows)
diff --git a/KeePass/UI/HotKeyControlEx.cs b/KeePass/UI/HotKeyControlEx.cs
index 4168b35..a5b73f7 100644
--- a/KeePass/UI/HotKeyControlEx.cs
+++ b/KeePass/UI/HotKeyControlEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/IGwmWindow.cs b/KeePass/UI/IGwmWindow.cs
index 64a59f5..923fe6b 100644
--- a/KeePass/UI/IGwmWindow.cs
+++ b/KeePass/UI/IGwmWindow.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ImageComboBoxEx.cs b/KeePass/UI/ImageComboBoxEx.cs
index f328297..0de30a5 100644
--- a/KeePass/UI/ImageComboBoxEx.cs
+++ b/KeePass/UI/ImageComboBoxEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/KeyboardControl.cs b/KeePass/UI/KeyboardControl.cs
index 848bf8d..43a66e5 100644
--- a/KeePass/UI/KeyboardControl.cs
+++ b/KeePass/UI/KeyboardControl.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ListSorter.cs b/KeePass/UI/ListSorter.cs
index a804a75..d2509d5 100644
--- a/KeePass/UI/ListSorter.cs
+++ b/KeePass/UI/ListSorter.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ListViewSortMenu.cs b/KeePass/UI/ListViewSortMenu.cs
index 90bda20..e87bc60 100644
--- a/KeePass/UI/ListViewSortMenu.cs
+++ b/KeePass/UI/ListViewSortMenu.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ListViewStateEx.cs b/KeePass/UI/ListViewStateEx.cs
index 62403e5..69579b0 100644
--- a/KeePass/UI/ListViewStateEx.cs
+++ b/KeePass/UI/ListViewStateEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/MruList.cs b/KeePass/UI/MruList.cs
index a56be90..f825abc 100644
--- a/KeePass/UI/MruList.cs
+++ b/KeePass/UI/MruList.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/NotifyIconEx.cs b/KeePass/UI/NotifyIconEx.cs
index 7178a7b..2e178b1 100644
--- a/KeePass/UI/NotifyIconEx.cs
+++ b/KeePass/UI/NotifyIconEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/OnDemandStatusDialog.cs b/KeePass/UI/OnDemandStatusDialog.cs
index 8bee59f..b3682eb 100644
--- a/KeePass/UI/OnDemandStatusDialog.cs
+++ b/KeePass/UI/OnDemandStatusDialog.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/OpenWithMenu.cs b/KeePass/UI/OpenWithMenu.cs
index 29e43f9..3cbb55a 100644
--- a/KeePass/UI/OpenWithMenu.cs
+++ b/KeePass/UI/OpenWithMenu.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@ namespace KeePass.UI
 		public string FilePath { get { return m_strPath; } }
 
 		private string m_strMenuText;
-		public string MenuText { get { return m_strMenuText; } }
+		// public string MenuText { get { return m_strMenuText; } }
 
 		private Image m_imgIcon;
 		public Image Image { get { return m_imgIcon; } }
diff --git a/KeePass/UI/PromptedTextBox.cs b/KeePass/UI/PromptedTextBox.cs
index f1f1f4b..9b953f0 100644
--- a/KeePass/UI/PromptedTextBox.cs
+++ b/KeePass/UI/PromptedTextBox.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ProtectedDialog.cs b/KeePass/UI/ProtectedDialog.cs
index 9069378..29d3c66 100644
--- a/KeePass/UI/ProtectedDialog.cs
+++ b/KeePass/UI/ProtectedDialog.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/PwInputControlGroup.cs b/KeePass/UI/PwInputControlGroup.cs
new file mode 100644
index 0000000..f1e6ad4
--- /dev/null
+++ b/KeePass/UI/PwInputControlGroup.cs
@@ -0,0 +1,331 @@
+/*
+  KeePass Password Safe - The Open-Source Password Manager
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Diagnostics;
+
+using KeePass.App;
+using KeePass.App.Configuration;
+using KeePass.Forms;
+using KeePass.Resources;
+
+using KeePassLib;
+using KeePassLib.Cryptography;
+using KeePassLib.Utility;
+
+namespace KeePass.UI
+{
+	public sealed class PwInputControlGroup
+	{
+		private TextBox m_tbPassword = null;
+		private CheckBox m_cbHide = null;
+		private Label m_lblRepeat = null;
+		private TextBox m_tbRepeat = null;
+		private Label m_lblQualityPrompt = null;
+		private QualityProgressBar m_pbQuality = null;
+		private Label m_lblQualityBits = null;
+		private Form m_fParent = null;
+
+		private SecureEdit m_secPassword = null;
+		private SecureEdit m_secRepeat = null;
+
+		private bool m_bInitializing = false;
+		private bool m_bPrgmCheck = false;
+
+		private bool m_bEnabled = true;
+		public bool Enabled
+		{
+			get { return m_bEnabled; }
+			set
+			{
+				if(value != m_bEnabled)
+				{
+					m_bEnabled = value;
+					UpdateUI();
+				}
+			}
+		}
+
+		public uint PasswordLength
+		{
+			get
+			{
+				if(m_secPassword == null) { Debug.Assert(false); return 0; }
+				return m_secPassword.TextLength;
+			}
+		}
+
+		private bool AutoRepeat
+		{
+			get
+			{
+				if(m_cbHide == null) { Debug.Assert(false); return false; }
+				return !m_cbHide.Checked;
+			}
+		}
+
+		public PwInputControlGroup()
+		{
+		}
+
+#if DEBUG
+		~PwInputControlGroup()
+		{
+			Debug.Assert(m_tbPassword == null); // Owner should call Release()
+			Debug.Assert(m_uBlockUIUpdate == 0);
+		}
+#endif
+
+		public void Attach(TextBox tbPassword, CheckBox cbHide, Label lblRepeat,
+			TextBox tbRepeat, Label lblQualityPrompt, QualityProgressBar pbQuality,
+			Label lblQualityBits, Form fParent, bool bInitialHide, bool bSecureDesktopMode)
+		{
+			if(tbPassword == null) throw new ArgumentNullException("tbPassword");
+			if(cbHide == null) throw new ArgumentNullException("cbHide");
+			if(lblRepeat == null) throw new ArgumentNullException("lblRepeat");
+			if(tbRepeat == null) throw new ArgumentNullException("tbRepeat");
+			if(lblQualityPrompt == null) throw new ArgumentNullException("lblQualityPrompt");
+			if(pbQuality == null) throw new ArgumentNullException("pbQuality");
+			if(lblQualityBits == null) throw new ArgumentNullException("lblQualityBits");
+			if(fParent == null) throw new ArgumentNullException("fParent");
+
+			Release();
+			m_bInitializing = true;
+
+			m_tbPassword = tbPassword;
+			m_cbHide = cbHide;
+			m_lblRepeat = lblRepeat;
+			m_tbRepeat = tbRepeat;
+			m_lblQualityPrompt = lblQualityPrompt;
+			m_pbQuality = pbQuality;
+			m_lblQualityBits = lblQualityBits;
+			m_fParent = fParent;
+
+			m_secPassword = new SecureEdit();
+			m_secPassword.SecureDesktopMode = bSecureDesktopMode;
+			m_secPassword.Attach(m_tbPassword, this.OnPasswordTextChanged, bInitialHide);
+
+			m_secRepeat = new SecureEdit();
+			m_secRepeat.SecureDesktopMode = bSecureDesktopMode;
+			m_secRepeat.Attach(m_tbRepeat, this.OnRepeatTextChanged, bInitialHide);
+
+			m_cbHide.Checked = bInitialHide;
+			m_cbHide.CheckedChanged += this.OnHideCheckedChanged;
+
+			Debug.Assert(m_pbQuality.Minimum == 0);
+			Debug.Assert(m_pbQuality.Maximum == 100);
+
+			m_bInitializing = false;
+			UpdateUI();
+		}
+
+		public void Release()
+		{
+			Debug.Assert(!m_bInitializing);
+			if(m_tbPassword == null) return;
+
+			m_secPassword.Detach();
+			m_secRepeat.Detach();
+
+			m_cbHide.CheckedChanged -= this.OnHideCheckedChanged;
+
+			m_tbPassword = null;
+			m_cbHide = null;
+			m_lblRepeat = null;
+			m_tbRepeat = null;
+			m_lblQualityPrompt = null;
+			m_pbQuality = null;
+			m_lblQualityBits = null;
+			m_fParent = null;
+
+			m_secPassword = null;
+			m_secRepeat = null;
+		}
+
+		private uint m_uBlockUIUpdate = 0;
+		private void UpdateUI()
+		{
+			if((m_uBlockUIUpdate > 0) || m_bInitializing) return;
+			++m_uBlockUIUpdate;
+
+			ulong uFlags = 0;
+			if(m_fParent is KeyCreationForm)
+				uFlags = Program.Config.UI.KeyCreationFlags;
+
+			byte[] pbUtf8 = m_secPassword.ToUtf8();
+
+			m_tbPassword.Enabled = m_bEnabled;
+			m_cbHide.Enabled = (m_bEnabled && ((uFlags &
+				(ulong)AceKeyUIFlags.DisableHidePassword) == 0));
+
+			if((uFlags & (ulong)AceKeyUIFlags.CheckHidePassword) != 0)
+			{
+				m_bPrgmCheck = true;
+				m_cbHide.Checked = true;
+				m_bPrgmCheck = false;
+			}
+			if((uFlags & (ulong)AceKeyUIFlags.UncheckHidePassword) != 0)
+			{
+				m_bPrgmCheck = true;
+				m_cbHide.Checked = false;
+				m_bPrgmCheck = false;
+			}
+
+			bool bAutoRepeat = this.AutoRepeat;
+			if(bAutoRepeat && (m_secRepeat.TextLength > 0))
+				m_secRepeat.SetPassword(new byte[0]);
+
+			byte[] pbRepeat = m_secRepeat.ToUtf8();
+			if(!MemUtil.ArraysEqual(pbUtf8, pbRepeat) && !bAutoRepeat)
+				m_tbRepeat.BackColor = AppDefs.ColorEditError;
+			else m_tbRepeat.ResetBackColor();
+
+			bool bRepeatEnable = (m_bEnabled && !bAutoRepeat);
+			m_lblRepeat.Enabled = bRepeatEnable;
+			m_tbRepeat.Enabled = bRepeatEnable;
+
+			m_lblQualityPrompt.Enabled = m_bEnabled;
+			m_pbQuality.Enabled = m_bEnabled;
+			m_lblQualityBits.Enabled = m_bEnabled;
+
+			uint uBits = QualityEstimation.EstimatePasswordBits(pbUtf8);
+			m_lblQualityBits.Text = uBits.ToString() + " " + KPRes.Bits;
+			int iPos = (int)((100 * uBits) / (256 / 2));
+			if(iPos < 0) iPos = 0; else if(iPos > 100) iPos = 100;
+			m_pbQuality.Value = iPos;
+
+			MemUtil.ZeroByteArray(pbUtf8);
+			MemUtil.ZeroByteArray(pbRepeat);
+			--m_uBlockUIUpdate;
+		}
+
+		private void OnPasswordTextChanged(object sender, EventArgs e)
+		{
+			UpdateUI();
+		}
+
+		private void OnRepeatTextChanged(object sender, EventArgs e)
+		{
+			UpdateUI();
+		}
+
+		private void OnHideCheckedChanged(object sender, EventArgs e)
+		{
+			if(m_bInitializing) return;
+
+			bool bHide = m_cbHide.Checked;
+			if(!bHide && !m_bPrgmCheck && !AppPolicy.Try(AppPolicyId.UnhidePasswords))
+			{
+				m_cbHide.Checked = true;
+				return;
+			}
+
+			m_secPassword.EnableProtection(bHide);
+			m_secRepeat.EnableProtection(bHide);
+
+			if(bHide && !m_bPrgmCheck)
+			{
+				++m_uBlockUIUpdate;
+				byte[] pb = GetPasswordUtf8();
+				m_secRepeat.SetPassword(pb);
+				MemUtil.ZeroByteArray(pb);
+				--m_uBlockUIUpdate;
+			}
+
+			UpdateUI();
+			if(!m_bPrgmCheck) UIUtil.SetFocus(m_tbPassword, m_fParent);
+		}
+
+		public void SetPassword(byte[] pbUtf8, bool bSetRepeatPw)
+		{
+			if(pbUtf8 == null) { Debug.Assert(false); return; }
+
+			++m_uBlockUIUpdate;
+			m_secPassword.SetPassword(pbUtf8);
+			if(bSetRepeatPw && !this.AutoRepeat)
+				m_secRepeat.SetPassword(pbUtf8);
+			--m_uBlockUIUpdate;
+
+			UpdateUI();
+		}
+
+		public void SetPasswords(string strPassword, string strRepeat)
+		{
+			byte[] pbP = ((strPassword != null) ? StrUtil.Utf8.GetBytes(
+				strPassword) : null);
+			byte[] pbR = ((strRepeat != null) ? StrUtil.Utf8.GetBytes(
+				strRepeat) : null);
+			SetPasswords(pbP, pbR);
+		}
+
+		public void SetPasswords(byte[] pbPasswordUtf8, byte[] pbRepeatUtf8)
+		{
+			++m_uBlockUIUpdate;
+			if(pbPasswordUtf8 != null)
+				m_secPassword.SetPassword(pbPasswordUtf8);
+			if((pbRepeatUtf8 != null) && !this.AutoRepeat)
+				m_secRepeat.SetPassword(pbRepeatUtf8);
+			--m_uBlockUIUpdate;
+
+			UpdateUI();
+		}
+
+		public string GetPassword()
+		{
+			return StrUtil.Utf8.GetString(m_secPassword.ToUtf8());
+		}
+
+		public byte[] GetPasswordUtf8()
+		{
+			return m_secPassword.ToUtf8();
+		}
+
+		public string GetRepeat()
+		{
+			if(this.AutoRepeat) return GetPassword();
+			return StrUtil.Utf8.GetString(m_secRepeat.ToUtf8());
+		}
+
+		public byte[] GetRepeatUtf8()
+		{
+			if(this.AutoRepeat) return GetPasswordUtf8();
+			return m_secRepeat.ToUtf8();
+		}
+
+		public bool ValidateData(bool bUIOnError)
+		{
+			if(this.AutoRepeat) return true;
+			if(m_secPassword.ContentsEqualTo(m_secRepeat)) return true;
+
+			if(bUIOnError)
+			{
+				if(!VistaTaskDialog.ShowMessageBox(KPRes.PasswordRepeatFailed,
+					KPRes.ValidationFailed, PwDefs.ShortProductName,
+					VtdIcon.Warning, m_fParent.Handle))
+					MessageService.ShowWarning(KPRes.PasswordRepeatFailed);
+			}
+
+			return false;
+		}
+	}
+}
diff --git a/KeePass/UI/QualityProgressBar.cs b/KeePass/UI/QualityProgressBar.cs
index a12ba06..7d98278 100644
--- a/KeePass/UI/QualityProgressBar.cs
+++ b/KeePass/UI/QualityProgressBar.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -103,6 +103,11 @@ namespace KeePass.UI
 
 			Color clrStart = Color.FromArgb(255, 128, 0);
 			Color clrEnd = Color.FromArgb(0, 255, 0);
+			if(!this.Enabled)
+			{
+				clrStart = UIUtil.ColorToGrayscale(SystemColors.ControlDark);
+				clrEnd = UIUtil.ColorToGrayscale(SystemColors.Control);
+			}
 
 			bool bRtl = (this.RightToLeft == RightToLeft.Yes);
 			if(bRtl)
diff --git a/KeePass/UI/RichTextBoxContextMenu.cs b/KeePass/UI/RichTextBoxContextMenu.cs
index 5bd24ed..41dd1d3 100644
--- a/KeePass/UI/RichTextBoxContextMenu.cs
+++ b/KeePass/UI/RichTextBoxContextMenu.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/RichTextBuilder.cs b/KeePass/UI/RichTextBuilder.cs
index f3f1a0e..64cd39b 100644
--- a/KeePass/UI/RichTextBuilder.cs
+++ b/KeePass/UI/RichTextBuilder.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/SecureEdit.cs b/KeePass/UI/SecureEdit.cs
index beeefa2..f299537 100644
--- a/KeePass/UI/SecureEdit.cs
+++ b/KeePass/UI/SecureEdit.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -331,7 +331,7 @@ namespace KeePass.UI
 		public void SetPassword(byte[] pbUtf8)
 		{
 			Debug.Assert(pbUtf8 != null);
-			if(pbUtf8 == null) throw new ArgumentNullException("pbUTF8");
+			if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8");
 
 			if(m_secString != null)
 			{
diff --git a/KeePass/UI/ShowWarningsLogger.cs b/KeePass/UI/ShowWarningsLogger.cs
index 2786b56..134abb7 100644
--- a/KeePass/UI/ShowWarningsLogger.cs
+++ b/KeePass/UI/ShowWarningsLogger.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/StatusBarLogger.cs b/KeePass/UI/StatusBarLogger.cs
index 5333f28..0ff1db2 100644
--- a/KeePass/UI/StatusBarLogger.cs
+++ b/KeePass/UI/StatusBarLogger.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/StatusUtil.cs b/KeePass/UI/StatusUtil.cs
index ca3e8da..4dbe857 100644
--- a/KeePass/UI/StatusUtil.cs
+++ b/KeePass/UI/StatusUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/TabControlEx.cs b/KeePass/UI/TabControlEx.cs
index 70612c4..8e435b0 100644
--- a/KeePass/UI/TabControlEx.cs
+++ b/KeePass/UI/TabControlEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/TaskbarList.cs b/KeePass/UI/TaskbarList.cs
index b42d3c9..f7ad1da 100644
--- a/KeePass/UI/TaskbarList.cs
+++ b/KeePass/UI/TaskbarList.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/ThemeToolStripRenderer.cs b/KeePass/UI/ThemeToolStripRenderer.cs
index 6a83bc6..adceb70 100644
--- a/KeePass/UI/ThemeToolStripRenderer.cs
+++ b/KeePass/UI/ThemeToolStripRenderer.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/UISystemFonts.cs b/KeePass/UI/UISystemFonts.cs
index 4744b9b..09c9d49 100644
--- a/KeePass/UI/UISystemFonts.cs
+++ b/KeePass/UI/UISystemFonts.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/UIUtil.cs b/KeePass/UI/UIUtil.cs
index 35120ab..877b075 100644
--- a/KeePass/UI/UIUtil.cs
+++ b/KeePass/UI/UIUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -541,7 +541,7 @@ namespace KeePass.UI
 		/// Fill a <c>ListView</c> with password entries.
 		/// </summary>
 		public static void CreateEntryList(ListView lv, List<AutoTypeCtx> lCtxs,
-			ImageList ilIcons)
+			AceAutoTypeCtxFlags f, ImageList ilIcons)
 		{
 			if(lv == null) throw new ArgumentNullException("lv");
 			if(lCtxs == null) throw new ArgumentNullException("lCtxs");
@@ -553,10 +553,20 @@ namespace KeePass.UI
 			lv.ShowGroups = true;
 			lv.SmallImageList = ilIcons;
 
+			Debug.Assert((f & AceAutoTypeCtxFlags.ColTitle) != AceAutoTypeCtxFlags.None);
+			f |= AceAutoTypeCtxFlags.ColTitle; // Enforce title
+
 			lv.Columns.Add(KPRes.Title);
-			lv.Columns.Add(KPRes.UserName);
-			lv.Columns.Add(KPRes.Url);
-			lv.Columns.Add(KPRes.Sequence);
+			if((f & AceAutoTypeCtxFlags.ColUserName) != AceAutoTypeCtxFlags.None)
+				lv.Columns.Add(KPRes.UserName);
+			if((f & AceAutoTypeCtxFlags.ColPassword) != AceAutoTypeCtxFlags.None)
+				lv.Columns.Add(KPRes.Password);
+			if((f & AceAutoTypeCtxFlags.ColUrl) != AceAutoTypeCtxFlags.None)
+				lv.Columns.Add(KPRes.Url);
+			if((f & AceAutoTypeCtxFlags.ColNotes) != AceAutoTypeCtxFlags.None)
+				lv.Columns.Add(KPRes.Notes);
+			if((f & AceAutoTypeCtxFlags.ColSequence) != AceAutoTypeCtxFlags.None)
+				lv.Columns.Add(KPRes.Sequence);
 
 			ListViewGroup lvg = new ListViewGroup(Guid.NewGuid().ToString());
 			DateTime dtNow = DateTime.Now;
@@ -602,11 +612,21 @@ namespace KeePass.UI
 					else { Debug.Assert(false); lvi.ImageIndex = (int)pe.IconId; }
 				}
 
-				lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe(
-					PwDefs.UserNameField), sprCtx));
-				lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe(
-					PwDefs.UrlField), sprCtx));
-				lvi.SubItems.Add(ctx.Sequence);
+				if((f & AceAutoTypeCtxFlags.ColUserName) != AceAutoTypeCtxFlags.None)
+					lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe(
+						PwDefs.UserNameField), sprCtx));
+				if((f & AceAutoTypeCtxFlags.ColPassword) != AceAutoTypeCtxFlags.None)
+					lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe(
+						PwDefs.PasswordField), sprCtx));
+				if((f & AceAutoTypeCtxFlags.ColUrl) != AceAutoTypeCtxFlags.None)
+					lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe(
+						PwDefs.UrlField), sprCtx));
+				if((f & AceAutoTypeCtxFlags.ColNotes) != AceAutoTypeCtxFlags.None)
+					lvi.SubItems.Add(StrUtil.MultiToSingleLine(SprEngine.Compile(
+						pe.Strings.ReadSafe(PwDefs.NotesField), sprCtx)));
+				if((f & AceAutoTypeCtxFlags.ColSequence) != AceAutoTypeCtxFlags.None)
+					lvi.SubItems.Add(ctx.Sequence);
+				Debug.Assert(lvi.SubItems.Count == lv.Columns.Count);
 
 				if(!pe.ForegroundColor.IsEmpty)
 					lvi.ForeColor = pe.ForegroundColor;
@@ -627,14 +647,13 @@ namespace KeePass.UI
 				}
 			}
 
-			int nColWidth = (lv.ClientRectangle.Width - GetVScrollBarWidth()) /
-				lv.Columns.Count;
+			lv.EndUpdate();
+
+			int nColWidth = lv.ClientRectangle.Width / lv.Columns.Count;
 			foreach(ColumnHeader ch in lv.Columns)
 			{
 				ch.Width = nColWidth;
 			}
-
-			lv.EndUpdate();
 		}
 
 		public static int GetVScrollBarWidth()
@@ -836,15 +855,46 @@ namespace KeePass.UI
 		{
 			if((tn == null) || (pg == null)) { Debug.Assert(false); return; }
 
-			if(pg.Notes.Length > 0)
-			{
-				string str = pg.Name + MessageService.NewParagraph + pg.Notes;
+			string str = GetPwGroupToolTip(pg);
+			if(str == null) return;
+
+			try { tn.ToolTipText = str; }
+			catch(Exception) { Debug.Assert(false); }
+		}
+
+		public static string GetPwGroupToolTip(PwGroup pg)
+		{
+			if(pg == null) { Debug.Assert(false); return null; }
+
+			StringBuilder sb = new StringBuilder();
+			sb.Append(pg.Name);
 
-				try { tn.ToolTipText = str; }
-				catch(Exception) { Debug.Assert(false); }
+			string strNotes = pg.Notes.Trim();
+			if(strNotes.Length > 0)
+			{
+				sb.Append(MessageService.NewParagraph);
+				sb.Append(strNotes);
 			}
+			else return null;
+
+			// uint uSubGroups, uEntries;
+			// pg.GetCounts(true, out uSubGroups, out uEntries);
+			// sb.Append(MessageService.NewParagraph);
+			// sb.Append(KPRes.Subgroups); sb.Append(": "); sb.Append(uSubGroups);
+			// sb.Append(MessageService.NewLine);
+			// sb.Append(KPRes.Entries); sb.Append(": "); sb.Append(uEntries);
+
+			return sb.ToString();
 		}
 
+		// public static string GetPwGroupToolTipTN(TreeNode tn)
+		// {
+		//	if(tn == null) { Debug.Assert(false); return null; }
+		//	PwGroup pg = (tn.Tag as PwGroup);
+		//	if(pg == null) { Debug.Assert(false); return null; }
+		//	return GetPwGroupToolTip(pg);
+		// }
+
 		public static Color LightenColor(Color clrBase, double dblFactor)
 		{
 			if((dblFactor <= 0.0) || (dblFactor > 1.0)) return clrBase;
@@ -961,7 +1011,6 @@ namespace KeePass.UI
 			if(pb == null) throw new ArgumentNullException("pb");
 
 			MemoryStream ms = new MemoryStream(pb, false);
-
 			try { return Image.FromStream(ms); }
 			catch(Exception)
 			{
@@ -970,14 +1019,15 @@ namespace KeePass.UI
 
 				throw;
 			}
+			finally { ms.Close(); }
 		}
 
 		private static Image TryLoadIco(byte[] pb)
 		{
 			MemoryStream ms = new MemoryStream(pb, false);
-
 			try { return (new Icon(ms)).ToBitmap(); }
 			catch(Exception) { }
+			finally { ms.Close(); }
 
 			return null;
 		}
@@ -1006,12 +1056,32 @@ namespace KeePass.UI
 		public static void ConfigureTbButton(ToolStripItem tb, string strText,
 			string strTooltip)
 		{
+			ConfigureTbButton(tb, strText, strTooltip, null);
+		}
+
+		private static char[] m_vTbTrim = null;
+		public static void ConfigureTbButton(ToolStripItem tb, string strText,
+			string strTooltip, ToolStripMenuItem tsmiEquiv)
+		{
 			if(strText != null) tb.Text = strText;
 
-			if(strTooltip != null)
-				tb.ToolTipText = StrUtil.RemoveAccelerator(strTooltip);
-			else if(strText != null)
-				tb.ToolTipText = StrUtil.RemoveAccelerator(strText);
+			if(m_vTbTrim == null)
+				m_vTbTrim = new char[] { ' ', '\t', '\r', '\n', '.', '\u2026' };
+
+			string strTip = (strTooltip ?? strText);
+			if(strTip == null) return;
+
+			strTip = StrUtil.RemoveAccelerator(strTip);
+			strTip = strTip.Trim(m_vTbTrim);
+
+			if((tsmiEquiv != null) && (strTip.Length > 0))
+			{
+				string strShortcut = tsmiEquiv.ShortcutKeyDisplayString;
+				if(!string.IsNullOrEmpty(strShortcut))
+					strTip += " (" + strShortcut + ")";
+			}
+
+			tb.ToolTipText = strTip;
 		}
 
 		public static void CreateGroupList(PwGroup pgContainer, ComboBox cmb,
@@ -1919,5 +1989,34 @@ namespace KeePass.UI
 			}
 			catch(Exception) { Debug.Assert(KeePassLib.Native.NativeLib.IsUnix()); }
 		}
+
+		private static KeysConverter m_convKeys = null;
+		public static string GetKeysName(Keys k)
+		{
+			if(m_convKeys == null) m_convKeys = new KeysConverter();
+			return m_convKeys.ConvertToString(k);
+		}
+
+		/// <summary>
+		/// Assign shortcut keys to a menu item. This method uses
+		/// custom-translated display strings.
+		/// </summary>
+		public static void AssignShortcut(ToolStripMenuItem tsmi, Keys k)
+		{
+			if(tsmi == null) { Debug.Assert(false); return; }
+
+			tsmi.ShortcutKeys = k;
+
+			string str = string.Empty;
+			if((k & Keys.Control) != Keys.None)
+				str += KPRes.KeyboardKeyCtrl + "+";
+			if((k & Keys.Alt) != Keys.None)
+				str += KPRes.KeyboardKeyAlt + "+";
+			if((k & Keys.Shift) != Keys.None)
+				str += KPRes.KeyboardKeyShift + "+";
+			str += GetKeysName(k & Keys.KeyCode);
+
+			tsmi.ShortcutKeyDisplayString = str;
+		}
 	}
 }
diff --git a/KeePass/UI/UserActivityNotifyFilter.cs b/KeePass/UI/UserActivityNotifyFilter.cs
index 5719b08..5f337cd 100644
--- a/KeePass/UI/UserActivityNotifyFilter.cs
+++ b/KeePass/UI/UserActivityNotifyFilter.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/UI/VistaTaskDialog.cs b/KeePass/UI/VistaTaskDialog.cs
index ff48fbe..959f22f 100644
--- a/KeePass/UI/VistaTaskDialog.cs
+++ b/KeePass/UI/VistaTaskDialog.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -186,7 +186,8 @@ namespace KeePass.UI
 
 	public sealed class VistaTaskDialog
 	{
-		private const int VtdConfigSize = 96;
+		private const int VtdConfigSize32 = 96;
+		private const int VtdConfigSize64 = 160;
 
 		private VtdConfig m_cfg = new VtdConfig(true);
 		private int m_iResult = (int)DialogResult.Cancel;
@@ -222,6 +223,12 @@ namespace KeePass.UI
 			}
 		}
 
+		public string FooterText
+		{
+			get { return m_cfg.pszFooter; }
+			set { m_cfg.pszFooter = value; }
+		}
+
 		public string VerificationText
 		{
 			get { return m_cfg.pszVerificationText; }
@@ -275,6 +282,12 @@ namespace KeePass.UI
 			m_cfg.hMainIcon = hIcon;
 		}
 
+		public void SetFooterIcon(VtdIcon vtdIcon)
+		{
+			m_cfg.dwFlags &= ~VtdFlags.UseHIconFooter;
+			m_cfg.hFooterIcon = new IntPtr((int)vtdIcon);
+		}
+
 		private void ButtonsToPtr()
 		{
 			if(m_vButtons.Count == 0) { m_cfg.pButtons = IntPtr.Zero; return; }
@@ -317,7 +330,10 @@ namespace KeePass.UI
 		private bool InternalShowDialog()
 		{
 			if(IntPtr.Size == 4)
-				{ Debug.Assert(Marshal.SizeOf(typeof(VtdConfig)) == VtdConfigSize); }
+				{ Debug.Assert(Marshal.SizeOf(typeof(VtdConfig)) == VtdConfigSize32); }
+			else if(IntPtr.Size == 8)
+				{ Debug.Assert(Marshal.SizeOf(typeof(VtdConfig)) == VtdConfigSize64); }
+			else { Debug.Assert(false); }
 
 			m_cfg.cbSize = (uint)Marshal.SizeOf(typeof(VtdConfig));
 
diff --git a/KeePass/Util/AppLocator.cs b/KeePass/Util/AppLocator.cs
index 62cf203..422bb15 100644
--- a/KeePass/Util/AppLocator.cs
+++ b/KeePass/Util/AppLocator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/AutoType.cs b/KeePass/Util/AutoType.cs
index 171fe03..186c3d7 100644
--- a/KeePass/Util/AutoType.cs
+++ b/KeePass/Util/AutoType.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -216,6 +216,9 @@ namespace KeePass.Util
 
 			if(!pwe.GetAutoTypeEnabled()) return l;
 
+			SprContext sprCtx = new SprContext(pwe, pdContext,
+				SprCompileFlags.NonActive);
+
 			// Specifically defined sequences must match before the title,
 			// in order to allow selecting the first item as default one
 			foreach(AutoTypeAssociation a in pwe.AutoType.Associations)
@@ -223,11 +226,7 @@ namespace KeePass.Util
 				string strWndSpec = a.WindowName;
 				if(strWndSpec == null) { Debug.Assert(false); continue; }
 
-				strWndSpec = strWndSpec.Trim();
-
-				if(strWndSpec.Length > 0)
-					strWndSpec = SprEngine.Compile(strWndSpec, new SprContext(
-						pwe, pdContext, SprCompileFlags.All));
+				strWndSpec = SprEngine.Compile(strWndSpec.Trim(), sprCtx);
 
 				if(MatchWindows(strWndSpec, strWindow))
 				{
@@ -240,20 +239,38 @@ namespace KeePass.Util
 
 			if(Program.Config.Integration.AutoTypeMatchByTitle)
 			{
-				string strTitle = pwe.Strings.ReadSafe(PwDefs.TitleField);
-				strTitle = strTitle.Trim();
-
+				string strTitle = SprEngine.Compile(pwe.Strings.ReadSafe(
+					PwDefs.TitleField).Trim(), sprCtx);
 				if((strTitle.Length > 0) && (strWindow.IndexOf(strTitle,
 					StrUtil.CaseIgnoreCmp) >= 0))
 					AddSequence(l, pwe.GetAutoTypeSequence());
 			}
 
+			string strCmpUrl = null; // To cache compiled URL
 			if(Program.Config.Integration.AutoTypeMatchByUrlInTitle)
 			{
-				string strUrl = pwe.Strings.ReadSafe(PwDefs.UrlField);
-				strUrl = strUrl.Trim();
+				strCmpUrl = SprEngine.Compile(pwe.Strings.ReadSafe(
+					PwDefs.UrlField).Trim(), sprCtx);
+				if((strCmpUrl.Length > 0) && (strWindow.IndexOf(strCmpUrl,
+					StrUtil.CaseIgnoreCmp) >= 0))
+					AddSequence(l, pwe.GetAutoTypeSequence());
+			}
+
+			if(Program.Config.Integration.AutoTypeMatchByUrlHostInTitle)
+			{
+				if(strCmpUrl == null)
+					strCmpUrl = SprEngine.Compile(pwe.Strings.ReadSafe(
+						PwDefs.UrlField).Trim(), sprCtx);
+
+				string strCleanUrl = StrUtil.RemovePlaceholders(strCmpUrl);
+				string strHost = UrlUtil.GetHost(strCleanUrl);
+
+				if(strHost.StartsWith("www.", StrUtil.CaseIgnoreCmp) &&
+					(strCleanUrl.StartsWith("http:", StrUtil.CaseIgnoreCmp) ||
+					strCleanUrl.StartsWith("https:", StrUtil.CaseIgnoreCmp)))
+					strHost = strHost.Substring(4);
 
-				if((strUrl.Length > 0) && (strWindow.IndexOf(strUrl,
+				if((strHost.Length > 0) && (strWindow.IndexOf(strHost,
 					StrUtil.CaseIgnoreCmp) >= 0))
 					AddSequence(l, pwe.GetAutoTypeSequence());
 			}
diff --git a/KeePass/Util/AutoTypeCtx.cs b/KeePass/Util/AutoTypeCtx.cs
index eda8b21..a193d02 100644
--- a/KeePass/Util/AutoTypeCtx.cs
+++ b/KeePass/Util/AutoTypeCtx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/BinaryDataClassifier.cs b/KeePass/Util/BinaryDataClassifier.cs
index 01db2d9..e38337d 100644
--- a/KeePass/Util/BinaryDataClassifier.cs
+++ b/KeePass/Util/BinaryDataClassifier.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -105,11 +105,10 @@ namespace KeePass.Util
 			try
 			{
 				Image.FromStream(ms);
-
-				ms.Close();
 				return BinaryDataClass.Image;
 			}
-			catch(Exception) { ms.Close(); }
+			catch(Exception) { }
+			finally { ms.Close(); }
 
 			return BinaryDataClass.Unknown;
 		}
diff --git a/KeePass/Util/CancellableOperationEventArgs.cs b/KeePass/Util/CancellableOperationEventArgs.cs
index 1a8f3cd..4380b2b 100644
--- a/KeePass/Util/CancellableOperationEventArgs.cs
+++ b/KeePass/Util/CancellableOperationEventArgs.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/ClipboardContents.cs b/KeePass/Util/ClipboardContents.cs
index 506433e..d58d143 100644
--- a/KeePass/Util/ClipboardContents.cs
+++ b/KeePass/Util/ClipboardContents.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/ClipboardEventChainBlocker.cs b/KeePass/Util/ClipboardEventChainBlocker.cs
index 2c297e8..fbc6baf 100644
--- a/KeePass/Util/ClipboardEventChainBlocker.cs
+++ b/KeePass/Util/ClipboardEventChainBlocker.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/ClipboardUtil.Windows.cs b/KeePass/Util/ClipboardUtil.Windows.cs
index b14ce68..6771f85 100644
--- a/KeePass/Util/ClipboardUtil.Windows.cs
+++ b/KeePass/Util/ClipboardUtil.Windows.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/ClipboardUtil.cs b/KeePass/Util/ClipboardUtil.cs
index fb8ba40..3050a14 100644
--- a/KeePass/Util/ClipboardUtil.cs
+++ b/KeePass/Util/ClipboardUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/CommandLineArgs.cs b/KeePass/Util/CommandLineArgs.cs
index d629867..91ba956 100644
--- a/KeePass/Util/CommandLineArgs.cs
+++ b/KeePass/Util/CommandLineArgs.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -148,7 +148,10 @@ namespace KeePass.Util
 			XmlSerializer xml = new XmlSerializer(typeof(string[]));
 			xml.Serialize(ms, args);
 
-			return Convert.ToBase64String(ms.ToArray(), Base64FormattingOptions.None);
+			string strSerialized = Convert.ToBase64String(ms.ToArray(),
+				Base64FormattingOptions.None);
+			ms.Close();
+			return strSerialized;
 		}
 
 		public static string[] SafeDeserialize(string str)
@@ -161,6 +164,7 @@ namespace KeePass.Util
 
 			try { return (string[])xml.Deserialize(ms); }
 			catch(Exception) { Debug.Assert(false); }
+			finally { ms.Close(); }
 
 			return null;
 		}
diff --git a/KeePass/Util/EntryMenu.cs b/KeePass/Util/EntryMenu.cs
index 1b9c808..cc324b8 100644
--- a/KeePass/Util/EntryMenu.cs
+++ b/KeePass/Util/EntryMenu.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/EntryTemplates.cs b/KeePass/Util/EntryTemplates.cs
index 748489c..1c03fbd 100644
--- a/KeePass/Util/EntryTemplates.cs
+++ b/KeePass/Util/EntryTemplates.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/EntryUtil.cs b/KeePass/Util/EntryUtil.cs
index 0535138..5351775 100644
--- a/KeePass/Util/EntryUtil.cs
+++ b/KeePass/Util/EntryUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -92,11 +92,13 @@ namespace KeePass.Util
 						else continue; // DialogResult.No
 					}
 
-					try { File.WriteAllBytes(strFile, kvp.Value.ReadData()); }
+					byte[] pbData = kvp.Value.ReadData();
+					try { File.WriteAllBytes(strFile, pbData); }
 					catch(Exception exWrite)
 					{
 						MessageService.ShowWarning(strFile, exWrite);
 					}
+					MemUtil.ZeroByteArray(pbData);
 				}
 				if(bCancel) break;
 			}
@@ -157,20 +159,16 @@ namespace KeePass.Util
 			// Adjust protection settings and add entries
 			foreach(PwEntry pe in vEntries)
 			{
-				ProtectedString ps = pe.Strings.Get(PwDefs.TitleField);
-				if(ps != null) ps.EnableProtection(pwDatabase.MemoryProtection.ProtectTitle);
-
-				ps = pe.Strings.Get(PwDefs.UserNameField);
-				if(ps != null) ps.EnableProtection(pwDatabase.MemoryProtection.ProtectUserName);
-
-				ps = pe.Strings.Get(PwDefs.PasswordField);
-				if(ps != null) ps.EnableProtection(pwDatabase.MemoryProtection.ProtectPassword);
-
-				ps = pe.Strings.Get(PwDefs.UrlField);
-				if(ps != null) ps.EnableProtection(pwDatabase.MemoryProtection.ProtectUrl);
-
-				ps = pe.Strings.Get(PwDefs.NotesField);
-				if(ps != null) ps.EnableProtection(pwDatabase.MemoryProtection.ProtectNotes);
+				pe.Strings.EnableProtection(PwDefs.TitleField,
+					pwDatabase.MemoryProtection.ProtectTitle);
+				pe.Strings.EnableProtection(PwDefs.UserNameField,
+					pwDatabase.MemoryProtection.ProtectUserName);
+				pe.Strings.EnableProtection(PwDefs.PasswordField,
+					pwDatabase.MemoryProtection.ProtectPassword);
+				pe.Strings.EnableProtection(PwDefs.UrlField,
+					pwDatabase.MemoryProtection.ProtectUrl);
+				pe.Strings.EnableProtection(PwDefs.NotesField,
+					pwDatabase.MemoryProtection.ProtectNotes);
 
 				pgStorage.AddEntry(pe, true, true);
 			}
@@ -205,11 +203,11 @@ namespace KeePass.Util
 			const string strNewPwPlh = @"{NEWPASSWORD}";
 			if(str.IndexOf(strNewPwPlh, StrUtil.CaseIgnoreCmp) >= 0)
 			{
-				ProtectedString psAutoGen = new ProtectedString(
-					pd.MemoryProtection.ProtectPassword);
-				PwgError e = PwGenerator.Generate(psAutoGen,
+				ProtectedString psAutoGen;
+				PwgError e = PwGenerator.Generate(out psAutoGen,
 					Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile,
 					null, Program.PwGeneratorPool);
+				psAutoGen = psAutoGen.WithProtection(pd.MemoryProtection.ProtectPassword);
 
 				if(e == PwgError.Success)
 				{
diff --git a/KeePass/Util/GlobalMutexPool.cs b/KeePass/Util/GlobalMutexPool.cs
index bf27bb3..43964a8 100644
--- a/KeePass/Util/GlobalMutexPool.cs
+++ b/KeePass/Util/GlobalMutexPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/HotKeyManager.cs b/KeePass/Util/HotKeyManager.cs
index efeaa8f..36ee8c7 100644
--- a/KeePass/Util/HotKeyManager.cs
+++ b/KeePass/Util/HotKeyManager.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/IniFile.cs b/KeePass/Util/IniFile.cs
index fb31a0b..be78c6a 100644
--- a/KeePass/Util/IniFile.cs
+++ b/KeePass/Util/IniFile.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/IpcBroadcast.Fsw.cs b/KeePass/Util/IpcBroadcast.Fsw.cs
index 4c0e45c..6aed17b 100644
--- a/KeePass/Util/IpcBroadcast.Fsw.cs
+++ b/KeePass/Util/IpcBroadcast.Fsw.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/IpcBroadcast.cs b/KeePass/Util/IpcBroadcast.cs
index 988d319..198213a 100644
--- a/KeePass/Util/IpcBroadcast.cs
+++ b/KeePass/Util/IpcBroadcast.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/IpcUtilEx.cs b/KeePass/Util/IpcUtilEx.cs
index b0dd137..366b6a8 100644
--- a/KeePass/Util/IpcUtilEx.cs
+++ b/KeePass/Util/IpcUtilEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/KeyUtil.cs b/KeePass/Util/KeyUtil.cs
index b986638..a3f51e5 100644
--- a/KeePass/Util/KeyUtil.cs
+++ b/KeePass/Util/KeyUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/NetUtil.cs b/KeePass/Util/NetUtil.cs
index 8555ae2..dfe035e 100644
--- a/KeePass/Util/NetUtil.cs
+++ b/KeePass/Util/NetUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ namespace KeePass.Util
 {
 	public static class NetUtil
 	{
-		public static string GZipUtf8ResultToString(DownloadDataCompletedEventArgs e)
+		/* public static string GZipUtf8ResultToString(DownloadDataCompletedEventArgs e)
 		{
 			if(e.Cancelled || (e.Error != null) || (e.Result == null))
 				return null;
@@ -57,7 +57,7 @@ namespace KeePass.Util
 			msZipped.Close();
 
 			return StrUtil.Utf8.GetString(msUTF8.ToArray());
-		}
+		} */
 
 		public static string WebPageLogin(Uri url, string strPostData,
 			out List<KeyValuePair<string, string>> vCookies)
diff --git a/KeePass/Util/PwGeneratorUtil.cs b/KeePass/Util/PwGeneratorUtil.cs
index f7c5ed0..bf7fc20 100644
--- a/KeePass/Util/PwGeneratorUtil.cs
+++ b/KeePass/Util/PwGeneratorUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -32,13 +32,30 @@ namespace KeePass.Util
 {
 	public static class PwGeneratorUtil
 	{
-		/// <summary>
-		/// Add standard profiles if none are available. If there is
-		/// at least one profile available, this function does nothing.
-		/// </summary>
-		public static void AddStandardProfilesIfNoneAvailable()
+		private static string m_strBuiltInSuffix = null;
+		internal static string BuiltInSuffix
 		{
-			if(Program.Config.PasswordGenerator.UserProfiles.Count > 0) return;
+			get
+			{
+				if(m_strBuiltInSuffix == null)
+					m_strBuiltInSuffix = " (" + KPRes.BuiltIn + ")";
+				return m_strBuiltInSuffix;
+			}
+		}
+
+		private static List<PwProfile> m_lBuiltIn = null;
+		public static List<PwProfile> BuiltInProfiles
+		{
+			get
+			{
+				if(m_lBuiltIn == null) AllocStandardProfiles();
+				return m_lBuiltIn;
+			}
+		}
+
+		private static void AllocStandardProfiles()
+		{
+			m_lBuiltIn = new List<PwProfile>();
 
 			AddStdPattern(KPRes.RandomMacAddress, @"HH\-HH\-HH\-HH\-HH\-HH");
 
@@ -52,12 +69,60 @@ namespace KeePass.Util
 		{
 			PwProfile p = new PwProfile();
 
-			p.Name = strName;
+			p.Name = strName + PwGeneratorUtil.BuiltInSuffix;
 			p.CollectUserEntropy = false;
 			p.GeneratorType = PasswordGeneratorType.Pattern;
 			p.Pattern = strPattern;
 
-			Program.Config.PasswordGenerator.UserProfiles.Add(p);
+			m_lBuiltIn.Add(p);
+		}
+
+		/// <summary>
+		/// Get a list of all password generator profiles (built-in
+		/// and user-defined ones).
+		/// </summary>
+		public static List<PwProfile> GetAllProfiles(bool bSort)
+		{
+			List<PwProfile> lUser = Program.Config.PasswordGenerator.UserProfiles;
+
+			// Sort it in the configuration file
+			if(bSort) lUser.Sort(PwGeneratorUtil.CompareProfilesByName);
+
+			// Remove old built-in profiles by KeePass <= 2.17
+			for(int i = lUser.Count - 1; i >= 0; --i)
+			{
+				if(IsBuiltInProfile(lUser[i].Name)) lUser.RemoveAt(i);
+			}
+
+			List<PwProfile> l = new List<PwProfile>();
+			l.AddRange(PwGeneratorUtil.BuiltInProfiles);
+			l.AddRange(lUser);
+			if(bSort) l.Sort(PwGeneratorUtil.CompareProfilesByName);
+			return l;
+		}
+
+		public static bool IsBuiltInProfile(string strName)
+		{
+			if(strName == null) { Debug.Assert(false); return false; }
+
+			string strWithSuffix = strName + PwGeneratorUtil.BuiltInSuffix;
+			foreach(PwProfile p in PwGeneratorUtil.BuiltInProfiles)
+			{
+				if(p.Name.Equals(strName, StrUtil.CaseIgnoreCmp) ||
+					p.Name.Equals(strWithSuffix, StrUtil.CaseIgnoreCmp))
+					return true;
+			}
+
+			return false;
+		}
+
+		public static int CompareProfilesByName(PwProfile a, PwProfile b)
+		{
+			if(a == b) return 0;
+			if(a == null) { Debug.Assert(false); return -1; }
+			if(b == null) { Debug.Assert(false); return 1; }
+
+			return StrUtil.CompareNaturally(a.Name, b.Name);
 		}
 	}
 }
diff --git a/KeePass/Util/SearchUtil.cs b/KeePass/Util/SearchUtil.cs
index 14aec9a..7bd337a 100644
--- a/KeePass/Util/SearchUtil.cs
+++ b/KeePass/Util/SearchUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/SendInputEx.Unix.cs b/KeePass/Util/SendInputEx.Unix.cs
index e30599f..4a72813 100644
--- a/KeePass/Util/SendInputEx.Unix.cs
+++ b/KeePass/Util/SendInputEx.Unix.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/SendInputEx.Windows.cs b/KeePass/Util/SendInputEx.Windows.cs
index ce47171..1217bac 100644
--- a/KeePass/Util/SendInputEx.Windows.cs
+++ b/KeePass/Util/SendInputEx.Windows.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -39,6 +39,8 @@ namespace KeePass.Util
 
 			si.CurrentKeyboardLayout = hklSelf;
 
+			if(!Program.Config.Integration.AutoTypeAdjustKeyboardLayout) return;
+
 			if(hklSelf != hklTarget)
 			{
 				si.OriginalKeyboardLayout = NativeMethods.ActivateKeyboardLayout(
@@ -307,7 +309,7 @@ namespace KeePass.Util
 			// Workaround for ^/& .NET SendKeys bug:
 			// https://connect.microsoft.com/VisualStudio/feedback/details/93922/sendkeys-send-sends-wrong-character
 
-			string[] vSpecial = new string[]{ @"{^}", @"{%}", @"´", @"`" };
+			string[] vSpecial = new string[]{ @"{^}", @"{%}", @"´", @"`", @"@" };
 			List<string> vSend = StrUtil.SplitWithSep(strSequence, vSpecial, true);
 
 			foreach(string strSend in vSend)
@@ -318,6 +320,7 @@ namespace KeePass.Util
 				else if(strSend.Equals(@"{%}")) SendCharNative('%');
 				else if(strSend.Equals(@"´")) SendCharNative('´');
 				else if(strSend.Equals(@"`")) SendCharNative('`');
+				else if(strSend.Equals(@"@")) SendCharNative('@');
 				else SendKeys.SendWait(strSend);
 			}
 		}
diff --git a/KeePass/Util/SendInputEx.cs b/KeePass/Util/SendInputEx.cs
index 593e93f..279072d 100644
--- a/KeePass/Util/SendInputEx.cs
+++ b/KeePass/Util/SendInputEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/SessionLockNotifier.cs b/KeePass/Util/SessionLockNotifier.cs
index 64a2a69..276b3ef 100644
--- a/KeePass/Util/SessionLockNotifier.cs
+++ b/KeePass/Util/SessionLockNotifier.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/ShellUtil.cs b/KeePass/Util/ShellUtil.cs
index b63ee1e..6f6674a 100644
--- a/KeePass/Util/ShellUtil.cs
+++ b/KeePass/Util/ShellUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/Spr/SprContext.cs b/KeePass/Util/Spr/SprContext.cs
index bbffa82..41b8c54 100644
--- a/KeePass/Util/Spr/SprContext.cs
+++ b/KeePass/Util/Spr/SprContext.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/Spr/SprEncoding.cs b/KeePass/Util/Spr/SprEncoding.cs
index 9613cfe..9cf1b9c 100644
--- a/KeePass/Util/Spr/SprEncoding.cs
+++ b/KeePass/Util/Spr/SprEncoding.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/Spr/SprEngine.PickChars.cs b/KeePass/Util/Spr/SprEngine.PickChars.cs
index ce2f93c..29a8b79 100644
--- a/KeePass/Util/Spr/SprEngine.PickChars.cs
+++ b/KeePass/Util/Spr/SprEngine.PickChars.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/Spr/SprEngine.cs b/KeePass/Util/Spr/SprEngine.cs
index 03320c1..561ce18 100644
--- a/KeePass/Util/Spr/SprEngine.cs
+++ b/KeePass/Util/Spr/SprEngine.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -231,8 +231,7 @@ namespace KeePass.Util.Spr
 
 			if(ctx.EncodeAsAutoTypeSequence)
 			{
-				str = str.Replace("\r\n", "\n");
-				str = str.Replace("\r", "\n");
+				str = StrUtil.NormalizeNewLines(str, false);
 				str = str.Replace("\n", @"{ENTER}");
 			}
 
@@ -327,7 +326,7 @@ namespace KeePass.Util.Spr
 
 				if(!ctx.ForcePlainTextPasswords && strKey.Equals(@"{" +
 					PwDefs.PasswordField + @"}", StrUtil.CaseIgnoreCmp) &&
-					Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password, true))
+					Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password))
 				{
 					str = SprEngine.FillIfExists(str, strKey, new ProtectedString(
 						false, PwDefs.HiddenPassword), ctx, uRecursionLevel);
@@ -403,7 +402,7 @@ namespace KeePass.Util.Spr
 					else { nOffset = nStart + 1; continue; }
 
 					if((chWanted == 'P') && !ctx.ForcePlainTextPasswords &&
-						Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password, true))
+						Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password))
 						strInsData = PwDefs.HiddenPassword;
 
 					SprContext sprSub = ctx.WithoutContentTransformations();
diff --git a/KeePass/Util/TempFilesPool.cs b/KeePass/Util/TempFilesPool.cs
index d5ce48b..9cc9e5b 100644
--- a/KeePass/Util/TempFilesPool.cs
+++ b/KeePass/Util/TempFilesPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/TextSimilarity.cs b/KeePass/Util/TextSimilarity.cs
index 8946b69..b2c695b 100644
--- a/KeePass/Util/TextSimilarity.cs
+++ b/KeePass/Util/TextSimilarity.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePass/Util/UpdateCheckEx.cs b/KeePass/Util/UpdateCheckEx.cs
new file mode 100644
index 0000000..f11ad06
--- /dev/null
+++ b/KeePass/Util/UpdateCheckEx.cs
@@ -0,0 +1,488 @@
+/*
+  KeePass Password Safe - The Open-Source Password Manager
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Threading;
+using System.Windows.Forms;
+using System.Diagnostics;
+
+using KeePass.Forms;
+using KeePass.Plugins;
+using KeePass.Resources;
+using KeePass.UI;
+
+using KeePassLib;
+using KeePassLib.Interfaces;
+using KeePassLib.Serialization;
+using KeePassLib.Utility;
+
+namespace KeePass.Util
+{
+	public enum UpdateComponentStatus
+	{
+		Unknown = 0,
+		UpToDate,
+		NewVerAvailable,
+		PreRelease,
+		DownloadFailed
+	}
+
+	public sealed class UpdateComponentInfo
+	{
+		private readonly string m_strName; // Never null
+		public string Name
+		{
+			get { return m_strName; }
+		}
+
+		private readonly ulong m_uVerInstalled;
+		public ulong VerInstalled
+		{
+			get { return m_uVerInstalled; }
+		}
+
+		private ulong m_uVerAvailable = 0;
+		public ulong VerAvailable
+		{
+			get { return m_uVerAvailable; }
+			set { m_uVerAvailable = value; }
+		}
+
+		private UpdateComponentStatus m_status = UpdateComponentStatus.Unknown;
+		public UpdateComponentStatus Status
+		{
+			get { return m_status; }
+			set { m_status = value; }
+		}
+
+		private readonly string m_strUpdateUrl; // Never null
+		public string UpdateUrl
+		{
+			get { return m_strUpdateUrl; }
+		}
+
+		private readonly string m_strCat; // Never null
+		public string Category
+		{
+			get { return m_strCat; }
+		}
+
+		public UpdateComponentInfo(string strName, ulong uVerInstalled,
+			string strUpdateUrl, string strCategory)
+		{
+			if(strName == null) throw new ArgumentNullException("strName");
+			if(strUpdateUrl == null) throw new ArgumentNullException("strUpdateUrl");
+			if(strCategory == null) throw new ArgumentNullException("strCategory");
+
+			m_strName = strName;
+			m_uVerInstalled = uVerInstalled;
+			m_strUpdateUrl = strUpdateUrl;
+			m_strCat = strCategory;
+		}
+	}
+
+	public static class UpdateCheckEx
+	{
+		private sealed class UpdateCheckParams
+		{
+			public readonly bool ForceUI;
+			public readonly Form Parent; // May be null
+
+			public UpdateCheckParams(bool bForceUI, Form fOptParent)
+			{
+				this.ForceUI = bForceUI;
+				this.Parent = fOptParent;
+			}
+		}
+
+		public static void Run(bool bForceUI, Form fOptParent)
+		{
+			DateTime dtNow = DateTime.Now, dtLast;
+			string strLast = Program.Config.Application.LastUpdateCheck;
+			if(!bForceUI && (strLast.Length > 0) && TimeUtil.TryDeserializeUtc(
+				strLast, out dtLast))
+			{
+				if(CompareDates(dtLast, dtNow) == 0) return; // Checked today already
+			}
+			Program.Config.Application.LastUpdateCheck = TimeUtil.SerializeUtc(dtNow);
+
+			UpdateCheckParams p = new UpdateCheckParams(bForceUI, fOptParent);
+			if(!bForceUI) // Async
+			{
+				// // Local, but thread will continue to run anyway
+				// Thread th = new Thread(new ParameterizedThreadStart(
+				//	UpdateCheckEx.RunPriv));
+				// th.Start(p);
+
+				try
+				{
+					ThreadPool.QueueUserWorkItem(new WaitCallback(
+						UpdateCheckEx.RunPriv), p);
+				}
+				catch(Exception) { Debug.Assert(false); }
+			}
+			else RunPriv(p);
+		}
+
+		private static int CompareDates(DateTime a, DateTime b)
+		{
+			if(a.Year != b.Year) return ((a.Year < b.Year) ? -1 : 1);
+			if(a.Month != b.Month) return ((a.Month < b.Month) ? -1 : 1);
+			if(a.Day != b.Day) return ((a.Day < b.Day) ? -1 : 1);
+			return 0;
+		}
+
+		private static void RunPriv(object o)
+		{
+			UpdateCheckParams p = (o as UpdateCheckParams);
+			if(p == null) { Debug.Assert(false); return; }
+
+			IStatusLogger sl = null;
+			try
+			{
+				if(p.ForceUI)
+				{
+					Form fStatusDialog;
+					sl = StatusUtil.CreateStatusDialog(p.Parent, out fStatusDialog,
+						KPRes.UpdateCheck, KPRes.CheckingForUpd + "...", true, true);
+				}
+
+				List<UpdateComponentInfo> lInst = GetInstalledComponents();
+				List<string> lUrls = GetUrls(lInst);
+				Dictionary<string, List<UpdateComponentInfo>> dictAvail =
+					DownloadInfoFiles(lUrls, sl);
+				if(dictAvail == null) return; // User cancelled
+
+				MergeInfo(lInst, dictAvail);
+
+				bool bUpdAvail = false;
+				foreach(UpdateComponentInfo uc in lInst)
+				{
+					if(uc.Status == UpdateComponentStatus.NewVerAvailable)
+					{
+						bUpdAvail = true;
+						break;
+					}
+				}
+
+				if(sl != null) { sl.EndLogging(); sl = null; }
+
+				if(bUpdAvail || p.ForceUI)
+				{
+					UpdateCheckForm dlg = new UpdateCheckForm();
+					dlg.InitEx(lInst, p.ForceUI);
+					UIUtil.ShowDialogAndDestroy(dlg);
+				}
+			}
+			catch(Exception) { Debug.Assert(false); }
+			finally
+			{
+				try { if(sl != null) sl.EndLogging(); }
+				catch(Exception) { Debug.Assert(false); }
+			}
+		}
+
+		private sealed class UpdateDownloadInfo
+		{
+			public readonly string Url; // Never null
+			public object SyncObj = new object();
+			public bool Ready = false;
+			public List<UpdateComponentInfo> ComponentInfo = null;
+
+			public UpdateDownloadInfo(string strUrl)
+			{
+				if(strUrl == null) throw new ArgumentNullException("strUrl");
+
+				this.Url = strUrl;
+			}
+		}
+
+		private static Dictionary<string, List<UpdateComponentInfo>>
+			DownloadInfoFiles(List<string> lUrls, IStatusLogger sl)
+		{
+			List<UpdateDownloadInfo> lDl = new List<UpdateDownloadInfo>();
+			foreach(string strUrl in lUrls)
+			{
+				if(string.IsNullOrEmpty(strUrl)) { Debug.Assert(false); continue; }
+
+				UpdateDownloadInfo dl = new UpdateDownloadInfo(strUrl);
+				lDl.Add(dl);
+
+				ThreadPool.QueueUserWorkItem(new WaitCallback(
+					UpdateCheckEx.DownloadInfoFile), dl);
+			}
+
+			while(true)
+			{
+				bool bReady = true;
+				foreach(UpdateDownloadInfo dl in lDl)
+				{
+					lock(dl.SyncObj) { bReady &= dl.Ready; }
+				}
+
+				if(bReady) break;
+				Thread.Sleep(40);
+
+				if(sl != null)
+				{
+					if(!sl.ContinueWork()) return null;
+				}
+			}
+
+			Dictionary<string, List<UpdateComponentInfo>> dict =
+				new Dictionary<string, List<UpdateComponentInfo>>();
+			foreach(UpdateDownloadInfo dl in lDl)
+			{
+				dict[dl.Url.ToLower()] = dl.ComponentInfo;
+			}
+			return dict;
+		}
+
+		private static void DownloadInfoFile(object o)
+		{
+			UpdateDownloadInfo dl = (o as UpdateDownloadInfo);
+			if(dl == null) { Debug.Assert(false); return; }
+
+			dl.ComponentInfo = LoadInfoFile(dl.Url);
+			lock(dl.SyncObj) { dl.Ready = true; }
+		}
+
+		private static List<string> GetUrls(List<UpdateComponentInfo> l)
+		{
+			List<string> lUrls = new List<string>();
+			foreach(UpdateComponentInfo uc in l)
+			{
+				string strUrl = uc.UpdateUrl;
+				if(string.IsNullOrEmpty(strUrl)) continue;
+
+				bool bFound = false;
+				for(int i = 0; i < lUrls.Count; ++i)
+				{
+					if(lUrls[i].Equals(strUrl, StrUtil.CaseIgnoreCmp))
+					{
+						bFound = true;
+						break;
+					}
+				}
+
+				if(!bFound) lUrls.Add(strUrl);
+			}
+
+			return lUrls;
+		}
+
+		private static List<UpdateComponentInfo> LoadInfoFile(string strUrl)
+		{
+			try
+			{
+				IOConnectionInfo ioc = IOConnectionInfo.FromPath(strUrl.Trim());
+
+				Stream s = IOConnection.OpenRead(ioc);
+				if(s == null) throw new InvalidOperationException();
+				MemoryStream ms = new MemoryStream();
+				MemUtil.CopyStream(s, ms);
+				s.Close();
+				byte[] pb = ms.ToArray();
+				ms.Close();
+
+				if(ioc.Path.EndsWith(".gz", StrUtil.CaseIgnoreCmp))
+					pb = MemUtil.Decompress(pb);
+
+				string strData = StrUtil.Utf8.GetString(pb);
+				strData = StrUtil.NormalizeNewLines(strData, false);
+				string[] vLines = strData.Split('\n');
+
+				List<UpdateComponentInfo> l = new List<UpdateComponentInfo>();
+				bool bHeader = true, bFooterFound = false;
+				char chSep = ':'; // Modified by header
+				for(int i = 0; i < vLines.Length; ++i)
+				{
+					string str = vLines[i].Trim();
+					if(str.Length == 0) continue;
+
+					if(bHeader)
+					{
+						chSep = str[0];
+						bHeader = false;
+					}
+					else if(str[0] == chSep)
+					{
+						bFooterFound = true;
+						break;
+					}
+					else // Component info
+					{
+						string[] vInfo = str.Split(new char[] { chSep });
+						if(vInfo.Length >= 2)
+						{
+							UpdateComponentInfo c = new UpdateComponentInfo(
+								vInfo[0].Trim(), 0, ioc.Path, string.Empty);
+							c.VerAvailable = StrUtil.GetVersion(vInfo[1]);
+
+							AddComponent(l, c);
+						}
+					}
+				}
+
+				return (bFooterFound ? l : null);
+			}
+			catch(Exception) { }
+
+			return null;
+		}
+
+		private static void AddComponent(List<UpdateComponentInfo> l,
+			UpdateComponentInfo c)
+		{
+			if((l == null) || (c == null)) { Debug.Assert(false); return; }
+
+			for(int i = l.Count - 1; i >= 0; --i)
+			{
+				if(l[i].Name.Equals(c.Name, StrUtil.CaseIgnoreCmp))
+					l.RemoveAt(i);
+			}
+
+			l.Add(c);
+		}
+
+		private static List<UpdateComponentInfo> GetInstalledComponents()
+		{
+			List<UpdateComponentInfo> l = new List<UpdateComponentInfo>();
+
+			foreach(PluginInfo pi in Program.MainForm.PluginManager)
+			{
+				Plugin p = pi.Interface;
+				string strUrl = ((p != null) ? (p.UpdateUrl ?? string.Empty) :
+					string.Empty);
+
+				AddComponent(l, new UpdateComponentInfo(pi.Name.Trim(),
+					StrUtil.GetVersion(pi.FileVersion), strUrl.Trim(),
+					KPRes.Plugins));
+			}
+
+			// Add KeePass at the end to override any buggy plugin names
+			AddComponent(l, new UpdateComponentInfo(PwDefs.ShortProductName,
+				PwDefs.FileVersion64, PwDefs.VersionUrl, PwDefs.ShortProductName));
+			
+			l.Sort(UpdateCheckEx.CompareComponents);
+			return l;
+		}
+
+		private static int CompareComponents(UpdateComponentInfo a,
+			UpdateComponentInfo b)
+		{
+			if(a.Name == b.Name) return 0;
+			if(a.Name == PwDefs.ShortProductName) return -1;
+			if(b.Name == PwDefs.ShortProductName) return 1;
+
+			return a.Name.CompareTo(b.Name);
+		}
+
+		private static void MergeInfo(List<UpdateComponentInfo> lInst,
+			Dictionary<string, List<UpdateComponentInfo>> dictAvail)
+		{
+			string strOvrId = PwDefs.VersionUrl.ToLower();
+			List<UpdateComponentInfo> lOvr;
+			dictAvail.TryGetValue(strOvrId, out lOvr);
+
+			foreach(UpdateComponentInfo uc in lInst)
+			{
+				string strUrlId = uc.UpdateUrl.ToLower();
+				List<UpdateComponentInfo> lAvail;
+				dictAvail.TryGetValue(strUrlId, out lAvail);
+
+				if(SetComponentAvail(uc, lOvr)) { }
+				else if(SetComponentAvail(uc, lAvail)) { }
+				else if((strUrlId.Length > 0) && (lAvail == null))
+					uc.Status = UpdateComponentStatus.DownloadFailed;
+				else uc.Status = UpdateComponentStatus.Unknown;
+			}
+		}
+
+		private static bool SetComponentAvail(UpdateComponentInfo uc,
+			List<UpdateComponentInfo> lAvail)
+		{
+			if(uc == null) { Debug.Assert(false); return false; }
+			if(lAvail == null) return false; // No assert
+
+			foreach(UpdateComponentInfo ucAvail in lAvail)
+			{
+				if(ucAvail.Name.Equals(uc.Name, StrUtil.CaseIgnoreCmp))
+				{
+					uc.VerAvailable = ucAvail.VerAvailable;
+
+					if(uc.VerInstalled == uc.VerAvailable)
+						uc.Status = UpdateComponentStatus.UpToDate;
+					else if(uc.VerInstalled < uc.VerAvailable)
+						uc.Status = UpdateComponentStatus.NewVerAvailable;
+					else uc.Status = UpdateComponentStatus.PreRelease;
+
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		public static void EnsureConfigured(Form fParent)
+		{
+			if(Program.Config.Application.Start.CheckForUpdateConfigured) return;
+
+			// If the user has manually enabled the automatic update check
+			// before, there's no need to ask him again
+			if(!Program.Config.Application.Start.CheckForUpdate)
+			{
+				string strHdr = KPRes.UpdateCheckInfo;
+				string strSub = KPRes.UpdateCheckInfoRes + MessageService.NewParagraph +
+					KPRes.UpdateCheckInfoPriv;
+
+				VistaTaskDialog dlg = new VistaTaskDialog((fParent != null) ?
+					fParent.Handle : IntPtr.Zero);
+				dlg.CommandLinks = true;
+				dlg.Content = strHdr;
+				dlg.MainInstruction = KPRes.UpdateCheckEnableQ;
+				dlg.WindowTitle = PwDefs.ShortProductName;
+				dlg.AddButton((int)DialogResult.Yes, KPRes.Enable +
+					" (" + KPRes.Recommended + ")", null);
+				dlg.AddButton((int)DialogResult.No, KPRes.Disable, null);
+				dlg.SetIcon(VtdCustomIcon.Question);
+				dlg.FooterText = strSub;
+				dlg.SetFooterIcon(VtdIcon.Information);
+
+				int iResult;
+				if(dlg.ShowDialog()) iResult = dlg.Result;
+				else
+				{
+					string strMain = strHdr + MessageService.NewParagraph + strSub;
+					iResult = (MessageService.AskYesNo(strMain + MessageService.NewParagraph +
+						KPRes.UpdateCheckEnableQ, PwDefs.ShortProductName) ?
+						(int)DialogResult.Yes : (int)DialogResult.No);
+				}
+
+				Program.Config.Application.Start.CheckForUpdate = ((iResult ==
+					(int)DialogResult.OK) || (iResult == (int)DialogResult.Yes));
+			}
+
+			Program.Config.Application.Start.CheckForUpdateConfigured = true;
+		}
+	}
+}
diff --git a/KeePass/Util/WinUtil.cs b/KeePass/Util/WinUtil.cs
index facf720..8b1df4e 100644
--- a/KeePass/Util/WinUtil.cs
+++ b/KeePass/Util/WinUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -569,5 +569,39 @@ namespace KeePass.Util
 
 			return null;
 		}
+
+		public static string LocateSystemApp(string strExeName)
+		{
+			if(strExeName == null) { Debug.Assert(false); return string.Empty; }
+			if(strExeName.Length == 0) return strExeName;
+
+			if(NativeLib.IsUnix()) return strExeName;
+
+			try
+			{
+				string str = null;
+				for(int i = 0; i < 3; ++i)
+				{
+					if(i == 0)
+						str = Environment.GetFolderPath(
+							Environment.SpecialFolder.System);
+					else if(i == 1)
+						str = Environment.GetEnvironmentVariable("WinDir");
+					else if(i == 2)
+						str = Environment.GetEnvironmentVariable("SystemRoot");
+
+					if(!string.IsNullOrEmpty(str))
+					{
+						str = UrlUtil.EnsureTerminatingSeparator(str, false);
+						str += strExeName;
+
+						if(File.Exists(str)) return str;
+					}
+				}
+			}
+			catch(Exception) { Debug.Assert(false); }
+
+			return strExeName;
+		}
 	}
 }
diff --git a/KeePass/Util/XmlUtil.cs b/KeePass/Util/XmlUtil.cs
index da4a43f..aa62d56 100644
--- a/KeePass/Util/XmlUtil.cs
+++ b/KeePass/Util/XmlUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Collections/AutoTypeConfig.cs b/KeePassLib/Collections/AutoTypeConfig.cs
index 85196e7..fb098ce 100644
--- a/KeePassLib/Collections/AutoTypeConfig.cs
+++ b/KeePassLib/Collections/AutoTypeConfig.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Collections/ProtectedBinaryDictionary.cs b/KeePassLib/Collections/ProtectedBinaryDictionary.cs
index ab6fe6e..3e870c5 100644
--- a/KeePassLib/Collections/ProtectedBinaryDictionary.cs
+++ b/KeePassLib/Collections/ProtectedBinaryDictionary.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -82,13 +82,10 @@ namespace KeePassLib.Collections
 		{
 			ProtectedBinaryDictionary plNew = new ProtectedBinaryDictionary();
 
-			ProtectedBinary pbNew;
 			foreach(KeyValuePair<string, ProtectedBinary> kvpBin in m_vBinaries)
 			{
-				pbNew = new ProtectedBinary(kvpBin.Value); // Clone deep
-				Debug.Assert(pbNew != kvpBin.Value);
-
-				plNew.Set(kvpBin.Key, pbNew);
+				// ProtectedBinary objects are immutable
+				plNew.Set(kvpBin.Key, kvpBin.Value);
 			}
 
 			return plNew;
@@ -104,7 +101,7 @@ namespace KeePassLib.Collections
 			{
 				ProtectedBinary pb = dict.Get(kvp.Key);
 				if(pb == null) return false;
-				if(!MemUtil.ArraysEqual(pb.ReadData(), kvp.Value.ReadData())) return false;
+				if(!pb.Equals(kvp.Value)) return false;
 			}
 
 			return true;
diff --git a/KeePassLib/Collections/ProtectedStringDictionary.cs b/KeePassLib/Collections/ProtectedStringDictionary.cs
index a72b4d6..77832af 100644
--- a/KeePassLib/Collections/ProtectedStringDictionary.cs
+++ b/KeePassLib/Collections/ProtectedStringDictionary.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -82,13 +82,10 @@ namespace KeePassLib.Collections
 		{
 			ProtectedStringDictionary plNew = new ProtectedStringDictionary();
 
-			ProtectedString psNew;
 			foreach(KeyValuePair<string, ProtectedString> kvpStr in m_vStrings)
 			{
-				psNew = new ProtectedString(kvpStr.Value);
-				Debug.Assert(psNew != kvpStr.Value);
-
-				plNew.Set(kvpStr.Key, psNew);
+				// ProtectedString objects are immutable
+				plNew.Set(kvpStr.Key, kvpStr.Value);
 			}
 
 			return plNew;
@@ -97,19 +94,36 @@ namespace KeePassLib.Collections
 		[Obsolete]
 		public bool EqualsDictionary(ProtectedStringDictionary dict)
 		{
-			return EqualsDictionary(dict, MemProtCmpMode.None);
+			return EqualsDictionary(dict, PwCompareOptions.None, MemProtCmpMode.None);
 		}
 
+		[Obsolete]
 		public bool EqualsDictionary(ProtectedStringDictionary dict,
 			MemProtCmpMode mpCompare)
 		{
+			return EqualsDictionary(dict, PwCompareOptions.None, mpCompare);
+		}
+
+		public bool EqualsDictionary(ProtectedStringDictionary dict,
+			PwCompareOptions pwOpt, MemProtCmpMode mpCompare)
+		{
 			if(dict == null) { Debug.Assert(false); return false; }
 
-			if(m_vStrings.Count != dict.m_vStrings.Count) return false;
+			bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
+				PwCompareOptions.None);
+			if(!bNeEqStd)
+			{
+				if(m_vStrings.Count != dict.m_vStrings.Count) return false;
+			}
 
 			foreach(KeyValuePair<string, ProtectedString> kvp in m_vStrings)
 			{
+				bool bStdField = PwDefs.IsStandardField(kvp.Key);
 				ProtectedString ps = dict.Get(kvp.Key);
+
+				if(bNeEqStd && (ps == null) && bStdField)
+					ps = ProtectedString.Empty;
+
 				if(ps == null) return false;
 
 				if(mpCompare == MemProtCmpMode.Full)
@@ -118,13 +132,25 @@ namespace KeePassLib.Collections
 				}
 				else if(mpCompare == MemProtCmpMode.CustomOnly)
 				{
-					if(!PwDefs.IsStandardField(kvp.Key) &&
-						(ps.IsProtected != kvp.Value.IsProtected)) return false;
+					if(!bStdField && (ps.IsProtected != kvp.Value.IsProtected))
+						return false;
 				}
 
 				if(ps.ReadString() != kvp.Value.ReadString()) return false;
 			}
 
+			if(bNeEqStd)
+			{
+				foreach(KeyValuePair<string, ProtectedString> kvp in dict.m_vStrings)
+				{
+					ProtectedString ps = Get(kvp.Key);
+
+					if(ps != null) continue; // Compared previously
+					if(!PwDefs.IsStandardField(kvp.Key)) return false;
+					if(!kvp.Value.IsEmpty) return false;
+				}
+			}
+
 			return true;
 		}
 
@@ -164,7 +190,7 @@ namespace KeePassLib.Collections
 			ProtectedString ps;
 			if(m_vStrings.TryGetValue(strName, out ps)) return ps;
 
-			return new ProtectedString();
+			return ProtectedString.Empty;
 		}
 
 		/// <summary>
@@ -219,7 +245,7 @@ namespace KeePassLib.Collections
 			if(m_vStrings.TryGetValue(strName, out ps))
 			{
 				if(ps.IsProtected) return PwDefs.HiddenPassword;
-				else return ps.ReadString();
+				return ps.ReadString();
 			}
 
 			return string.Empty;
@@ -263,5 +289,18 @@ namespace KeePassLib.Collections
 
 			return v;
 		}
+
+		public void EnableProtection(string strField, bool bProtect)
+		{
+			ProtectedString ps = Get(strField);
+			if(ps == null) return; // Nothing to do, no assert
+
+			if(ps.IsProtected != bProtect)
+			{
+				byte[] pbData = ps.ReadUtf8();
+				Set(strField, new ProtectedString(bProtect, pbData));
+				MemUtil.ZeroByteArray(pbData);
+			}
+		}
 	}
 }
diff --git a/KeePassLib/Collections/PwObjectList.cs b/KeePassLib/Collections/PwObjectList.cs
index 5a3a837..0cb748b 100644
--- a/KeePassLib/Collections/PwObjectList.cs
+++ b/KeePassLib/Collections/PwObjectList.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Collections/PwObjectPool.cs b/KeePassLib/Collections/PwObjectPool.cs
index 6abfebe..2889765 100644
--- a/KeePassLib/Collections/PwObjectPool.cs
+++ b/KeePassLib/Collections/PwObjectPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Collections/StringDictionaryEx.cs b/KeePassLib/Collections/StringDictionaryEx.cs
index 585acac..4c4d715 100644
--- a/KeePassLib/Collections/StringDictionaryEx.cs
+++ b/KeePassLib/Collections/StringDictionaryEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/Cipher/CipherPool.cs b/KeePassLib/Cryptography/Cipher/CipherPool.cs
index 1a4fce9..ab7e899 100644
--- a/KeePassLib/Cryptography/Cipher/CipherPool.cs
+++ b/KeePassLib/Cryptography/Cipher/CipherPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/Cipher/ICipherEngine.cs b/KeePassLib/Cryptography/Cipher/ICipherEngine.cs
index d052e23..dad37e2 100644
--- a/KeePassLib/Cryptography/Cipher/ICipherEngine.cs
+++ b/KeePassLib/Cryptography/Cipher/ICipherEngine.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -48,7 +48,7 @@ namespace KeePassLib.Cryptography.Cipher
 		/// <summary>
 		/// Encrypt a stream.
 		/// </summary>
-		/// <param name="sPlainText">Stream to read the plain text from.</param>
+		/// <param name="sPlainText">Stream to read the plain-text from.</param>
 		/// <param name="pbKey">Key to use.</param>
 		/// <param name="pbIV">Initialization vector.</param>
 		/// <returns>Stream, from which the encrypted data can be read.</returns>
diff --git a/KeePassLib/Cryptography/Cipher/Salsa20Cipher.cs b/KeePassLib/Cryptography/Cipher/Salsa20Cipher.cs
index bcea943..4f9de90 100644
--- a/KeePassLib/Cryptography/Cipher/Salsa20Cipher.cs
+++ b/KeePassLib/Cryptography/Cipher/Salsa20Cipher.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/Cipher/StandardAesEngine.cs b/KeePassLib/Cryptography/Cipher/StandardAesEngine.cs
index ea52331..11640a8 100644
--- a/KeePassLib/Cryptography/Cipher/StandardAesEngine.cs
+++ b/KeePassLib/Cryptography/Cipher/StandardAesEngine.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/CryptoRandom.cs b/KeePassLib/Cryptography/CryptoRandom.cs
index 91a82af..6fb32ba 100644
--- a/KeePassLib/Cryptography/CryptoRandom.cs
+++ b/KeePassLib/Cryptography/CryptoRandom.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@ namespace KeePassLib.Cryptography
 			Random r = new Random();
 			m_uCounter = (uint)r.Next();
 
-			AddEntropy(GetSystemData());
+			AddEntropy(GetSystemData(r));
 			AddEntropy(GetCspData());
 		}
 
@@ -122,14 +122,14 @@ namespace KeePassLib.Cryptography
 				SHA256Managed shaPool = new SHA256Managed();
 #endif
 				m_pbEntropyPool = shaPool.ComputeHash(pbFinal);
-				ms.Close();
 			}
+			ms.Close();
 		}
 
-		private static byte[] GetSystemData()
+		private static byte[] GetSystemData(Random rWeak)
 		{
-			byte[] pb;
 			MemoryStream ms = new MemoryStream();
+			byte[] pb;
 
 			pb = MemUtil.UInt32ToBytes((uint)Environment.TickCount);
 			ms.Write(pb, 0, pb.Length);
@@ -145,8 +145,7 @@ namespace KeePassLib.Cryptography
 			ms.Write(pb, 0, pb.Length);
 #endif
 
-			Random r = new Random();
-			pb = MemUtil.UInt32ToBytes((uint)r.Next());
+			pb = MemUtil.UInt32ToBytes((uint)rWeak.Next());
 			ms.Write(pb, 0, pb.Length);
 
 			pb = MemUtil.UInt32ToBytes((uint)NativeLib.GetPlatformID());
@@ -205,7 +204,9 @@ namespace KeePassLib.Cryptography
 			pb = Guid.NewGuid().ToByteArray();
 			ms.Write(pb, 0, pb.Length);
 
-			return ms.ToArray();
+			byte[] pbAll = ms.ToArray();
+			ms.Close();
+			return pbAll;
 		}
 
 		private byte[] GetCspData()
@@ -235,6 +236,7 @@ namespace KeePassLib.Cryptography
 				pbFinal = ms.ToArray();
 				Debug.Assert(pbFinal.Length == (m_pbEntropyPool.Length +
 					pbCounter.Length + pbCspRandom.Length));
+				ms.Close();
 
 				m_uGeneratedBytesCount += 32;
 			}
diff --git a/KeePassLib/Cryptography/CryptoRandomStream.cs b/KeePassLib/Cryptography/CryptoRandomStream.cs
index 429753e..eda21ab 100644
--- a/KeePassLib/Cryptography/CryptoRandomStream.cs
+++ b/KeePassLib/Cryptography/CryptoRandomStream.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/HashingStreamEx.cs b/KeePassLib/Cryptography/HashingStreamEx.cs
index 130a530..aa2e4db 100644
--- a/KeePassLib/Cryptography/HashingStreamEx.cs
+++ b/KeePassLib/Cryptography/HashingStreamEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/HmacOtp.cs b/KeePassLib/Cryptography/HmacOtp.cs
index b1328ae..faa3785 100644
--- a/KeePassLib/Cryptography/HmacOtp.cs
+++ b/KeePassLib/Cryptography/HmacOtp.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs b/KeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs
index 4640ce7..67f1295 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -29,9 +29,10 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 {
 	internal static class CharSetBasedGenerator
 	{
-		public static PwgError Generate(ProtectedString psOutBuffer,
+		internal static PwgError Generate(out ProtectedString psOut,
 			PwProfile pwProfile, CryptoRandomStream crsRandomSource)
 		{
+			psOut = ProtectedString.Empty;
 			if(pwProfile.Length == 0) return PwgError.Success;
 
 			PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString());
@@ -53,9 +54,9 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 				vGenerated[nIndex] = ch;
 			}
 
-			byte[] pbUTF8 = StrUtil.Utf8.GetBytes(vGenerated);
-			psOutBuffer.SetString(StrUtil.Utf8.GetString(pbUTF8, 0, pbUTF8.Length));
-			Array.Clear(pbUTF8, 0, pbUTF8.Length);
+			byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vGenerated);
+			psOut = new ProtectedString(true, pbUtf8);
+			MemUtil.ZeroByteArray(pbUtf8);
 			Array.Clear(vGenerated, 0, vGenerated.Length);
 
 			return PwgError.Success;
diff --git a/KeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs b/KeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs
index 1e696b0..041d04e 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs b/KeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs
index 18575a8..38a3f77 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs b/KeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs
index e892f79..9c32132 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -29,9 +29,10 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 {
 	internal static class PatternBasedGenerator
 	{
-		public static PwgError Generate(ProtectedString psOutBuffer,
+		internal static PwgError Generate(out ProtectedString psOut,
 			PwProfile pwProfile, CryptoRandomStream crsRandomSource)
 		{
+			psOut = ProtectedString.Empty;
 			LinkedList<char> vGenerated = new LinkedList<char>();
 			PwCharSet pcsCurrent = new PwCharSet();
 			PwCharSet pcsCustom = new PwCharSet();
@@ -118,8 +119,8 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 				PwGenerator.ShufflePassword(vArray, crsRandomSource);
 
 			byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vArray);
-			psOutBuffer.SetString(StrUtil.Utf8.GetString(pbUtf8, 0, pbUtf8.Length));
-			Array.Clear(pbUtf8, 0, pbUtf8.Length);
+			psOut = new ProtectedString(true, pbUtf8);
+			MemUtil.ZeroByteArray(pbUtf8);
 			Array.Clear(vArray, 0, vArray.Length);
 			vGenerated.Clear();
 
diff --git a/KeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs b/KeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs
index 25ab04e..8a32c6e 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs b/KeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs
index fac51c4..4ddaa1d 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -39,27 +39,23 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 	/// </summary>
 	public static class PwGenerator
 	{
-		public static PwgError Generate(ProtectedString psOutBuffer,
+		public static PwgError Generate(out ProtectedString psOut,
 			PwProfile pwProfile, byte[] pbUserEntropy,
 			CustomPwGeneratorPool pwAlgorithmPool)
 		{
-			Debug.Assert(psOutBuffer != null);
-			if(psOutBuffer == null) throw new ArgumentNullException("psOutBuffer");
 			Debug.Assert(pwProfile != null);
 			if(pwProfile == null) throw new ArgumentNullException("pwProfile");
 
-			psOutBuffer.Clear();
-
 			CryptoRandomStream crs = CreateCryptoStream(pbUserEntropy);
 			PwgError e = PwgError.Unknown;
 
 			if(pwProfile.GeneratorType == PasswordGeneratorType.CharSet)
-				e = CharSetBasedGenerator.Generate(psOutBuffer, pwProfile, crs);
+				e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs);
 			else if(pwProfile.GeneratorType == PasswordGeneratorType.Pattern)
-				e = PatternBasedGenerator.Generate(psOutBuffer, pwProfile, crs);
+				e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs);
 			else if(pwProfile.GeneratorType == PasswordGeneratorType.Custom)
-				e = GenerateCustom(psOutBuffer, pwProfile, crs, pwAlgorithmPool);
-			else { Debug.Assert(false); }
+				e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool);
+			else { Debug.Assert(false); psOut = ProtectedString.Empty; }
 
 			return e;
 		}
@@ -123,10 +119,12 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 			}
 		}
 
-		private static PwgError GenerateCustom(ProtectedString psOutBuffer,
+		private static PwgError GenerateCustom(out ProtectedString psOut,
 			PwProfile pwProfile, CryptoRandomStream crs,
 			CustomPwGeneratorPool pwAlgorithmPool)
 		{
+			psOut = ProtectedString.Empty;
+
 			Debug.Assert(pwProfile.GeneratorType == PasswordGeneratorType.Custom);
 			if(pwAlgorithmPool == null) return PwgError.UnknownAlgorithm;
 
@@ -141,7 +139,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 			ProtectedString pwd = pwg.Generate(pwProfile.CloneDeep(), crs);
 			if(pwd == null) return PwgError.Unknown;
 
-			psOutBuffer.SetString(pwd.ReadString());
+			psOut = pwd;
 			return PwgError.Success;
 		}
 	}
diff --git a/KeePassLib/Cryptography/PasswordGenerator/PwProfile.cs b/KeePassLib/Cryptography/PasswordGenerator/PwProfile.cs
index 089c27e..46bb2d4 100644
--- a/KeePassLib/Cryptography/PasswordGenerator/PwProfile.cs
+++ b/KeePassLib/Cryptography/PasswordGenerator/PwProfile.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -239,8 +239,8 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 			PwProfile pp = new PwProfile();
 			Debug.Assert(psPassword != null); if(psPassword == null) return pp;
 
-			byte[] pbUTF8 = psPassword.ReadUtf8();
-			char[] vChars = StrUtil.Utf8.GetChars(pbUTF8);
+			byte[] pbUtf8 = psPassword.ReadUtf8();
+			char[] vChars = StrUtil.Utf8.GetChars(pbUtf8);
 
 			pp.GeneratorType = PasswordGeneratorType.CharSet;
 			pp.Length = (uint)vChars.Length;
@@ -265,7 +265,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
 			}
 
 			Array.Clear(vChars, 0, vChars.Length);
-			Array.Clear(pbUTF8, 0, pbUTF8.Length);
+			MemUtil.ZeroByteArray(pbUtf8);
 			return pp;
 		}
 
diff --git a/KeePassLib/Cryptography/PopularPasswords.cs b/KeePassLib/Cryptography/PopularPasswords.cs
index 3426a7f..af82756 100644
--- a/KeePassLib/Cryptography/PopularPasswords.cs
+++ b/KeePassLib/Cryptography/PopularPasswords.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/QualityEstimation.cs b/KeePassLib/Cryptography/QualityEstimation.cs
index 3a97c1c..de96068 100644
--- a/KeePassLib/Cryptography/QualityEstimation.cs
+++ b/KeePassLib/Cryptography/QualityEstimation.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Cryptography/SelfTest.cs b/KeePassLib/Cryptography/SelfTest.cs
index d1d7937..1625f25 100644
--- a/KeePassLib/Cryptography/SelfTest.cs
+++ b/KeePassLib/Cryptography/SelfTest.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -67,7 +67,7 @@ namespace KeePassLib.Cryptography
 
 			TestHmacOtp();
 
-			TestProtectedMemory();
+			TestProtectedObjects();
 			TestStrUtil();
 			TestUrlUtil();
 
@@ -243,7 +243,7 @@ namespace KeePassLib.Cryptography
 #endif
 		}
 
-		private static void TestProtectedMemory()
+		private static void TestProtectedObjects()
 		{
 #if DEBUG
 			byte[] pbData = Encoding.ASCII.GetBytes("Test Test Test Test");
@@ -259,9 +259,43 @@ namespace KeePassLib.Cryptography
 			byte[] pbData3 = Encoding.ASCII.GetBytes("Test Test Test Test Test");
 			ProtectedBinary pb2 = new ProtectedBinary(true, pbData2);
 			ProtectedBinary pb3 = new ProtectedBinary(true, pbData3);
-			if(!pb.EqualsValue(pb2)) throw new SecurityException("ProtectedBinary-4");
-			if(pb.EqualsValue(pb3)) throw new SecurityException("ProtectedBinary-5");
-			if(pb2.EqualsValue(pb3)) throw new SecurityException("ProtectedBinary-6");
+			if(!pb.Equals(pb2)) throw new SecurityException("ProtectedBinary-4");
+			if(pb.Equals(pb3)) throw new SecurityException("ProtectedBinary-5");
+			if(pb2.Equals(pb3)) throw new SecurityException("ProtectedBinary-6");
+
+			if(pb.GetHashCode() != pb2.GetHashCode())
+				throw new SecurityException("ProtectedBinary-7");
+			if(!((object)pb).Equals((object)pb2))
+				throw new SecurityException("ProtectedBinary-8");
+			if(((object)pb).Equals((object)pb3))
+				throw new SecurityException("ProtectedBinary-9");
+			if(((object)pb2).Equals((object)pb3))
+				throw new SecurityException("ProtectedBinary-10");
+
+			ProtectedString ps = new ProtectedString();
+			if(ps.Length != 0) throw new SecurityException("ProtectedString-1");
+			if(!ps.IsEmpty) throw new SecurityException("ProtectedString-2");
+			if(ps.ReadString().Length != 0)
+				throw new SecurityException("ProtectedString-3");
+
+			ps = new ProtectedString(true, "Test");
+			ProtectedString ps2 = new ProtectedString(true,
+				StrUtil.Utf8.GetBytes("Test"));
+			if(ps.IsEmpty) throw new SecurityException("ProtectedString-4");
+			pbData = ps.ReadUtf8();
+			pbData2 = ps2.ReadUtf8();
+			if(!MemUtil.ArraysEqual(pbData, pbData2))
+				throw new SecurityException("ProtectedString-5");
+			if(pbData.Length != 4)
+				throw new SecurityException("ProtectedString-6");
+			if(ps.ReadString() != ps2.ReadString())
+				throw new SecurityException("ProtectedString-7");
+			pbData = ps.ReadUtf8();
+			pbData2 = ps2.ReadUtf8();
+			if(!MemUtil.ArraysEqual(pbData, pbData2))
+				throw new SecurityException("ProtectedString-8");
+			if(!ps.IsProtected) throw new SecurityException("ProtectedString-9");
+			if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10");
 #endif
 		}
 
@@ -293,12 +327,38 @@ namespace KeePassLib.Cryptography
 			List<string> v3 = StrUtil.SplitWithSep("pqrs", vSeps, false);
 			if(v3.Count != 1) throw new InvalidOperationException("StrUtil-15");
 			if(!v3[0].Equals("pqrs")) throw new InvalidOperationException("StrUtil-16");
+
+			if(StrUtil.VersionToString(0x000F000E000D000CUL) != "15.14.13.12")
+				throw new InvalidOperationException("StrUtil-V1");
+			if(StrUtil.VersionToString(0x00FF000E00010000UL) != "255.14.1")
+				throw new InvalidOperationException("StrUtil-V2");
+			if(StrUtil.VersionToString(0x000F00FF00000000UL) != "15.255")
+				throw new InvalidOperationException("StrUtil-V3");
+			if(StrUtil.VersionToString(0x00FF000000000000UL) != "255")
+				throw new InvalidOperationException("StrUtil-V4");
 #endif
 		}
 
 		private static void TestUrlUtil()
 		{
 #if DEBUG
+			if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") !=
+				"domain")
+				throw new InvalidOperationException("UrlUtil-H1");
+			if(UrlUtil.GetHost(@"http://example.org:80") != "example.org")
+				throw new InvalidOperationException("UrlUtil-H2");
+			if(UrlUtil.GetHost(@"mailto:bob at example.com") != "example.com")
+				throw new InvalidOperationException("UrlUtil-H3");
+			if(UrlUtil.GetHost(@"ftp://asmith@ftp.example.org") != "ftp.example.org")
+				throw new InvalidOperationException("UrlUtil-H4");
+			if(UrlUtil.GetHost(@"scheme://username:password@domain:port/path?query_string#fragment_id") !=
+				"domain")
+				throw new InvalidOperationException("UrlUtil-H5");
+			if(UrlUtil.GetHost(@"bob at example.com") != "example.com")
+				throw new InvalidOperationException("UrlUtil-H6");
+			if(UrlUtil.GetHost(@"s://u:p@d.tld:p/p?q#f") != "d.tld")
+				throw new InvalidOperationException("UrlUtil-H7");
+
 			if(NativeLib.IsUnix()) return;
 
 			string strBase = "\\\\HOMESERVER\\Apps\\KeePass\\KeePass.exe";
@@ -306,10 +366,10 @@ namespace KeePassLib.Cryptography
 			string strRel = "..\\..\\Documents\\KeePass\\NewDatabase.kdbx";
 
 			string str = UrlUtil.MakeRelativePath(strBase, strDoc);
-			if(!str.Equals(strRel)) throw new InvalidOperationException("UrlUtil-1");
+			if(!str.Equals(strRel)) throw new InvalidOperationException("UrlUtil-R1");
 
 			str = UrlUtil.MakeAbsolutePath(strBase, strRel);
-			if(!str.Equals(strDoc)) throw new InvalidOperationException("UrlUtil-2");
+			if(!str.Equals(strDoc)) throw new InvalidOperationException("UrlUtil-R2");
 #endif
 		}
 	}
diff --git a/KeePassLib/Delegates/Handlers.cs b/KeePassLib/Delegates/Handlers.cs
index 27fc6fd..de858c7 100644
--- a/KeePassLib/Delegates/Handlers.cs
+++ b/KeePassLib/Delegates/Handlers.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Interfaces/IDeepCloneable.cs b/KeePassLib/Interfaces/IDeepCloneable.cs
index 7825b71..1233c52 100644
--- a/KeePassLib/Interfaces/IDeepCloneable.cs
+++ b/KeePassLib/Interfaces/IDeepCloneable.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Interfaces/IStatusLogger.cs b/KeePassLib/Interfaces/IStatusLogger.cs
index 0bbf390..5e595f6 100644
--- a/KeePassLib/Interfaces/IStatusLogger.cs
+++ b/KeePassLib/Interfaces/IStatusLogger.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Interfaces/IStructureItem.cs b/KeePassLib/Interfaces/IStructureItem.cs
index baafa9c..5294d57 100644
--- a/KeePassLib/Interfaces/IStructureItem.cs
+++ b/KeePassLib/Interfaces/IStructureItem.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Interfaces/ITimeLogger.cs b/KeePassLib/Interfaces/ITimeLogger.cs
index 755d105..0e25eba 100644
--- a/KeePassLib/Interfaces/ITimeLogger.cs
+++ b/KeePassLib/Interfaces/ITimeLogger.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Interfaces/IUIOperations.cs b/KeePassLib/Interfaces/IUIOperations.cs
index 549eb26..a4a2efb 100644
--- a/KeePassLib/Interfaces/IUIOperations.cs
+++ b/KeePassLib/Interfaces/IUIOperations.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/KeePassLib.csproj b/KeePassLib/KeePassLib.csproj
index a127a30..0a86798 100644
--- a/KeePassLib/KeePassLib.csproj
+++ b/KeePassLib/KeePassLib.csproj
@@ -100,6 +100,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="PwEnums.cs" />
     <Compile Include="Serialization\BinaryReaderEx.cs" />
+    <Compile Include="Serialization\FileLock.cs" />
     <Compile Include="Serialization\FileTransactionEx.cs" />
     <Compile Include="Serialization\HashedBlockStream.cs" />
     <Compile Include="Serialization\IOConnection.cs">
diff --git a/KeePassLib/Keys/CompositeKey.cs b/KeePassLib/Keys/CompositeKey.cs
index 422cbfd..c149fae 100644
--- a/KeePassLib/Keys/CompositeKey.cs
+++ b/KeePassLib/Keys/CompositeKey.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -60,25 +60,24 @@ namespace KeePassLib.Keys
 		{
 		}
 
-		/// <summary>
-		/// Deconstructor, clears up the key.
-		/// </summary>
-		~CompositeKey()
-		{
-			this.Clear();
-		}
-
-		/// <summary>
-		/// Clears the key. This function also erases all previously stored
-		/// user key data objects.
-		/// </summary>
-		public void Clear()
-		{
-			foreach(IUserKey pKey in m_vUserKeys)
-				pKey.Clear();
-
-			m_vUserKeys.Clear();
-		}
+		// /// <summary>
+		// /// Deconstructor, clears up the key.
+		// /// </summary>
+		// ~CompositeKey()
+		// {
+		//	Clear();
+		// }
+
+		// /// <summary>
+		// /// Clears the key. This function also erases all previously stored
+		// /// user key data objects.
+		// /// </summary>
+		// public void Clear()
+		// {
+		//	foreach(IUserKey pKey in m_vUserKeys)
+		//		pKey.Clear();
+		//	m_vUserKeys.Clear();
+		// }
 
 		/// <summary>
 		/// Add a user key.
@@ -163,12 +162,14 @@ namespace KeePassLib.Keys
 				{
 					byte[] pbKeyData = b.ReadData();
 					ms.Write(pbKeyData, 0, pbKeyData.Length);
-					Array.Clear(pbKeyData, 0, pbKeyData.Length);
+					MemUtil.ZeroByteArray(pbKeyData);
 				}
 			}
 
 			SHA256Managed sha256 = new SHA256Managed();
-			return sha256.ComputeHash(ms.ToArray());
+			byte[] pbHash = sha256.ComputeHash(ms.ToArray());
+			ms.Close();
+			return pbHash;
 		}
 
 		public bool EqualsValue(CompositeKey ckOther)
@@ -209,8 +210,8 @@ namespace KeePassLib.Keys
 				{ Debug.Assert(false); return null; }
 
 			ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32);
-			Array.Clear(pbTrf32, 0, 32);
-			Array.Clear(pbRaw32, 0, 32);
+			MemUtil.ZeroByteArray(pbTrf32);
+			MemUtil.ZeroByteArray(pbRaw32);
 
 			return pbRet;
 		}
diff --git a/KeePassLib/Keys/IUserKey.cs b/KeePassLib/Keys/IUserKey.cs
index 92bd8de..c9ccfd3 100644
--- a/KeePassLib/Keys/IUserKey.cs
+++ b/KeePassLib/Keys/IUserKey.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -38,9 +38,9 @@ namespace KeePassLib.Keys
 			get;
 		}
 
-		/// <summary>
-		/// Clear the key and securely erase all security-critical information.
-		/// </summary>
-		void Clear();
+		// /// <summary>
+		// /// Clear the key and securely erase all security-critical information.
+		// /// </summary>
+		// void Clear();
 	}
 }
diff --git a/KeePassLib/Keys/KcpCustomKey.cs b/KeePassLib/Keys/KcpCustomKey.cs
index 53b1d49..098351f 100644
--- a/KeePassLib/Keys/KcpCustomKey.cs
+++ b/KeePassLib/Keys/KcpCustomKey.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -24,12 +24,13 @@ using System.Diagnostics;
 using System.Security.Cryptography;
 
 using KeePassLib.Security;
+using KeePassLib.Utility;
 
 namespace KeePassLib.Keys
 {
 	public sealed class KcpCustomKey : IUserKey
 	{
-		private string m_strName;
+		private readonly string m_strName;
 		private ProtectedBinary m_pbKey;
 
 		/// <summary>
@@ -61,9 +62,9 @@ namespace KeePassLib.Keys
 			else m_pbKey = new ProtectedBinary(true, pbKeyData);
 		}
 
-		public void Clear()
-		{
-			m_pbKey.Clear();
-		}
+		// public void Clear()
+		// {
+		//	m_pbKey = null;
+		// }
 	}
 }
diff --git a/KeePassLib/Keys/KcpKeyFile.cs b/KeePassLib/Keys/KcpKeyFile.cs
index 959ad8e..1dcd8c5 100644
--- a/KeePassLib/Keys/KcpKeyFile.cs
+++ b/KeePassLib/Keys/KcpKeyFile.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -79,19 +79,11 @@ namespace KeePassLib.Keys
 			m_pbKeyData = new ProtectedBinary(true, pbKey);
 		}
 
-		/// <summary>
-		/// Clear the key and securely erase all security-critical information.
-		/// </summary>
-		public void Clear()
-		{
-			m_strPath = string.Empty;
-
-			if(m_pbKeyData != null)
-			{
-				m_pbKeyData.Clear();
-				m_pbKeyData = null;
-			}
-		}
+		// public void Clear()
+		// {
+		//	m_strPath = string.Empty;
+		//	m_pbKeyData = null;
+		// }
 
 		private static byte[] LoadKeyFile(IOConnectionInfo iocFile)
 		{
@@ -139,12 +131,9 @@ namespace KeePassLib.Keys
 			try
 			{
 				string strHex = Encoding.ASCII.GetString(pbFileData, 0, 64);
-
-				if(StrUtil.IsHexString(strHex, true) == false)
-					return null;
+				if(!StrUtil.IsHexString(strHex, true)) return null;
 
 				byte[] pbKey = MemUtil.HexStringToByteArray(strHex);
-
 				if((pbKey == null) || (pbKey.Length != 32))
 					return null;
 
diff --git a/KeePassLib/Keys/KcpPassword.cs b/KeePassLib/Keys/KcpPassword.cs
index 9a85c3e..1a1d86a 100644
--- a/KeePassLib/Keys/KcpPassword.cs
+++ b/KeePassLib/Keys/KcpPassword.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -32,8 +32,8 @@ namespace KeePassLib.Keys
 	/// </summary>
 	public sealed class KcpPassword : IUserKey
 	{
-		private ProtectedString m_psPassword = null;
-		private ProtectedBinary m_pbKeyData = null;
+		private ProtectedString m_psPassword;
+		private ProtectedBinary m_pbKeyData;
 
 		/// <summary>
 		/// Get the password as protected string.
@@ -75,22 +75,10 @@ namespace KeePassLib.Keys
 			m_pbKeyData = new ProtectedBinary(true, pbRaw);
 		}
 
-		/// <summary>
-		/// Clear the key and securely erase all security-critical information.
-		/// </summary>
-		public void Clear()
-		{
-			if(m_psPassword != null)
-			{
-				m_psPassword.Clear();
-				m_psPassword = null;
-			}
-
-			if(m_pbKeyData != null)
-			{
-				m_pbKeyData.Clear();
-				m_pbKeyData = null;
-			}
-		}
+		// public void Clear()
+		// {
+		//	m_psPassword = null;
+		//	m_pbKeyData = null;
+		// }
 	}
 }
diff --git a/KeePassLib/Keys/KcpUserAccount.cs b/KeePassLib/Keys/KcpUserAccount.cs
index a624dd0..3615656 100644
--- a/KeePassLib/Keys/KcpUserAccount.cs
+++ b/KeePassLib/Keys/KcpUserAccount.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -73,17 +73,10 @@ namespace KeePassLib.Keys
 			Array.Clear(pbKey, 0, pbKey.Length);
 		}
 
-		/// <summary>
-		/// Clear the key and securely erase all security-critical information.
-		/// </summary>
-		public void Clear()
-		{
-			if(m_pbKeyData != null)
-			{
-				m_pbKeyData.Clear();
-				m_pbKeyData = null;
-			}
-		}
+		// public void Clear()
+		// {
+		//	m_pbKeyData = null;
+		// }
 
 		private static string GetUserKeyFilePath(bool bCreate)
 		{
diff --git a/KeePassLib/Keys/KeyProvider.cs b/KeePassLib/Keys/KeyProvider.cs
index dd26118..1455302 100644
--- a/KeePassLib/Keys/KeyProvider.cs
+++ b/KeePassLib/Keys/KeyProvider.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Keys/KeyProviderPool.cs b/KeePassLib/Keys/KeyProviderPool.cs
index bf6fc99..8e1877d 100644
--- a/KeePassLib/Keys/KeyProviderPool.cs
+++ b/KeePassLib/Keys/KeyProviderPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Keys/KeyValidator.cs b/KeePassLib/Keys/KeyValidator.cs
index 48c9e62..9d93034 100644
--- a/KeePassLib/Keys/KeyValidator.cs
+++ b/KeePassLib/Keys/KeyValidator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Keys/KeyValidatorPool.cs b/KeePassLib/Keys/KeyValidatorPool.cs
index f56a188..d31a428 100644
--- a/KeePassLib/Keys/KeyValidatorPool.cs
+++ b/KeePassLib/Keys/KeyValidatorPool.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Keys/UserKeyType.cs b/KeePassLib/Keys/UserKeyType.cs
index 6b6641e..046d54a 100644
--- a/KeePassLib/Keys/UserKeyType.cs
+++ b/KeePassLib/Keys/UserKeyType.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Native/NativeLib.cs b/KeePassLib/Native/NativeLib.cs
index 19cd4d5..c4af820 100644
--- a/KeePassLib/Native/NativeLib.cs
+++ b/KeePassLib/Native/NativeLib.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Native/NativeMethods.cs b/KeePassLib/Native/NativeMethods.cs
index f431022..87170bd 100644
--- a/KeePassLib/Native/NativeMethods.cs
+++ b/KeePassLib/Native/NativeMethods.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Properties/AssemblyInfo.cs b/KeePassLib/Properties/AssemblyInfo.cs
index c5c3cc4..2d2b982 100644
--- a/KeePassLib/Properties/AssemblyInfo.cs
+++ b/KeePassLib/Properties/AssemblyInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Dominik Reichl")]
 [assembly: AssemblyProduct("KeePassLib")]
-[assembly: AssemblyCopyright("Copyright © 2003-2011 Dominik Reichl")]
+[assembly: AssemblyCopyright("Copyright © 2003-2012 Dominik Reichl")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -38,5 +38,5 @@ using System.Runtime.InteropServices;
 [assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")]
 
 // Assembly version information
-[assembly: AssemblyVersion("2.1.7.*")]
-[assembly: AssemblyFileVersion("2.1.7.0")]
+[assembly: AssemblyVersion("2.1.8.*")]
+[assembly: AssemblyFileVersion("2.1.8.0")]
diff --git a/KeePassLib/PwCustomIcon.cs b/KeePassLib/PwCustomIcon.cs
index c422ecc..72470dc 100644
--- a/KeePassLib/PwCustomIcon.cs
+++ b/KeePassLib/PwCustomIcon.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/PwDatabase.cs b/KeePassLib/PwDatabase.cs
index 9442918..df2d771 100644
--- a/KeePassLib/PwDatabase.cs
+++ b/KeePassLib/PwDatabase.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -96,6 +96,7 @@ namespace KeePassLib
 		private byte[] m_pbHashOfLastIO = null;
 
 		private bool m_bUseFileTransactions = false;
+		private bool m_bUseFileLocks = false;
 
 		private IStatusLogger m_slStatus = null;
 
@@ -436,6 +437,12 @@ namespace KeePassLib
 			set { m_bUseFileTransactions = value; }
 		}
 
+		public bool UseFileLocks
+		{
+			get { return m_bUseFileLocks; }
+			set { m_bUseFileLocks = value; }
+		}
+
 		private string m_strDetachBins = null;
 		/// <summary>
 		/// Detach binaries when opening a file. If this isn't <c>null</c>,
@@ -519,6 +526,7 @@ namespace KeePassLib
 			m_pbHashOfLastIO = null;
 
 			m_bUseFileTransactions = false;
+			m_bUseFileLocks = false;
 		}
 
 		/// <summary>
@@ -604,22 +612,24 @@ namespace KeePassLib
 		{
 			Debug.Assert(ValidateUuidUniqueness());
 
-			// bool bMadeUnhidden = UrlUtil.UnhideFile(m_ioSource.Path);
-			// Stream s = IOConnection.OpenWrite(m_ioSource);
-
-			FileTransactionEx ft = new FileTransactionEx(m_ioSource, m_bUseFileTransactions);
-			Stream s = ft.OpenWrite();
-
-			Kdb4File kdb = new Kdb4File(this);
-			kdb.Save(s, null, Kdb4Format.Default, slLogger);
+			FileLock fl = null;
+			if(m_bUseFileLocks) fl = new FileLock(m_ioSource);
+			try
+			{
+				FileTransactionEx ft = new FileTransactionEx(m_ioSource,
+					m_bUseFileTransactions);
+				Stream s = ft.OpenWrite();
 
-			ft.CommitWrite();
+				Kdb4File kdb = new Kdb4File(this);
+				kdb.Save(s, null, Kdb4Format.Default, slLogger);
 
-			// if(bMadeUnhidden) UrlUtil.HideFile(m_ioSource.Path, true); // Hide again
+				ft.CommitWrite();
 
-			m_pbHashOfLastIO = kdb.HashOfFileOnDisk;
-			m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
-			Debug.Assert(m_pbHashOfFileOnDisk != null);
+				m_pbHashOfLastIO = kdb.HashOfFileOnDisk;
+				m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
+				Debug.Assert(m_pbHashOfFileOnDisk != null);
+			}
+			finally { if(fl != null) fl.Dispose(); }
 
 			m_bModified = false;
 		}
@@ -762,8 +772,10 @@ namespace KeePassLib
 				{
 					Debug.Assert(mm != PwMergeMethod.CreateNewUuids);
 
-					bool bEquals = peLocal.EqualsEntry(pe, true, false, true,
-						true, false, MemProtCmpMode.None);
+					const PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup |
+						PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreHistory |
+						PwCompareOptions.NullEmptyEquivStd);
+					bool bEquals = peLocal.EqualsEntry(pe, cmpOpt, MemProtCmpMode.None);
 
 					bool bOrgBackup = !bEquals;
 					if(mm != PwMergeMethod.OverwriteExisting)
@@ -1634,6 +1646,7 @@ namespace KeePassLib
 				ProtectedString psB = b.Strings.Get(kvpA.Key);
 				if(psB == null) return false;
 
+				// Ignore protection setting, compare values only
 				if(!kvpA.Value.ReadString().Equals(psB.ReadString())) return false;
 			}
 
@@ -1654,7 +1667,13 @@ namespace KeePassLib
 				ProtectedBinary pbB = b.Binaries.Get(kvpBin.Key);
 				if(pbB == null) return false;
 
-				if(!kvpBin.Value.EqualsValue(pbB)) return false;
+				// Ignore protection setting, compare values only
+				byte[] pbDataA = kvpBin.Value.ReadData();
+				byte[] pbDataB = pbB.ReadData();
+				bool bBinEq = MemUtil.ArraysEqual(pbDataA, pbDataB);
+				MemUtil.ZeroByteArray(pbDataA);
+				MemUtil.ZeroByteArray(pbDataB);
+				if(!bBinEq) return false;
 			}
 
 			return true;
@@ -1733,6 +1752,7 @@ namespace KeePassLib
 				++uDeleted;
 			}
 
+			if(uDeleted > 0) m_bUINeedsIconUpdate = true;
 			return uDeleted;
 		}
 	}
diff --git a/KeePassLib/PwDefs.cs b/KeePassLib/PwDefs.cs
index cf7c6e6..89cad13 100644
--- a/KeePassLib/PwDefs.cs
+++ b/KeePassLib/PwDefs.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -48,15 +48,15 @@ namespace KeePassLib
 		/// Version, encoded as 32-bit unsigned integer.
 		/// 2.00 = 0x02000000, 2.01 = 0x02000100, 2.15 = 0x02010500, etc.
 		/// </summary>
-		public const uint Version32 = 0x02010700;
-		public const ulong FileVersion64 = 0x0002001100000000UL;
+		public const uint Version32 = 0x02010800;
+		public const ulong FileVersion64 = 0x0002001200000000UL;
 
 		/// <summary>
 		/// Version, encoded as string.
 		/// </summary>
-		public const string VersionString = "2.17";
+		public const string VersionString = "2.18";
 
-		public const string Copyright = @"Copyright © 2003-2011 Dominik Reichl";
+		public const string Copyright = @"Copyright © 2003-2012 Dominik Reichl";
 
 		/// <summary>
 		/// Product website URL. Terminated by a forward slash.
@@ -79,10 +79,10 @@ namespace KeePassLib
 		public const string TranslationsUrl = "http://keepass.info/translations.html";
 
 		/// <summary>
-		/// URL to an XML file that contains information about the latest KeePass
-		/// available on the website.
+		/// URL to a TXT file (eventually compressed) that contains information
+		/// about the latest KeePass version available on the website.
 		/// </summary>
-		public const string VersionUrl = "http://keepass.info/update/version2.xml.gz";
+		public const string VersionUrl = "http://keepass.info/update/version2x.txt.gz";
 
 		/// <summary>
 		/// URL to the root path of the online KeePass help. Terminated by
diff --git a/KeePassLib/PwDeletedObject.cs b/KeePassLib/PwDeletedObject.cs
index b6cb859..8e12546 100644
--- a/KeePassLib/PwDeletedObject.cs
+++ b/KeePassLib/PwDeletedObject.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/PwEntry.cs b/KeePassLib/PwEntry.cs
index 275218b..51ef0b5 100644
--- a/KeePassLib/PwEntry.cs
+++ b/KeePassLib/PwEntry.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -370,50 +370,87 @@ namespace KeePassLib
 			return peNew;
 		}
 
+		private static PwCompareOptions BuildCmpOpt(bool bIgnoreParentGroup,
+			bool bIgnoreLastMod, bool bIgnoreLastAccess, bool bIgnoreHistory,
+			bool bIgnoreThisLastBackup)
+		{
+			PwCompareOptions pwOpt = PwCompareOptions.None;
+			if(bIgnoreParentGroup) pwOpt |= PwCompareOptions.IgnoreParentGroup;
+			if(bIgnoreLastMod) pwOpt |= PwCompareOptions.IgnoreLastMod;
+			if(bIgnoreLastAccess) pwOpt |= PwCompareOptions.IgnoreLastAccess;
+			if(bIgnoreHistory) pwOpt |= PwCompareOptions.IgnoreHistory;
+			if(bIgnoreThisLastBackup) pwOpt |= PwCompareOptions.IgnoreLastBackup;
+			return pwOpt;
+		}
+
 		[Obsolete]
 		public bool EqualsEntry(PwEntry pe, bool bIgnoreParentGroup, bool bIgnoreLastMod,
 			bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup)
 		{
-			return EqualsEntry(pe, bIgnoreParentGroup, bIgnoreLastMod, bIgnoreLastAccess,
-				bIgnoreHistory, bIgnoreThisLastBackup, MemProtCmpMode.None);
+			return EqualsEntry(pe, BuildCmpOpt(bIgnoreParentGroup, bIgnoreLastMod,
+				bIgnoreLastAccess, bIgnoreHistory, bIgnoreThisLastBackup),
+				MemProtCmpMode.None);
 		}
 
+		[Obsolete]
 		public bool EqualsEntry(PwEntry pe, bool bIgnoreParentGroup, bool bIgnoreLastMod,
 			bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup,
 			MemProtCmpMode mpCmpStr)
 		{
+			return EqualsEntry(pe, BuildCmpOpt(bIgnoreParentGroup, bIgnoreLastMod,
+				bIgnoreLastAccess, bIgnoreHistory, bIgnoreThisLastBackup), mpCmpStr);
+		}
+
+		public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt,
+			MemProtCmpMode mpCmpStr)
+		{
 			if(pe == null) { Debug.Assert(false); return false; }
 
+			bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
+				PwCompareOptions.None);
+			bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) !=
+				PwCompareOptions.None);
+			bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) !=
+				PwCompareOptions.None);
+
 			if(!m_uuid.EqualsValue(pe.m_uuid)) return false;
-			if(!bIgnoreParentGroup)
+			if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None)
 			{
 				if(m_pParentGroup != pe.m_pParentGroup) return false;
 				if(!bIgnoreLastMod && (m_tParentGroupLastMod != pe.m_tParentGroupLastMod))
 					return false;
 			}
 
-			if(!m_listStrings.EqualsDictionary(pe.m_listStrings, mpCmpStr))
+			if(!m_listStrings.EqualsDictionary(pe.m_listStrings, pwOpt, mpCmpStr))
 				return false;
 			if(!m_listBinaries.EqualsDictionary(pe.m_listBinaries)) return false;
 
 			if(!m_listAutoType.Equals(pe.m_listAutoType)) return false;
 
-			if(!bIgnoreHistory)
+			if((pwOpt & PwCompareOptions.IgnoreHistory) == PwCompareOptions.None)
 			{
-				if(!bIgnoreThisLastBackup && (m_listHistory.UCount != pe.m_listHistory.UCount))
+				bool bIgnoreLastBackup = ((pwOpt & PwCompareOptions.IgnoreLastBackup) !=
+					PwCompareOptions.None);
+
+				if(!bIgnoreLastBackup && (m_listHistory.UCount != pe.m_listHistory.UCount))
 					return false;
-				if(bIgnoreThisLastBackup && (m_listHistory.UCount == 0))
+				if(bIgnoreLastBackup && (m_listHistory.UCount == 0))
 				{
 					Debug.Assert(false);
 					return false;
 				}
-				if(bIgnoreThisLastBackup && ((m_listHistory.UCount - 1) != pe.m_listHistory.UCount))
+				if(bIgnoreLastBackup && ((m_listHistory.UCount - 1) != pe.m_listHistory.UCount))
 					return false;
+
+				PwCompareOptions cmpSub = PwCompareOptions.IgnoreParentGroup;
+				if(bNeEqStd) cmpSub |= PwCompareOptions.NullEmptyEquivStd;
+				if(bIgnoreLastMod) cmpSub |= PwCompareOptions.IgnoreLastMod;
+				if(bIgnoreLastAccess) cmpSub |= PwCompareOptions.IgnoreLastAccess;
+
 				for(uint uHist = 0; uHist < pe.m_listHistory.UCount; ++uHist)
 				{
 					if(!m_listHistory.GetAt(uHist).EqualsEntry(pe.m_listHistory.GetAt(
-						uHist), true, bIgnoreLastMod, bIgnoreLastAccess, false, false,
-						MemProtCmpMode.None))
+						uHist), cmpSub, MemProtCmpMode.None))
 						return false;
 				}
 			}
@@ -592,10 +629,14 @@ namespace KeePassLib
 		{
 			if(peData == null) { Debug.Assert(false); return false; }
 
+			PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup |
+				PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd);
+			if(bIgnoreLastMod) cmpOpt |= PwCompareOptions.IgnoreLastMod;
+			if(bIgnoreLastAccess) cmpOpt |= PwCompareOptions.IgnoreLastAccess;
+
 			foreach(PwEntry pe in m_listHistory)
 			{
-				if(pe.EqualsEntry(peData, true, bIgnoreLastMod, bIgnoreLastAccess,
-					true, false, MemProtCmpMode.None)) return true;
+				if(pe.EqualsEntry(peData, cmpOpt, MemProtCmpMode.None)) return true;
 			}
 
 			return false;
diff --git a/KeePassLib/PwEnums.cs b/KeePassLib/PwEnums.cs
index 3336664..5520020 100644
--- a/KeePassLib/PwEnums.cs
+++ b/KeePassLib/PwEnums.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -183,4 +183,25 @@ namespace KeePassLib
 		/// </summary>
 		Full
 	}
+
+	[Flags]
+	public enum PwCompareOptions
+	{
+		None = 0x0,
+
+		/// <summary>
+		/// Empty standard string fields are considered to be the
+		/// same as non-existing standard string fields.
+		/// This doesn't affect custom string comparisons.
+		/// </summary>
+		NullEmptyEquivStd = 0x1,
+
+		IgnoreParentGroup = 0x2,
+		IgnoreLastAccess = 0x4,
+		IgnoreLastMod = 0x8,
+		IgnoreHistory = 0x10,
+		IgnoreLastBackup = 0x20,
+
+		IgnoreTimes = (IgnoreLastAccess | IgnoreLastMod)
+	}
 }
diff --git a/KeePassLib/PwGroup.cs b/KeePassLib/PwGroup.cs
index a4c6f26..6e79590 100644
--- a/KeePassLib/PwGroup.cs
+++ b/KeePassLib/PwGroup.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -640,14 +640,12 @@ namespace KeePassLib
 			EntryHandler eh = delegate(PwEntry pe)
 			{
 				// Enable protection of current string
-				ProtectedString ps = pe.Strings.Get(strFieldName);
-				if(ps != null) ps.EnableProtection(bEnable);
+				pe.Strings.EnableProtection(strFieldName, bEnable);
 
 				// Do the same for all history items
 				foreach(PwEntry peHistory in pe.History)
 				{
-					ProtectedString psHistory = peHistory.Strings.Get(strFieldName);
-					if(psHistory != null) psHistory.EnableProtection(bEnable);
+					peHistory.Strings.EnableProtection(strFieldName, bEnable);
 				}
 
 				return true;
diff --git a/KeePassLib/PwUuid.cs b/KeePassLib/PwUuid.cs
index d5dca04..a507fba 100644
--- a/KeePassLib/PwUuid.cs
+++ b/KeePassLib/PwUuid.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Resources/KLRes.Generated.cs b/KeePassLib/Resources/KLRes.Generated.cs
index c40aa2c..bfa2048 100644
--- a/KeePassLib/Resources/KLRes.Generated.cs
+++ b/KeePassLib/Resources/KLRes.Generated.cs
@@ -34,6 +34,7 @@ namespace KeePassLib.Resources
 			m_strFileCorrupted = TryGetEx(dictNew, "FileCorrupted", m_strFileCorrupted);
 			m_strFileHeaderEndEarly = TryGetEx(dictNew, "FileHeaderEndEarly", m_strFileHeaderEndEarly);
 			m_strFileLoadFailed = TryGetEx(dictNew, "FileLoadFailed", m_strFileLoadFailed);
+			m_strFileLockedWrite = TryGetEx(dictNew, "FileLockedWrite", m_strFileLockedWrite);
 			m_strFileNewVerReq = TryGetEx(dictNew, "FileNewVerReq", m_strFileNewVerReq);
 			m_strFileSaveCorruptionWarning = TryGetEx(dictNew, "FileSaveCorruptionWarning", m_strFileSaveCorruptionWarning);
 			m_strFileSaveFailed = TryGetEx(dictNew, "FileSaveFailed", m_strFileSaveFailed);
@@ -49,6 +50,7 @@ namespace KeePassLib.Resources
 			m_strKeePass1xHint = TryGetEx(dictNew, "KeePass1xHint", m_strKeePass1xHint);
 			m_strMasterSeedLengthInvalid = TryGetEx(dictNew, "MasterSeedLengthInvalid", m_strMasterSeedLengthInvalid);
 			m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat);
+			m_strTryAgainSecs = TryGetEx(dictNew, "TryAgainSecs", m_strTryAgainSecs);
 			m_strUnknownHeaderId = TryGetEx(dictNew, "UnknownHeaderId", m_strUnknownHeaderId);
 			m_strUserAccountKeyError = TryGetEx(dictNew, "UserAccountKeyError", m_strUserAccountKeyError);
 		}
@@ -62,6 +64,7 @@ namespace KeePassLib.Resources
 			"FileCorrupted",
 			"FileHeaderEndEarly",
 			"FileLoadFailed",
+			"FileLockedWrite",
 			"FileNewVerReq",
 			"FileSaveCorruptionWarning",
 			"FileSaveFailed",
@@ -77,6 +80,7 @@ namespace KeePassLib.Resources
 			"KeePass1xHint",
 			"MasterSeedLengthInvalid",
 			"OldFormat",
+			"TryAgainSecs",
 			"UnknownHeaderId",
 			"UserAccountKeyError"
 		};
@@ -174,6 +178,17 @@ namespace KeePassLib.Resources
 			get { return m_strFileLoadFailed; }
 		}
 
+		private static string m_strFileLockedWrite =
+			@"The file is locked, because the following user is currently writing to it:";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'The file is locked, because the following user is currently writing to it:'.
+		/// </summary>
+		public static string FileLockedWrite
+		{
+			get { return m_strFileLockedWrite; }
+		}
+
 		private static string m_strFileNewVerReq =
 			@"A newer KeePass version is required to open this file.";
 		/// <summary>
@@ -339,6 +354,17 @@ namespace KeePassLib.Resources
 			get { return m_strOldFormat; }
 		}
 
+		private static string m_strTryAgainSecs =
+			@"Please try it again in a few seconds.";
+		/// <summary>
+		/// Look up a localized string similar to
+		/// 'Please try it again in a few seconds.'.
+		/// </summary>
+		public static string TryAgainSecs
+		{
+			get { return m_strTryAgainSecs; }
+		}
+
 		private static string m_strUnknownHeaderId =
 			@"Unknown header ID!";
 		/// <summary>
diff --git a/KeePassLib/Security/ProtectedBinary.cs b/KeePassLib/Security/ProtectedBinary.cs
index d830aa1..a86e91d 100644
--- a/KeePassLib/Security/ProtectedBinary.cs
+++ b/KeePassLib/Security/ProtectedBinary.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -32,45 +32,35 @@ namespace KeePassLib.Security
 {
 	/// <summary>
 	/// Represents a protected binary, i.e. a byte array that is encrypted
-	/// in-memory.
+	/// in memory. A <c>ProtectedBinary</c> object is immutable and
+	/// thread-safe.
 	/// </summary>
-	public sealed class ProtectedBinary
+	public sealed class ProtectedBinary : IEquatable<ProtectedBinary>
 	{
+		private const int PmBlockSize = 16;
+
 		// In-memory protection is supported only on Windows 2000 SP3 and
 		// higher.
-		private static bool m_bProtectionSupported = true;
+		private static bool m_bProtectionSupported;
 
-		private byte[] m_pbData = new byte[0]; // Never null
+		private byte[] m_pbData; // Never null
 
 		// The real length of the data. This value can be different than
 		// m_pbData.Length, as the length of m_pbData always is a multiple
-		// of 16 (required for fast in-memory protection).
-		private uint m_uDataLen = 0;
+		// of PmBlockSize (required for fast in-memory protection).
+		private uint m_uDataLen;
 
-		private bool m_bDoProtect = false; // See default constructor.
+		private bool m_bProtected;
 
-		private XorredBuffer m_xbEncrypted = null;
-		
-		/// <summary>
-		/// A flag specifying whether the <c>ProtectedBinary</c> object has turned on
-		/// in-memory protection or not.
-		/// </summary>
-		public bool IsProtected
-		{
-			get { return m_bDoProtect; }
-		}
+		private object m_objSync = new object();
 
 		/// <summary>
-		/// A value specifying whether the <c>ProtectedString</c> object is currently
-		/// in-memory protected or not. This flag can be different than
-		/// <c>IsProtected</c>: if a <c>XorredBuffer</c> is used, the <c>IsProtected</c>
-		/// flag represents the memory protection flag, but not the actual protection.
-		/// In this case use <c>IsViewable</c>, which returns <c>true</c> if a
-		/// <c>XorredBuffer</c> is currently in use.
+		/// A flag specifying whether the <c>ProtectedBinary</c> object has
+		/// turned on in-memory protection or not.
 		/// </summary>
-		public bool IsViewable
+		public bool IsProtected
 		{
-			get { return (!m_bDoProtect && (m_xbEncrypted == null)); }
+			get { return m_bProtected; }
 		}
 
 		/// <summary>
@@ -78,19 +68,16 @@ namespace KeePassLib.Security
 		/// </summary>
 		public uint Length
 		{
-			get
-			{
-				if(m_xbEncrypted != null) return m_xbEncrypted.Length;
-				return m_uDataLen;
-			}
+			get { return m_uDataLen; }
 		}
 
 		static ProtectedBinary()
 		{
-			try // Test if ProtectedMemory is supported
+			try // Test whether ProtectedMemory is supported
 			{
-				byte[] pbDummy = new byte[128];
+				byte[] pbDummy = new byte[PmBlockSize * 2];
 				ProtectedMemory.Protect(pbDummy, MemoryProtectionScope.SameProcess);
+				m_bProtectionSupported = true;
 			}
 			catch(Exception) // Windows 98 / ME
 			{
@@ -100,57 +87,26 @@ namespace KeePassLib.Security
 
 		/// <summary>
 		/// Construct a new, empty protected binary data object. Protection
-		/// is disabled by default! You need to call the
-		/// <c>EnableProtection</c> member function to enable the protection
-		/// manually, if you wish the data to be protected.
+		/// is disabled.
 		/// </summary>
 		public ProtectedBinary()
 		{
-		}
-
-		/// <summary>
-		/// Construct a new, empty protected binary data object.
-		/// </summary>
-		/// <param name="bEnableProtection">If this parameter is <c>true</c>,
-		/// the data will be encrypted in-memory. If it is <c>false</c>, the
-		/// data is stored in plain-text in the process memory.</param>
-		public ProtectedBinary(bool bEnableProtection)
-		{
-			m_bDoProtect = bEnableProtection;
+			Init(false, new byte[0]);
 		}
 
 		/// <summary>
 		/// Construct a new protected binary data object.
 		/// </summary>
 		/// <param name="bEnableProtection">If this paremeter is <c>true</c>,
-		/// the data will be encrypted in-memory. If it is <c>false</c>, the
+		/// the data will be encrypted in memory. If it is <c>false</c>, the
 		/// data is stored in plain-text in the process memory.</param>
-		/// <param name="pbInitialValue">Initial value of the protected
-		/// object. The input parameter is not modified.</param>
-		public ProtectedBinary(bool bEnableProtection, byte[] pbInitialValue)
-		{
-			m_bDoProtect = bEnableProtection;
-			SetData(pbInitialValue);
-		}
-
-		/// <summary>
-		/// Construct a new protected binary data object. Copy the data from
-		/// an existing object.
-		/// </summary>
-		/// <param name="pbTemplate">Existing <c>ProtectedBinary</c> object,
-		/// which is used to initialize the new object. This parameter must
-		/// not be <c>null</c>.</param>
-		/// <exception cref="System.ArgumentNullException">Thrown if the input
-		/// parameter is <c>null</c>.</exception>
-		public ProtectedBinary(ProtectedBinary pbTemplate)
+		/// <param name="pbData">Value of the protected object.
+		/// The input parameter is not modified and
+		/// <c>ProtectedBinary</c> doesn't take ownership of the data,
+		/// i.e. the caller is responsible for clearing it.</param>
+		public ProtectedBinary(bool bEnableProtection, byte[] pbData)
 		{
-			Debug.Assert(pbTemplate != null); if(pbTemplate == null) throw new ArgumentNullException("pbTemplate");
-
-			m_bDoProtect = pbTemplate.m_bDoProtect;
-
-			byte[] pbBuf = pbTemplate.ReadData();
-			SetData(pbBuf);
-			MemUtil.ZeroByteArray(pbBuf);
+			Init(bEnableProtection, pbData);
 		}
 
 		/// <summary>
@@ -166,134 +122,61 @@ namespace KeePassLib.Security
 		{
 			Debug.Assert(xbProtected != null); if(xbProtected == null) throw new ArgumentNullException("xbProtected");
 
-			m_bDoProtect = bEnableProtection;
-			m_xbEncrypted = xbProtected;
-		}
-
-		/// <summary>
-		/// Clear the protected data object. Doesn't change the protection level.
-		/// </summary>
-		public void Clear()
-		{
-			m_pbData = new byte[0];
-			m_uDataLen = 0;
-
-			m_xbEncrypted = null;
-		}
-
-		/// <summary>
-		/// Change the protection level (protect or don't protect). Note: you
-		/// only need to call this function if you really want to change the
-		/// protection. If you specified the protection flag in the constructor,
-		/// and don't want to change it, you don't need to call this function.
-		/// </summary>
-		/// <param name="bEnableProtection">If <c>true</c>, the data will be protected
-		/// (encrypted in-memory). Otherwise the data will be stored in
-		/// plain-text in the process memory.</param>
-		public void EnableProtection(bool bEnableProtection)
-		{
-			if(m_xbEncrypted != null)
-			{
-				m_bDoProtect = bEnableProtection;
-				return;
-			}
-
-			if(m_bDoProtect && !bEnableProtection) // Unprotect
-			{
-				byte[] pb = ReadData();
-				Debug.Assert(pb.Length == m_uDataLen);
-
-				Clear();
-
-				m_pbData = pb;
-				m_bDoProtect = false;
-			}
-			else if(!m_bDoProtect && bEnableProtection) // Protect
-			{
-				m_bDoProtect = true;
-				SetData(m_pbData);
-			}
+			byte[] pb = xbProtected.ReadPlainText();
+			Init(bEnableProtection, pb);
+			MemUtil.ZeroByteArray(pb);
 		}
 
-		/// <summary>
-		/// Set protected data. This function also clears the internal
-		/// <c>XorredBuffer</c> object.
-		/// </summary>
-		/// <param name="pbNew">Data to store in the protected object. The input
-		/// byte array will not be modified, the data is copied to an internal
-		/// buffer of the protected object. This parameter must not be <c>null</c>;
-		/// if you want to clear the object, call the <c>Clear</c> member
-		/// function.</param>
-		/// <exception cref="System.ArgumentNullException">Thrown if the input
-		/// parameter is <c>null</c>.</exception>
-		public void SetData(byte[] pbNew)
+		private void Init(bool bEnableProtection, byte[] pbData)
 		{
-			Debug.Assert(pbNew != null);
-			if(pbNew == null) throw new ArgumentNullException("pbNew");
+			if(pbData == null) throw new ArgumentNullException("pbData");
 
-			// Clear();
-			m_xbEncrypted = null;
+			m_bProtected = bEnableProtection;
+			m_uDataLen = (uint)pbData.Length;
 
-			m_uDataLen = (uint)pbNew.Length;
+			int nBlocks = (int)m_uDataLen / PmBlockSize;
+			if((nBlocks * PmBlockSize) < (int)m_uDataLen) ++nBlocks;
+			Debug.Assert((nBlocks * PmBlockSize) >= (int)m_uDataLen);
 
-			if(m_bDoProtect && m_bProtectionSupported)
-			{
-				int nAllocatedMem = (((int)m_uDataLen / 16) + 1) * 16;
-				m_pbData = new byte[nAllocatedMem];
-				Array.Clear(m_pbData, nAllocatedMem - 16, 16); // Clear the rest
-				Array.Copy(pbNew, m_pbData, (int)m_uDataLen);
+			m_pbData = new byte[nBlocks * PmBlockSize];
+			Array.Copy(pbData, m_pbData, (int)m_uDataLen);
 
+			// Data size must be > 0, otherwise 'Protect' throws
+			if(m_bProtected && m_bProtectionSupported && (m_uDataLen > 0))
 				ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
-			}
-			else // !m_bDoProtect
-			{
-				m_pbData = new byte[m_uDataLen];
-				pbNew.CopyTo(m_pbData, 0);
-			}
 		}
 
 		/// <summary>
-		/// Get the protected data as a byte array. Please note that the returned
-		/// byte array is not protected and can therefore been read by any other
-		/// applications. Make sure that your clear it properly after usage.
+		/// Get a copy of the protected data as a byte array.
+		/// Please note that the returned byte array is not protected and
+		/// can therefore been read by any other application.
+		/// Make sure that your clear it properly after usage.
 		/// </summary>
 		/// <returns>Unprotected byte array. This is always a copy of the internal
 		/// protected data and can therefore be cleared safely.</returns>
 		public byte[] ReadData()
 		{
-			if(m_xbEncrypted != null)
-			{
-				byte[] pb = m_xbEncrypted.ReadPlainText();
-				SetData(pb); // Clear the XorredBuffer object
-
-				return (pb ?? new byte[0]); // pb is writable, because XB is now invalid
-			}
+			if(m_uDataLen == 0) return new byte[0];
 
-			if(m_pbData.Length == 0) return new byte[0];
+			byte[] pbReturn = new byte[m_uDataLen];
 
-			if(m_bDoProtect && m_bProtectionSupported)
+			if(m_bProtected && m_bProtectionSupported)
 			{
-				Debug.Assert((m_pbData.Length % 16) == 0);
-				ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess);
+				lock(m_objSync)
+				{
+					ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess);
+					Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
+					ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
+				}
 			}
-
-			byte[] pbReturn = new byte[m_uDataLen];
-			if(m_uDataLen > 0) Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
-
-			if(m_bDoProtect && m_bProtectionSupported)
-				ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
+			else Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
 
 			return pbReturn;
 		}
 
 		/// <summary>
 		/// Read the protected data and return it protected with a sequence
-		/// of bytes generated by a random stream. The object's data will be
-		/// invisible in process memory only if the object has been initialized
-		/// using a <c>XorredBuffer</c>. If no <c>XorredBuffer</c> has been used
-		/// or the binary has been read once already (in plain-text), the
-		/// operation won't be secure and the protected string will be visible
-		/// in process memory.
+		/// of bytes generated by a random stream.
 		/// </summary>
 		/// <param name="crsRandomSource">Random number source.</param>
 		/// <returns>Protected data.</returns>
@@ -304,61 +187,55 @@ namespace KeePassLib.Security
 			Debug.Assert(crsRandomSource != null);
 			if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
 
-			if(m_xbEncrypted != null)
-			{
-				uint uLen = m_xbEncrypted.Length;
-				byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
-				return m_xbEncrypted.ChangeKey(randomPad);
-			}
-			else
-			{
-				byte[] pbData = ReadData();
-				uint uLen = (uint)pbData.Length;
+			byte[] pbData = ReadData();
+			uint uLen = (uint)pbData.Length;
 
-				byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
-				Debug.Assert(randomPad.Length == uLen);
+			byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
+			Debug.Assert(randomPad.Length == uLen);
 
-				for(uint i = 0; i < uLen; ++i)
-					pbData[i] ^= randomPad[i];
+			for(uint i = 0; i < uLen; ++i)
+				pbData[i] ^= randomPad[i];
 
-				return pbData;
-			}
+			return pbData;
 		}
 
-		public bool EqualsValue(ProtectedBinary pb)
+		public override int GetHashCode()
 		{
-			if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); }
+			int h = (m_bProtected ? 0x7B11D289 : 0);
 
-			if((pb.m_xbEncrypted != null) && (m_xbEncrypted != null))
-				return pb.m_xbEncrypted.EqualsValue(m_xbEncrypted);
-			if((pb.m_xbEncrypted != null) && (m_xbEncrypted == null))
+			byte[] pb = ReadData();
+			unchecked
 			{
-				if(pb.m_xbEncrypted.Length != m_uDataLen) return false;
-
-				byte[] pbThis = ReadData();
-				bool bEqThis = pb.m_xbEncrypted.EqualsValue(pbThis);
-				MemUtil.ZeroByteArray(pbThis);
-				return bEqThis;
+				for(int i = 0; i < pb.Length; ++i)
+					h = (h << 3) + h + (int)pb[i];
 			}
-			if((pb.m_xbEncrypted == null) && (m_xbEncrypted != null))
-			{
-				if(m_xbEncrypted.Length != pb.m_uDataLen) return false;
+			MemUtil.ZeroByteArray(pb);
 
-				byte[] pbOther = pb.ReadData();
-				bool bEqOther = m_xbEncrypted.EqualsValue(pbOther);
-				MemUtil.ZeroByteArray(pbOther);
-				return bEqOther;
-			}
+			return h;
+		}
 
-			// (pb.m_xbEncrypted == null) && (m_xbEncrypted == null)
+		public override bool Equals(object obj)
+		{
+			return Equals(obj as ProtectedBinary);
+		}
 
-			if(m_uDataLen != pb.m_uDataLen) return false;
+		public bool Equals(ProtectedBinary other)
+		{
+			if(other == null) return false; // No assert
+
+			if(m_bProtected != other.m_bProtected) return false;
+			if(m_uDataLen != other.m_uDataLen) return false;
 
 			byte[] pbL = ReadData();
-			byte[] pbR = pb.ReadData();
+			byte[] pbR = other.ReadData();
 			bool bEq = MemUtil.ArraysEqual(pbL, pbR);
 			MemUtil.ZeroByteArray(pbL);
 			MemUtil.ZeroByteArray(pbR);
+
+#if DEBUG
+			if(bEq) { Debug.Assert(GetHashCode() == other.GetHashCode()); }
+#endif
+
 			return bEq;
 		}
 	}
diff --git a/KeePassLib/Security/ProtectedString.cs b/KeePassLib/Security/ProtectedString.cs
index 2cee9b6..a82ec2b 100644
--- a/KeePassLib/Security/ProtectedString.cs
+++ b/KeePassLib/Security/ProtectedString.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -18,10 +18,8 @@
 */
 
 using System;
-using System.Security;
 using System.Text;
 using System.Diagnostics;
-using System.Runtime.InteropServices;
 
 using KeePassLib.Cryptography;
 using KeePassLib.Utility;
@@ -30,118 +28,83 @@ using KeePassLib.Utility;
 using KeePassLibSD;
 #endif
 
+// SecureString objects are limited to 65536 characters, don't use
+
 namespace KeePassLib.Security
 {
 	/// <summary>
 	/// Represents an in-memory encrypted string.
+	/// <c>ProtectedString</c> objects are immutable and thread-safe.
 	/// </summary>
-#if !KeePassLibSD
+#if (DEBUG && !KeePassLibSD)
 	[DebuggerDisplay(@"{ReadString()}")]
 #endif
 	public sealed class ProtectedString
 	{
-		// SecureString objects are supported only on Windows 2000 SP3 and
-		// higher. On all other systems (98 / ME) we use a standard string
-		// object instead of the secure one. This of course decreases the
-		// security of the class, but at least allows the application
-		// to run on older systems, too.
-		private SecureString m_secString = null; // Created in constructor
-		private string m_strAlternativeSecString = string.Empty;
-
-		private string m_strPlainText = string.Empty; // Never null
-		private bool m_bIsProtected = false; // See default constructor
+		// Exactly one of the following will be non-null
+		private ProtectedBinary m_pbUtf8 = null;
+		private string m_strPlainText = null;
 
-		private XorredBuffer m_xbEncrypted = null; // UTF-8 representation
+		private bool m_bIsProtected;
 
-		/// <summary>
-		/// A flag specifying whether the <c>ProtectedString</c> object has turned on
-		/// in-memory protection or not.
-		/// </summary>
-		public bool IsProtected
+		private static ProtectedString m_psEmpty = new ProtectedString();
+		public static ProtectedString Empty
 		{
-			get { return m_bIsProtected; }
+			get { return m_psEmpty; }
 		}
 
 		/// <summary>
-		/// A value specifying whether the <c>ProtectedString</c> object is currently
-		/// in-memory protected or not. This flag can be different than
-		/// <c>IsProtected</c>: if a <c>XorredBuffer</c> is used, the <c>IsProtected</c>
-		/// flag represents the memory protection flag, but not the actual protection.
-		/// In this case use <c>IsViewable</c>, which returns <c>true</c> if a
-		/// <c>XorredBuffer</c> is currently in use.
+		/// A flag specifying whether the <c>ProtectedString</c> object
+		/// has turned on in-memory protection or not.
 		/// </summary>
-		public bool IsViewable
+		public bool IsProtected
 		{
-			get { return (!m_bIsProtected && (m_xbEncrypted == null)); }
+			get { return m_bIsProtected; }
 		}
 
 		public bool IsEmpty
 		{
 			get
 			{
-				if(m_xbEncrypted != null) return (m_xbEncrypted.Length == 0);
-
-				if(m_bIsProtected)
-				{
-					if(m_secString != null) return (m_secString.Length == 0);
-					else return (m_strAlternativeSecString.Length == 0);
-				}
+				ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
+				if(pBin != null) return (pBin.Length == 0);
 
+				Debug.Assert(m_strPlainText != null);
 				return (m_strPlainText.Length == 0);
 			}
 		}
 
+		private int m_nCachedLength = -1;
 		public int Length
 		{
 			get
 			{
-				if(m_xbEncrypted != null)
-				{
-					byte[] pb = m_xbEncrypted.ReadPlainText();
-
-					string str = StrUtil.Utf8.GetString(pb, 0, pb.Length);
-					SetString(str); // Clear the XorredBuffer object
+				if(m_nCachedLength >= 0) return m_nCachedLength;
 
-					// No need to erase the pb buffer, the plain text is
-					// now readable in memory anyway (in str).
-
-					return ((str != null) ? str.Length : 0);
+				ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
+				if(pBin != null)
+				{
+					byte[] pbPlain = pBin.ReadData();
+					m_nCachedLength = StrUtil.Utf8.GetCharCount(pbPlain);
+					MemUtil.ZeroByteArray(pbPlain);
 				}
-
-				if(m_bIsProtected)
+				else
 				{
-					if(m_secString != null) return m_secString.Length;
-					else return m_strAlternativeSecString.Length;
+					Debug.Assert(m_strPlainText != null);
+					m_nCachedLength = m_strPlainText.Length;
 				}
-				
-				return m_strPlainText.Length; // Unprotected string
+
+				return m_nCachedLength;
 			}
 		}
 
 		/// <summary>
 		/// Construct a new protected string object. Protection is
-		/// disabled by default! You need to call the
-		/// <c>EnableProtection</c> member function in order to
-		/// enable the protection, if you wish the string to be protected.
+		/// disabled.
 		/// </summary>
 		public ProtectedString()
 		{
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
-		}
-
-		/// <summary>
-		/// Construct a new in-memory encrypted string object.
-		/// </summary>
-		/// <param name="bEnableProtection">If this parameter is <c>true</c>,
-		/// the string will be protected in-memory (encrypted). If it
-		/// is <c>false</c>, the string will be stored as plain-text.</param>
-		public ProtectedString(bool bEnableProtection)
-		{
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
-
-			m_bIsProtected = bEnableProtection;
+			Init(false, string.Empty);
 		}
 
 		/// <summary>
@@ -155,11 +118,7 @@ namespace KeePassLib.Security
 		/// parameter won't be modified.</param>
 		public ProtectedString(bool bEnableProtection, string strValue)
 		{
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
-
-			m_bIsProtected = bEnableProtection;
-			SetString(strValue);
+			Init(bEnableProtection, strValue);
 		}
 
 		/// <summary>
@@ -170,36 +129,11 @@ namespace KeePassLib.Security
 		/// the string will be protected in-memory (encrypted). If it
 		/// is <c>false</c>, the string will be stored as plain-text.</param>
 		/// <param name="vUtf8Value">The initial string value, encoded as
-		/// UTF-8 byte array. This parameter won't be modified.</param>
+		/// UTF-8 byte array. This parameter won't be modified; the caller
+		/// is responsible for clearing it.</param>
 		public ProtectedString(bool bEnableProtection, byte[] vUtf8Value)
 		{
-			if(vUtf8Value == null) throw new ArgumentNullException("vUtf8Value");
-
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
-
-			m_bIsProtected = bEnableProtection;
-			SetString(StrUtil.Utf8.GetString(vUtf8Value, 0, vUtf8Value.Length));
-		}
-
-		/// <summary>
-		/// Construct a new protected string. The string is initialized
-		/// to the value passed in the <c>pbTemplate</c> protected string.
-		/// </summary>
-		/// <param name="psTemplate">The initial string value. This
-		/// parameter won't be modified. Must not be <c>null</c>.</param>
-		/// <exception cref="System.ArgumentNullException">Thrown if the input
-		/// parameter is <c>null</c>.</exception>
-		public ProtectedString(ProtectedString psTemplate)
-		{
-			Debug.Assert(psTemplate != null);
-			if(psTemplate == null) throw new ArgumentNullException("psTemplate");
-
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
-
-			m_bIsProtected = psTemplate.m_bIsProtected;
-			SetString(psTemplate.ReadString());
+			Init(bEnableProtection, vUtf8Value);
 		}
 
 		/// <summary>
@@ -214,141 +148,58 @@ namespace KeePassLib.Security
 		/// parameter is <c>null</c>.</exception>
 		public ProtectedString(bool bEnableProtection, XorredBuffer xbProtected)
 		{
-			Debug.Assert(xbProtected != null);
 			if(xbProtected == null) throw new ArgumentNullException("xbProtected");
 
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
-
-			m_bIsProtected = bEnableProtection;
-			m_xbEncrypted = xbProtected;
-		}
-
-		/// <summary>
-		/// Clear the string. Doesn't change the protection level.
-		/// </summary>
-		public void Clear()
-		{
-			if(m_secString != null) m_secString.Clear();
-			else m_strAlternativeSecString = string.Empty;
-
-			m_strPlainText = string.Empty;
-
-			m_xbEncrypted = null;
+			byte[] pb = xbProtected.ReadPlainText();
+			Init(bEnableProtection, pb);
+			MemUtil.ZeroByteArray(pb);
 		}
 
-		/// <summary>
-		/// Change the protection level (protect or don't protect). Note: you
-		/// only need to call this function if you really want to change the
-		/// protection. If you specified the protection flag in the constructor,
-		/// and don't want to change it, you don't need to call this function.
-		/// </summary>
-		/// <param name="bProtect">If <c>true</c>, the string will be protected
-		/// (encrypted in-memory). Otherwise the string will be stored in
-		/// plain-text in the process memory.</param>
-		public void EnableProtection(bool bProtect)
+		private void Init(bool bEnableProtection, string str)
 		{
-			if(m_xbEncrypted != null)
-			{
-				m_bIsProtected = bProtect;
-				return;
-			}
-
-			if(m_bIsProtected && !bProtect) // Unprotect
-			{
-				string strPlainText = ReadString();
+			if(str == null) throw new ArgumentNullException("str");
 
-				Clear();
-
-				m_strPlainText = strPlainText;
-				m_bIsProtected = false;
-			}
-			else if(!m_bIsProtected && bProtect) // Protect
-			{
-				m_bIsProtected = true;
+			m_bIsProtected = bEnableProtection;
 
-				SetString(m_strPlainText);
-			}
+			// The string already is in memory and immutable,
+			// protection would be useless
+			m_strPlainText = str;
 		}
 
-		/// <summary>
-		/// Assign a new string value to the object.
-		/// </summary>
-		/// <param name="strNewValue">New string. The string must not contain
-		/// a <c>null</c> terminator.</param>
-		/// <exception cref="System.ArgumentNullException">Thrown if the input
-		/// parameter is <c>null</c>.</exception>
-		/// <exception cref="System.ArgumentException">Thrown if the new string
-		/// contains a <c>null</c> terminator.</exception>
-		public void SetString(string strNewValue)
+		private void Init(bool bEnableProtection, byte[] pbUtf8)
 		{
-			Clear();
+			if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8");
 
-			Debug.Assert(strNewValue != null); if(strNewValue == null) throw new ArgumentNullException("strNewValue");
-
-			// String must not contain any null character
-			Debug.Assert(strNewValue.IndexOf((char)0) < 0);
+			m_bIsProtected = bEnableProtection;
 
-			if(m_bIsProtected)
-			{
-				if(m_secString != null)
-				{
-					char ch;
-					for(int i = 0; i < strNewValue.Length; ++i)
-					{
-						ch = strNewValue[i];
-						if(ch == 0) throw new ArgumentException();
-
-						m_secString.AppendChar(ch);
-					}
-				}
-				else m_strAlternativeSecString = strNewValue;
-			}
-			else // Currently not protected
-			{
-				m_strPlainText = strNewValue;
-			}
+			if(bEnableProtection)
+				m_pbUtf8 = new ProtectedBinary(true, pbUtf8);
+			else
+				m_strPlainText = StrUtil.Utf8.GetString(pbUtf8, 0, pbUtf8.Length);
 		}
 
 		/// <summary>
 		/// Convert the protected string to a normal string object.
 		/// Be careful with this function, the returned string object
-		/// isn't protected any more and stored in plain-text in the
+		/// isn't protected anymore and stored in plain-text in the
 		/// process memory.
 		/// </summary>
 		/// <returns>Plain-text string. Is never <c>null</c>.</returns>
 		public string ReadString()
 		{
-			if(m_xbEncrypted != null)
-			{
-				byte[] pb = m_xbEncrypted.ReadPlainText();
+			if(m_strPlainText != null) return m_strPlainText;
 
-				string str = StrUtil.Utf8.GetString(pb, 0, pb.Length);
-				SetString(str); // Clear the XorredBuffer object
+			byte[] pb = ReadUtf8();
+			string str = ((pb.Length == 0) ? string.Empty :
+				StrUtil.Utf8.GetString(pb, 0, pb.Length));
+			// No need to clear pb
 
-				// No need to erase the pb buffer, the plain text is
-				// now readable in memory anyway (in str).
+			// As the text is now visible in process memory anyway,
+			// there's no need to protect it anymore
+			m_strPlainText = str;
+			m_pbUtf8 = null; // Thread-safe order
 
-				return (str ?? string.Empty);
-			}
-
-			if(m_bIsProtected)
-			{
-				if(m_secString != null)
-				{
-#if !KeePassLibSD
-					IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString);
-					string str = Marshal.PtrToStringUni(p);
-					Marshal.ZeroFreeGlobalAllocUnicode(p);
-#else
-					string str = m_secString.ReadAsString();
-#endif
-					return (str ?? string.Empty);
-				}
-				else return m_strAlternativeSecString;
-			}
-			
-			return m_strPlainText; // Unprotected string
+			return str;
 		}
 
 		/// <summary>
@@ -359,50 +210,15 @@ namespace KeePassLib.Security
 		/// <returns>Plain-text UTF-8 byte array.</returns>
 		public byte[] ReadUtf8()
 		{
-			if(m_xbEncrypted != null)
-			{
-				byte[] pb = m_xbEncrypted.ReadPlainText();
-
-				// Clear XorredBuffer
-				SetString(StrUtil.Utf8.GetString(pb, 0, pb.Length));
-
-				return pb;
-			}
+			ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
+			if(pBin != null) return pBin.ReadData();
 
-			if(m_bIsProtected)
-			{
-				if(m_secString != null)
-				{
-#if !KeePassLibSD
-					Debug.Assert(sizeof(char) == 2);
-					char[] vChars = new char[m_secString.Length];
-
-					IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString);
-					for(int i = 0; i < vChars.Length; ++i)
-						vChars[i] = (char)Marshal.ReadInt16(p, i * 2);
-					Marshal.ZeroFreeGlobalAllocUnicode(p);
-
-					byte[] pb = StrUtil.Utf8.GetBytes(vChars, 0, vChars.Length);
-					Array.Clear(vChars, 0, vChars.Length);
-#else
-					byte[] pb = StrUtil.Utf8.GetBytes(m_secString.ReadAsString());
-#endif
-					return pb;
-				}
-				else return StrUtil.Utf8.GetBytes(m_strAlternativeSecString);
-			}
-
-			return StrUtil.Utf8.GetBytes(m_strPlainText); // Unprotected string
+			return StrUtil.Utf8.GetBytes(m_strPlainText);
 		}
 
 		/// <summary>
 		/// Read the protected string and return it protected with a sequence
-		/// of bytes generated by a random stream. The object's data will be
-		/// invisible in process memory only if the object has been initialized
-		/// using a <c>XorredBuffer</c>. If no <c>XorredBuffer</c> has been used
-		/// or the string has been read once already (in plain-text), the
-		/// operation won't be secure and the protected string will be visible
-		/// in process memory.
+		/// of bytes generated by a random stream.
 		/// </summary>
 		/// <param name="crsRandomSource">Random number source.</param>
 		/// <returns>Protected string.</returns>
@@ -412,25 +228,26 @@ namespace KeePassLib.Security
 		{
 			Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
 
-			if(m_xbEncrypted != null)
-			{
-				uint uLen = m_xbEncrypted.Length;
-				byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
-				return m_xbEncrypted.ChangeKey(randomPad);
-			}
-			else // Not using XorredBuffer
-			{
-				byte[] pbData = ReadUtf8();
-				uint uLen = (uint)pbData.Length;
+			byte[] pbData = ReadUtf8();
+			uint uLen = (uint)pbData.Length;
 
-				byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
-				Debug.Assert(randomPad.Length == uLen);
+			byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
+			Debug.Assert(randomPad.Length == uLen);
 
-				for(uint i = 0; i < uLen; ++i)
-					pbData[i] ^= randomPad[i];
+			for(uint i = 0; i < uLen; ++i)
+				pbData[i] ^= randomPad[i];
 
-				return pbData;
-			}
+			return pbData;
+		}
+
+		public ProtectedString WithProtection(bool bProtect)
+		{
+			if(bProtect == m_bIsProtected) return this;
+
+			byte[] pb = ReadUtf8();
+			ProtectedString ps = new ProtectedString(bProtect, pb);
+			MemUtil.ZeroByteArray(pb);
+			return ps;
 		}
 	}
 }
diff --git a/KeePassLib/Security/XorredBuffer.cs b/KeePassLib/Security/XorredBuffer.cs
index 3b16d96..2073dc3 100644
--- a/KeePassLib/Security/XorredBuffer.cs
+++ b/KeePassLib/Security/XorredBuffer.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -24,13 +24,13 @@ namespace KeePassLib.Security
 {
 	/// <summary>
 	/// Represents an object that is encrypted using a XOR pad until
-	/// it is read. The key XOR pad can be changed without revealing the
-	/// protected data in process memory.
+	/// it is read. <c>XorredBuffer</c> objects are immutable and
+	/// thread-safe.
 	/// </summary>
 	public sealed class XorredBuffer
 	{
-		private byte[] m_pbData = new byte[0]; // Never null
-		private byte[] m_pbXorPad = new byte[0]; // Never null
+		private byte[] m_pbData; // Never null
+		private byte[] m_pbXorPad; // Always valid for m_pbData
 
 		/// <summary>
 		/// Length of the protected data in bytes.
@@ -45,18 +45,20 @@ namespace KeePassLib.Security
 		/// and a XOR pad that decrypts the protected data. The
 		/// <paramref name="pbProtectedData" /> byte array must have the same size
 		/// as the <paramref name="pbXorPad" /> byte array.
+		/// The <c>XorredBuffer</c> object takes ownership of the two byte
+		/// arrays, i.e. the caller must not use or modify them afterwards.
 		/// </summary>
 		/// <param name="pbProtectedData">Protected data (XOR pad applied).</param>
-		/// <param name="pbXorPad">XOR pad that is used to decrypt the
-		/// <paramref name="pbData" /> parameter.</param>
+		/// <param name="pbXorPad">XOR pad that can be used to decrypt the
+		/// <paramref name="pbProtectedData" /> parameter.</param>
 		/// <exception cref="System.ArgumentNullException">Thrown if one of the input
 		/// parameters is <c>null</c>.</exception>
 		/// <exception cref="System.ArgumentException">Thrown if the byte arrays are
 		/// of different size.</exception>
 		public XorredBuffer(byte[] pbProtectedData, byte[] pbXorPad)
 		{
-			Debug.Assert(pbProtectedData != null); if(pbProtectedData == null) throw new ArgumentNullException("pbProtectedData");
-			Debug.Assert(pbXorPad != null); if(pbXorPad == null) throw new ArgumentNullException("pbXorPad");
+			if(pbProtectedData == null) { Debug.Assert(false); throw new ArgumentNullException("pbProtectedData"); }
+			if(pbXorPad == null) { Debug.Assert(false); throw new ArgumentNullException("pbXorPad"); }
 
 			Debug.Assert(pbProtectedData.Length == pbXorPad.Length);
 			if(pbProtectedData.Length != pbXorPad.Length) throw new ArgumentException();
@@ -65,82 +67,31 @@ namespace KeePassLib.Security
 			m_pbXorPad = pbXorPad;
 		}
 
-		private void Decrypt()
-		{
-			Debug.Assert((m_pbData.Length == m_pbXorPad.Length) || (m_pbXorPad.Length == 0));
-
-			if(m_pbData.Length == m_pbXorPad.Length)
-			{
-				for(int i = 0; i < m_pbData.Length; ++i)
-					m_pbData[i] ^= m_pbXorPad[i];
-
-				m_pbXorPad = new byte[0];
-			}
-		}
-
 		/// <summary>
-		/// Decrypt the buffer. The <c>XorredBuffer</c> protection is useless
-		/// after you used this method. The object cannot be re-encrypted.
+		/// Get a copy of the plain-text. The caller is responsible
+		/// for clearing the byte array safely after using it.
 		/// </summary>
 		/// <returns>Unprotected plain-text byte array.</returns>
 		public byte[] ReadPlainText()
 		{
-			Decrypt();
-			return m_pbData;
-		}
+			byte[] pbPlain = new byte[m_pbData.Length];
 
-		/// <summary>
-		/// Change the protection key for this <c>XorredBuffer</c> object.
-		/// The data will first be decrypted using the old key and then
-		/// re-encrypted using the new key. This operation doesn't reveal
-		/// the plain-text in the process memory.
-		/// </summary>
-		/// <param name="pbNewXorPad">New protection pad. Must contain exactly
-		/// the same number of bytes as the length of the currently protected data.
-		/// Use the <c>Length</c> property of the <c>XorredBuffer</c> to query
-		/// the data length and pass a correct number of bytes to <c>ChangeKey</c>.</param>
-		/// <returns>New protected data (encrypted using the new XOR pad).</returns>
-		/// <exception cref="System.ArgumentNullException">Thrown if the input
-		/// parameter is <c>null</c>.</exception>
-		/// <exception cref="System.ArgumentException">Thrown if the input
-		/// byte array doesn't have the correct size.</exception>
-		public byte[] ChangeKey(byte[] pbNewXorPad)
-		{
-			Debug.Assert(pbNewXorPad != null); if(pbNewXorPad == null) throw new ArgumentNullException("pbNewXorPad");
-
-			Debug.Assert(pbNewXorPad.Length == m_pbData.Length);
-			if(pbNewXorPad.Length != m_pbData.Length) throw new ArgumentException();
+			for(int i = 0; i < pbPlain.Length; ++i)
+				pbPlain[i] = (byte)(m_pbData[i] ^ m_pbXorPad[i]);
 
-			if(m_pbXorPad.Length == m_pbData.Length) // Data is protected
-			{
-				for(int i = 0; i < m_pbData.Length; ++i)
-					m_pbData[i] ^= (byte)(m_pbXorPad[i] ^ pbNewXorPad[i]);
-			}
-			else // Data is unprotected
-			{
-				for(int i = 0; i < m_pbData.Length; ++i)
-					m_pbData[i] ^= pbNewXorPad[i];
-			}
-
-			m_pbXorPad = pbNewXorPad;
-			return m_pbData;
+			return pbPlain;
 		}
 
-		public bool EqualsValue(XorredBuffer xb)
+		/* public bool EqualsValue(XorredBuffer xb)
 		{
 			if(xb == null) { Debug.Assert(false); throw new ArgumentNullException("xb"); }
 
 			if(xb.m_pbData.Length != m_pbData.Length) return false;
 
-			bool bDecThis = (m_pbData.Length == m_pbXorPad.Length);
-			bool bDecOther = (xb.m_pbData.Length == xb.m_pbXorPad.Length);
 			for(int i = 0; i < m_pbData.Length; ++i)
 			{
-				byte bt1 = m_pbData[i];
-				if(bDecThis) bt1 ^= m_pbXorPad[i];
-
-				byte bt2 = xb.m_pbData[i];
-				if(bDecOther) bt2 ^= xb.m_pbXorPad[i];
+				byte bt1 = (byte)(m_pbData[i] ^ m_pbXorPad[i]);
+				byte bt2 = (byte)(xb.m_pbData[i] ^ xb.m_pbXorPad[i]);
 
 				if(bt1 != bt2) return false;
 			}
@@ -154,43 +105,12 @@ namespace KeePassLib.Security
 
 			if(pb.Length != m_pbData.Length) return false;
 
-			if(m_pbData.Length == m_pbXorPad.Length)
-			{
-				for(int i = 0; i < m_pbData.Length; ++i)
-				{
-					if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false;
-				}
-				return true;
-			}
-
 			for(int i = 0; i < m_pbData.Length; ++i)
 			{
-				if(m_pbData[i] != pb[i]) return false;
+				if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false;
 			}
-			return true;
-		}
 
-		/// <summary>
-		/// XOR all bytes in a data buffer with a pad. Both byte arrays must
-		/// be of the same size.
-		/// </summary>
-		/// <param name="pbData">Data to be protected.</param>
-		/// <param name="pbPad">XOR pad.</param>
-		/// <exception cref="System.ArgumentNullException">Thrown if one of the
-		/// parameters is <c>null</c>.</exception>
-		/// <exception cref="System.ArgumentException">Thrown if the length of
-		/// the data array and the pad aren't equal.</exception>
-		[Obsolete("Use MemUtil.XorArray instead.")]
-		public static void XorArrays(byte[] pbData, byte[] pbPad)
-		{
-			Debug.Assert(pbData != null); if(pbData == null) throw new ArgumentNullException("pbData");
-			Debug.Assert(pbPad != null); if(pbPad == null) throw new ArgumentNullException("pbPad");
-			
-			Debug.Assert(pbData.Length == pbPad.Length);
-			if(pbData.Length != pbPad.Length) throw new ArgumentException();
-
-			for(int i = 0; i < pbData.Length; ++i)
-				pbData[i] ^= pbPad[i];
-		}
+			return true;
+		} */
 	}
 }
diff --git a/KeePassLib/Serialization/BinaryReaderEx.cs b/KeePassLib/Serialization/BinaryReaderEx.cs
index c5f29a3..6f04850 100644
--- a/KeePassLib/Serialization/BinaryReaderEx.cs
+++ b/KeePassLib/Serialization/BinaryReaderEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Serialization/FileLock.cs b/KeePassLib/Serialization/FileLock.cs
new file mode 100644
index 0000000..04675ab
--- /dev/null
+++ b/KeePassLib/Serialization/FileLock.cs
@@ -0,0 +1,260 @@
+/*
+  KeePass Password Safe - The Open-Source Password Manager
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Threading;
+using System.Diagnostics;
+
+using KeePassLib.Cryptography;
+using KeePassLib.Resources;
+using KeePassLib.Utility;
+
+namespace KeePassLib.Serialization
+{
+	public sealed class FileLockException : Exception
+	{
+		private readonly string m_strMsg;
+
+		public override string Message
+		{
+			get { return m_strMsg; }
+		}
+
+		public FileLockException(string strBaseFile, string strUser)
+		{
+			StringBuilder sb = new StringBuilder();
+
+			if(!string.IsNullOrEmpty(strBaseFile))
+			{
+				sb.Append(strBaseFile);
+				sb.Append(MessageService.NewParagraph);
+			}
+
+			sb.Append(KLRes.FileLockedWrite);
+			sb.Append(MessageService.NewLine);
+
+			if(!string.IsNullOrEmpty(strUser)) sb.Append(strUser);
+			else sb.Append("?");
+
+			sb.Append(MessageService.NewParagraph);
+			sb.Append(KLRes.TryAgainSecs);
+
+			m_strMsg = sb.ToString();
+		}
+	}
+
+	public sealed class FileLock : IDisposable
+	{
+		private const string LockFileExt = ".lock";
+		private const string LockFileHeader = "KeePass Lock File";
+
+		private IOConnectionInfo m_iocLockFile;
+
+		private sealed class LockFileInfo
+		{
+			public readonly string ID;
+			public readonly DateTime Time;
+			public readonly string UserName;
+			public readonly string Machine;
+			public readonly string Domain;
+
+			private LockFileInfo(string strID, string strTime, string strUserName,
+				string strMachine, string strDomain)
+			{
+				this.ID = (strID ?? string.Empty).Trim();
+
+				DateTime dt;
+				if(TimeUtil.TryDeserializeUtc(strTime.Trim(), out dt))
+					this.Time = dt;
+				else
+				{
+					Debug.Assert(false);
+					this.Time = DateTime.UtcNow;
+				}
+
+				this.UserName = (strUserName ?? string.Empty).Trim();
+				this.Machine = (strMachine ?? string.Empty).Trim();
+				this.Domain = (strDomain ?? string.Empty).Trim();
+
+				if(this.Domain.Equals(this.Machine, StrUtil.CaseIgnoreCmp))
+					this.Domain = string.Empty;
+			}
+
+			public string GetOwner()
+			{
+				StringBuilder sb = new StringBuilder();
+				sb.Append((this.UserName.Length > 0) ? this.UserName : "?");
+
+				bool bMachine = (this.Machine.Length > 0);
+				bool bDomain = (this.Domain.Length > 0);
+				if(bMachine || bDomain)
+				{
+					sb.Append(" (");
+					sb.Append(this.Machine);
+					if(bMachine && bDomain) sb.Append(" @ ");
+					sb.Append(this.Domain);
+					sb.Append(")");
+				}
+
+				return sb.ToString();
+			}
+
+			public static LockFileInfo Load(IOConnectionInfo iocLockFile)
+			{
+				Stream s = null;
+				try
+				{
+					s = IOConnection.OpenRead(iocLockFile);
+					if(s == null) return null;
+					StreamReader sr = new StreamReader(s, StrUtil.Utf8);
+					string str = sr.ReadToEnd();
+					sr.Close();
+					if(str == null) { Debug.Assert(false); return null; }
+
+					str = StrUtil.NormalizeNewLines(str, false);
+					string[] v = str.Split('\n');
+					if((v == null) || (v.Length < 6)) { Debug.Assert(false); return null; }
+
+					if(!v[0].StartsWith(LockFileHeader)) { Debug.Assert(false); return null; }
+					return new LockFileInfo(v[1], v[2], v[3], v[4], v[5]);
+				}
+				catch(FileNotFoundException) { }
+				catch(Exception) { Debug.Assert(false); }
+				finally { if(s != null) s.Close(); }
+
+				return null;
+			}
+
+			// Throws on error
+			public static LockFileInfo Create(IOConnectionInfo iocLockFile)
+			{
+				LockFileInfo lfi;
+				Stream s = null;
+				try
+				{
+					byte[] pbID = CryptoRandom.Instance.GetRandomBytes(16);
+					string strTime = TimeUtil.SerializeUtc(DateTime.Now);
+
+#if !KeePassLibSD
+					lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
+						Environment.UserName, Environment.MachineName,
+						Environment.UserDomainName);
+#else
+					lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
+						string.Empty, string.Empty, string.Empty);
+#endif
+
+					StringBuilder sb = new StringBuilder();
+#if !KeePassLibSD
+					sb.AppendLine(LockFileHeader);
+					sb.AppendLine(lfi.ID);
+					sb.AppendLine(strTime);
+					sb.AppendLine(lfi.UserName);
+					sb.AppendLine(lfi.Machine);
+					sb.AppendLine(lfi.Domain);
+#else
+					sb.Append(LockFileHeader + MessageService.NewLine);
+					sb.Append(lfi.ID + MessageService.NewLine);
+					sb.Append(strTime + MessageService.NewLine);
+					sb.Append(lfi.UserName + MessageService.NewLine);
+					sb.Append(lfi.Machine + MessageService.NewLine);
+					sb.Append(lfi.Domain + MessageService.NewLine);
+#endif
+
+					byte[] pbFile = StrUtil.Utf8.GetBytes(sb.ToString());
+
+					s = IOConnection.OpenWrite(iocLockFile);
+					if(s == null) throw new IOException(iocLockFile.GetDisplayName());
+					s.Write(pbFile, 0, pbFile.Length);
+				}
+				finally { if(s != null) s.Close(); }
+
+				return lfi;
+			}
+		}
+
+		public FileLock(IOConnectionInfo iocBaseFile)
+		{
+			if(iocBaseFile == null) throw new ArgumentNullException("strBaseFile");
+
+			m_iocLockFile = iocBaseFile.CloneDeep();
+			m_iocLockFile.Path += LockFileExt;
+
+			LockFileInfo lfiEx = LockFileInfo.Load(m_iocLockFile);
+			if(lfiEx != null)
+			{
+				m_iocLockFile = null; // Otherwise Dispose deletes the existing one
+				throw new FileLockException(iocBaseFile.GetDisplayName(),
+					lfiEx.GetOwner());
+			}
+
+			LockFileInfo.Create(m_iocLockFile);
+		}
+
+		~FileLock()
+		{
+			Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
+		private void Dispose(bool bDisposing)
+		{
+			if(m_iocLockFile == null) return;
+
+			bool bFileDeleted = false;
+			for(int r = 0; r < 5; ++r)
+			{
+				// if(!OwnLockFile()) { bFileDeleted = true; break; }
+
+				try
+				{
+					IOConnection.DeleteFile(m_iocLockFile);
+					bFileDeleted = true;
+				}
+				catch(Exception) { Debug.Assert(false); }
+
+				if(bFileDeleted) break;
+
+				if(bDisposing) Thread.Sleep(50);
+			}
+
+			if(bDisposing && !bFileDeleted)
+				IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception
+
+			m_iocLockFile = null;
+		}
+
+		// private bool OwnLockFile()
+		// {
+		//	if(m_iocLockFile == null) { Debug.Assert(false); return false; }
+		//	if(m_strLockID == null) { Debug.Assert(false); return false; }
+		//	LockFileInfo lfi = LockFileInfo.Load(m_iocLockFile);
+		//	if(lfi == null) return false;
+		//	return m_strLockID.Equals(lfi.ID);
+		// }
+	}
+}
diff --git a/KeePassLib/Serialization/FileTransactionEx.cs b/KeePassLib/Serialization/FileTransactionEx.cs
index 60d3bdb..477f8cb 100644
--- a/KeePassLib/Serialization/FileTransactionEx.cs
+++ b/KeePassLib/Serialization/FileTransactionEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Serialization/HashedBlockStream.cs b/KeePassLib/Serialization/HashedBlockStream.cs
index 3fe9010..ca8b189 100644
--- a/KeePassLib/Serialization/HashedBlockStream.cs
+++ b/KeePassLib/Serialization/HashedBlockStream.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Serialization/IOConnection.cs b/KeePassLib/Serialization/IOConnection.cs
index 6e53d17..6bde6f8 100644
--- a/KeePassLib/Serialization/IOConnection.cs
+++ b/KeePassLib/Serialization/IOConnection.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -290,7 +290,7 @@ namespace KeePassLib.Serialization
 				if(s == null) throw new FileNotFoundException();
 
 				// For FTP clients we called RETR to get the file, but we never
-				// followed-up and downloaded the file. Close may produce a
+				// followed-up and downloaded the file; close may produce a
 				// 550 error -- that's okay
 				try { s.Close(); }
 				catch(Exception) { }
diff --git a/KeePassLib/Serialization/IOConnectionInfo.cs b/KeePassLib/Serialization/IOConnectionInfo.cs
index 6913cdf..3eafc2a 100644
--- a/KeePassLib/Serialization/IOConnectionInfo.cs
+++ b/KeePassLib/Serialization/IOConnectionInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Serialization/Kdb4File.Read.Streamed.cs b/KeePassLib/Serialization/Kdb4File.Read.Streamed.cs
index 6ad60f3..fae29ec 100644
--- a/KeePassLib/Serialization/Kdb4File.Read.Streamed.cs
+++ b/KeePassLib/Serialization/Kdb4File.Read.Streamed.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -105,7 +105,6 @@ namespace KeePassLib.Serialization
 
 			m_ctxGroups.Clear();
 			m_dictBinPool = new Dictionary<string, ProtectedBinary>();
-			m_dictBinPoolCopyOnRead = new Dictionary<string, ProtectedBinary>();
 
 			KdbContext ctx = KdbContext.Null;
 
@@ -639,10 +638,10 @@ namespace KeePassLib.Serialization
 		private string ReadString(XmlReader xr)
 		{
 			XorredBuffer xb = ProcessNode(xr);
-
 			if(xb != null)
 			{
 				byte[] pb = xb.ReadPlainText();
+				if(pb.Length == 0) return string.Empty;
 				return StrUtil.Utf8.GetString(pb, 0, pb.Length);
 			}
 
@@ -733,7 +732,17 @@ namespace KeePassLib.Serialization
 			XorredBuffer xb = ProcessNode(xr);
 			if(xb != null) return new ProtectedString(true, xb);
 
-			ProtectedString ps = new ProtectedString(false, ReadString(xr));
+			bool bProtect = false;
+			if(m_format == Kdb4Format.PlainXml)
+			{
+				if(xr.MoveToAttribute(AttrProtectedInMemPlainXml))
+				{
+					string strProtect = xr.Value;
+					bProtect = ((strProtect != null) && (strProtect == ValTrue));
+				}
+			}
+
+			ProtectedString ps = new ProtectedString(bProtect, ReadString(xr));
 			return ps;
 		}
 
@@ -763,7 +772,7 @@ namespace KeePassLib.Serialization
 			}
 
 			string strValue = ReadString(xr);
-			if(strValue.Length == 0) return new ProtectedBinary(false);
+			if(strValue.Length == 0) return new ProtectedBinary();
 
 			byte[] pbData = Convert.FromBase64String(strValue);
 			if(bCompressed) pbData = MemUtil.Decompress(pbData);
diff --git a/KeePassLib/Serialization/Kdb4File.Read.cs b/KeePassLib/Serialization/Kdb4File.Read.cs
index ef0783d..57aea0f 100644
--- a/KeePassLib/Serialization/Kdb4File.Read.cs
+++ b/KeePassLib/Serialization/Kdb4File.Read.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -126,7 +126,7 @@ namespace KeePassLib.Serialization
 					m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
 						m_pbProtectedStreamKey);
 				}
-				else m_randomStream = null; // No random stream for plain text files
+				else m_randomStream = null; // No random stream for plain-text files
 
 				ReadXmlStreamed(readerStream, hashedStream);
 				// ReadXmlDom(readerStream);
@@ -149,6 +149,10 @@ namespace KeePassLib.Serialization
 
 			sSource.Close();
 
+			// Reset memory protection settings (to always use reasonable
+			// defaults)
+			m_pwDatabase.MemoryProtection = new MemoryProtectionConfig();
+
 			// Remove old backups (this call is required here in order to apply
 			// the default history maintenance settings for people upgrading from
 			// KeePass <= 2.14 to >= 2.15; also it ensures history integrity in
diff --git a/KeePassLib/Serialization/Kdb4File.Write.cs b/KeePassLib/Serialization/Kdb4File.Write.cs
index 5152d73..12e3a8c 100644
--- a/KeePassLib/Serialization/Kdb4File.Write.cs
+++ b/KeePassLib/Serialization/Kdb4File.Write.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -633,21 +633,25 @@ namespace KeePassLib.Serialization
 			m_xmlWriter.WriteEndElement();
 			m_xmlWriter.WriteStartElement(ElemValue);
 
+			bool bProtected = value.IsProtected;
 			if(bIsEntryString)
 			{
+				// Adjust memory protection setting (which might be different
+				// from the database default, e.g. due to an import which
+				// didn't specify the correct setting)
 				if(name == PwDefs.TitleField)
-					value.EnableProtection(m_pwDatabase.MemoryProtection.ProtectTitle);
+					bProtected = m_pwDatabase.MemoryProtection.ProtectTitle;
 				else if(name == PwDefs.UserNameField)
-					value.EnableProtection(m_pwDatabase.MemoryProtection.ProtectUserName);
+					bProtected = m_pwDatabase.MemoryProtection.ProtectUserName;
 				else if(name == PwDefs.PasswordField)
-					value.EnableProtection(m_pwDatabase.MemoryProtection.ProtectPassword);
+					bProtected = m_pwDatabase.MemoryProtection.ProtectPassword;
 				else if(name == PwDefs.UrlField)
-					value.EnableProtection(m_pwDatabase.MemoryProtection.ProtectUrl);
+					bProtected = m_pwDatabase.MemoryProtection.ProtectUrl;
 				else if(name == PwDefs.NotesField)
-					value.EnableProtection(m_pwDatabase.MemoryProtection.ProtectNotes);
+					bProtected = m_pwDatabase.MemoryProtection.ProtectNotes;
 			}
 
-			if(value.IsProtected && (m_format != Kdb4Format.PlainXml))
+			if(bProtected && (m_format != Kdb4Format.PlainXml))
 			{
 				m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
 
@@ -696,6 +700,9 @@ namespace KeePassLib.Serialization
 					strValue = sb.ToString(); // Correct string for current code page
 				}
 
+				if((m_format == Kdb4Format.PlainXml) && bProtected)
+					m_xmlWriter.WriteAttributeString(AttrProtectedInMemPlainXml, ValTrue);
+
 				m_xmlWriter.WriteString(StrUtil.SafeXmlString(strValue));
 			}
 
diff --git a/KeePassLib/Serialization/Kdb4File.cs b/KeePassLib/Serialization/Kdb4File.cs
index b5a4e46..25df286 100644
--- a/KeePassLib/Serialization/Kdb4File.cs
+++ b/KeePassLib/Serialization/Kdb4File.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -172,6 +172,7 @@ namespace KeePassLib.Serialization
 		private const string AttrId = "ID";
 		private const string AttrRef = "Ref";
 		private const string AttrProtected = "Protected";
+		private const string AttrProtectedInMemPlainXml = "ProtectInMemory";
 		private const string AttrCompressed = "Compressed";
 
 		private const string ElemIsExpanded = "IsExpanded";
@@ -206,8 +207,6 @@ namespace KeePassLib.Serialization
 
 		private Dictionary<string, ProtectedBinary> m_dictBinPool =
 			new Dictionary<string, ProtectedBinary>();
-		private Dictionary<string, ProtectedBinary> m_dictBinPoolCopyOnRead =
-			new Dictionary<string, ProtectedBinary>();
 
 		private byte[] m_pbHashOfFileOnDisk = null;
 
@@ -332,7 +331,7 @@ namespace KeePassLib.Serialization
 
 			foreach(KeyValuePair<string, ProtectedBinary> kvp in m_dictBinPool)
 			{
-				if(pb.EqualsValue(kvp.Value)) return kvp.Key;
+				if(pb.Equals(kvp.Value)) return kvp.Key;
 			}
 
 			return null;
@@ -343,16 +342,7 @@ namespace KeePassLib.Serialization
 			if(strKey == null) { Debug.Assert(false); return null; }
 
 			ProtectedBinary pb;
-			if(m_dictBinPool.TryGetValue(strKey, out pb))
-			{
-				m_dictBinPool.Remove(strKey);
-				m_dictBinPoolCopyOnRead[strKey] = pb;
-
-				return pb;
-			}
-
-			if(m_dictBinPoolCopyOnRead.TryGetValue(strKey, out pb))
-				return new ProtectedBinary(pb);
+			if(m_dictBinPool.TryGetValue(strKey, out pb)) return pb;
 
 			return null;
 		}
@@ -383,7 +373,9 @@ namespace KeePassLib.Serialization
 			while(File.Exists(strPath));
 
 #if !KeePassLibSD
-			File.WriteAllBytes(strPath, pb.ReadData());
+			byte[] pbData = pb.ReadData();
+			File.WriteAllBytes(strPath, pbData);
+			MemUtil.ZeroByteArray(pbData);
 #else
 			FileStream fs = new FileStream(strPath, FileMode.Create,
 				FileAccess.Write, FileShare.None);
diff --git a/KeePassLib/Serialization/OldFormatException.cs b/KeePassLib/Serialization/OldFormatException.cs
index 749d92b..20788f8 100644
--- a/KeePassLib/Serialization/OldFormatException.cs
+++ b/KeePassLib/Serialization/OldFormatException.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Translation/KPControlCustomization.cs b/KeePassLib/Translation/KPControlCustomization.cs
index 3eb5adb..c59fc37 100644
--- a/KeePassLib/Translation/KPControlCustomization.cs
+++ b/KeePassLib/Translation/KPControlCustomization.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Translation/KPFormCustomization.cs b/KeePassLib/Translation/KPFormCustomization.cs
index 4281377..b4033d5 100644
--- a/KeePassLib/Translation/KPFormCustomization.cs
+++ b/KeePassLib/Translation/KPFormCustomization.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Translation/KPStringTable.cs b/KeePassLib/Translation/KPStringTable.cs
index a8c77e2..cd96340 100644
--- a/KeePassLib/Translation/KPStringTable.cs
+++ b/KeePassLib/Translation/KPStringTable.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Translation/KPStringTableItem.cs b/KeePassLib/Translation/KPStringTableItem.cs
index 83dcd2a..8127f57 100644
--- a/KeePassLib/Translation/KPStringTableItem.cs
+++ b/KeePassLib/Translation/KPStringTableItem.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Translation/KPTranslation.cs b/KeePassLib/Translation/KPTranslation.cs
index 88b5e0c..27d0e22 100644
--- a/KeePassLib/Translation/KPTranslation.cs
+++ b/KeePassLib/Translation/KPTranslation.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Translation/KPTranslationProperties.cs b/KeePassLib/Translation/KPTranslationProperties.cs
index b5b03fb..55f942b 100644
--- a/KeePassLib/Translation/KPTranslationProperties.cs
+++ b/KeePassLib/Translation/KPTranslationProperties.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Utility/AppLogEx.cs b/KeePassLib/Utility/AppLogEx.cs
index 7d2cb7c..c4d3afa 100644
--- a/KeePassLib/Utility/AppLogEx.cs
+++ b/KeePassLib/Utility/AppLogEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLib/Utility/MemUtil.cs b/KeePassLib/Utility/MemUtil.cs
index add7a1f..dabf0d8 100644
--- a/KeePassLib/Utility/MemUtil.cs
+++ b/KeePassLib/Utility/MemUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -40,27 +40,26 @@ namespace KeePassLib.Utility
 		/// Convert a hexadecimal string to a byte array. The input string must be
 		/// even (i.e. its length is a multiple of 2).
 		/// </summary>
-		/// <param name="strHexString">String containing hexadecimal characters.</param>
+		/// <param name="strHex">String containing hexadecimal characters.</param>
 		/// <returns>Returns a byte array. Returns <c>null</c> if the string parameter
 		/// was <c>null</c> or is an uneven string (i.e. if its length isn't a
 		/// multiple of 2).</returns>
-		/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="strHexString" />
+		/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="strHex" />
 		/// is <c>null</c>.</exception>
-		public static byte[] HexStringToByteArray(string strHexString)
+		public static byte[] HexStringToByteArray(string strHex)
 		{
-			Debug.Assert(strHexString != null); if(strHexString == null) throw new ArgumentNullException("strHexString");
+			if(strHex == null) { Debug.Assert(false); throw new ArgumentNullException("strHex"); }
 
-			int nStrLen = strHexString.Length;
-			if((nStrLen & 1) != 0) return null; // Only even strings supported
+			int nStrLen = strHex.Length;
+			if((nStrLen & 1) != 0) { Debug.Assert(false); return null; }
 
 			byte[] pb = new byte[nStrLen / 2];
 			byte bt;
 			char ch;
 
-			for(int i = 0; i < nStrLen; ++i)
+			for(int i = 0; i < nStrLen; i += 2)
 			{
-				ch = strHexString[i];
-				if((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n')) continue;
+				ch = strHex[i];
 
 				if((ch >= '0') && (ch <= '9'))
 					bt = (byte)(ch - '0');
@@ -68,20 +67,20 @@ namespace KeePassLib.Utility
 					bt = (byte)(ch - 'a' + 10);
 				else if((ch >= 'A') && (ch <= 'F'))
 					bt = (byte)(ch - 'A' + 10);
-				else bt = 0;
+				else { Debug.Assert(false); bt = 0; }
 
 				bt <<= 4;
-				++i;
 
-				ch = strHexString[i];
+				ch = strHex[i + 1];
 				if((ch >= '0') && (ch <= '9'))
 					bt += (byte)(ch - '0');
 				else if((ch >= 'a') && (ch <= 'f'))
 					bt += (byte)(ch - 'a' + 10);
 				else if((ch >= 'A') && (ch <= 'F'))
 					bt += (byte)(ch - 'A' + 10);
+				else { Debug.Assert(false); }
 
-				pb[i / 2] = bt;
+				pb[i >> 1] = bt;
 			}
 
 			return pb;
diff --git a/KeePassLib/Utility/MessageService.cs b/KeePassLib/Utility/MessageService.cs
index 45411aa..00044d5 100644
--- a/KeePassLib/Utility/MessageService.cs
+++ b/KeePassLib/Utility/MessageService.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -146,7 +146,7 @@ namespace KeePassLib.Utility
 				else
 					strAppend = obj.ToString();
 
-				if((strAppend != null) && (strAppend.Length > 0))
+				if(!string.IsNullOrEmpty(strAppend))
 				{
 					if(bSeparator) sbText.Append(strNewPara);
 					else bSeparator = true;
@@ -369,8 +369,14 @@ namespace KeePassLib.Utility
 		public static void ShowSaveWarning(string strFilePath, Exception ex,
 			bool bCorruptionWarning)
 		{
-			string str = string.Empty;
+			FileLockException fl = (ex as FileLockException);
+			if(fl != null)
+			{
+				ShowWarning(fl.Message);
+				return;
+			}
 
+			string str = string.Empty;
 			if((strFilePath != null) && (strFilePath.Length > 0))
 				str += strFilePath + MessageService.NewParagraph;
 
diff --git a/KeePassLib/Utility/StrUtil.cs b/KeePassLib/Utility/StrUtil.cs
index ac4a075..de01625 100644
--- a/KeePassLib/Utility/StrUtil.cs
+++ b/KeePassLib/Utility/StrUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -190,7 +190,7 @@ namespace KeePassLib.Utility
 			str = str.Replace("\"", @""");
 			str = str.Replace("\'", @"'");
 
-			str = str.Replace("\r", string.Empty);
+			str = NormalizeNewLines(str, false);
 			str = str.Replace("\n", @"<br />");
 
 			return str;
@@ -603,7 +603,6 @@ namespace KeePassLib.Utility
 			for(char ch = 'A'; ch <= 'Z'; ++ch)
 			{
 				string strEnhAcc = @"(&" + ch.ToString() + @")";
-
 				if(str.IndexOf(strEnhAcc) >= 0)
 				{
 					str = str.Replace(@" " + strEnhAcc, string.Empty);
@@ -718,12 +717,50 @@ namespace KeePassLib.Utility
 			return "null";
 		}
 
-		public static string ToWindowsString(string str)
+		/// <summary>
+		/// Normalize new line characters in a string. Input strings may
+		/// contain mixed new line character sequences from all commonly
+		/// used operating systems (i.e. \r\n from Windows, \n from Unix
+		/// and \r from Mac OS.
+		/// </summary>
+		/// <param name="str">String with mixed new line characters.</param>
+		/// <param name="bWindows">If <c>true</c>, new line characters
+		/// are normalized for Windows (\r\n); if <c>false</c>, new line
+		/// characters are normalized for Unix (\n).</param>
+		/// <returns>String with normalized new line characters.</returns>
+		public static string NormalizeNewLines(string str, bool bWindows)
 		{
 			if(string.IsNullOrEmpty(str)) return str;
 
-			string strSingular = str.Replace("\r", string.Empty);
-			return strSingular.Replace("\n", "\r\n");
+			str = str.Replace("\r\n", "\n");
+			str = str.Replace("\r", "\n");
+
+			if(bWindows) str = str.Replace("\n", "\r\n");
+
+			return str;
+		}
+
+		private static char[] m_vNewLineChars = null;
+		public static void NormalizeNewLines(ProtectedStringDictionary dict,
+			bool bWindows)
+		{
+			if(dict == null) { Debug.Assert(false); return; }
+
+			if(m_vNewLineChars == null)
+				m_vNewLineChars = new char[]{ '\r', '\n' };
+
+			List<string> vKeys = dict.GetKeys();
+			foreach(string strKey in vKeys)
+			{
+				ProtectedString ps = dict.Get(strKey);
+				if(ps == null) { Debug.Assert(false); continue; }
+
+				string strValue = ps.ReadString();
+				if(strValue.IndexOfAny(m_vNewLineChars) < 0) continue;
+
+				dict.Set(strKey, new ProtectedString(ps.IsProtected,
+					NormalizeNewLines(strValue, bWindows)));
+			}
 		}
 
 		public static string AlphaNumericOnly(string str)
@@ -771,36 +808,56 @@ namespace KeePassLib.Utility
 		private static readonly char[] m_vVersionSep = new char[]{ '.', ',' };
 		public static ulong GetVersion(string strVersion)
 		{
-			if(string.IsNullOrEmpty(strVersion)) { Debug.Assert(false); return 0; }
+			if(strVersion == null) { Debug.Assert(false); return 0; }
 
-			string[] vVer = strVersion.Split(m_vVersionSep);
+			string[] vVer = strVersion.Trim().Split(m_vVersionSep);
 			if((vVer == null) || (vVer.Length == 0)) { Debug.Assert(false); return 0; }
 
 			ushort uPart;
-			StrUtil.TryParseUShort(vVer[0], out uPart);
+			StrUtil.TryParseUShort(vVer[0].Trim(), out uPart);
 			ulong uVer = ((ulong)uPart << 48);
 
 			if(vVer.Length >= 2)
 			{
-				StrUtil.TryParseUShort(vVer[1], out uPart);
+				StrUtil.TryParseUShort(vVer[1].Trim(), out uPart);
 				uVer |= ((ulong)uPart << 32);
 			}
 
 			if(vVer.Length >= 3)
 			{
-				StrUtil.TryParseUShort(vVer[2], out uPart);
+				StrUtil.TryParseUShort(vVer[2].Trim(), out uPart);
 				uVer |= ((ulong)uPart << 16);
 			}
 
 			if(vVer.Length >= 4)
 			{
-				StrUtil.TryParseUShort(vVer[3], out uPart);
+				StrUtil.TryParseUShort(vVer[3].Trim(), out uPart);
 				uVer |= (ulong)uPart;
 			}
 
 			return uVer;
 		}
 
+		public static string VersionToString(ulong uVersion)
+		{
+			string str = string.Empty;
+
+			for(int i = 0; i < 4; ++i)
+			{
+				ushort us = (ushort)(uVersion & 0xFFFFUL);
+
+				if((us != 0) || (str.Length > 0))
+				{
+					if(str.Length > 0) str = "." + str;
+					str = us.ToString() + str;
+				}
+
+				uVersion >>= 16;
+			}
+
+			return str;
+		}
+
 		private static readonly byte[] m_pbOptEnt = { 0xA5, 0x74, 0x2E, 0xEC };
 
 		public static string EncryptString(string strPlainText)
@@ -1002,7 +1059,7 @@ namespace KeePassLib.Utility
 			if(strMulti.Length == 0) return string.Empty;
 
 			string str = strMulti;
-			str = str.Replace("\r\n", "\n");
+			str = str.Replace("\r\n", " ");
 			str = str.Replace("\r", " ");
 			str = str.Replace("\n", " ");
 
@@ -1121,5 +1178,27 @@ namespace KeePassLib.Utility
 			ms.Close();
 			return pb;
 		}
+
+		/// <summary>
+		/// Remove placeholders from a string (wrapped in '{' and '}').
+		/// This doesn't remove environment variables (wrapped in '%').
+		/// </summary>
+		public static string RemovePlaceholders(string str)
+		{
+			if(str == null) { Debug.Assert(false); return string.Empty; }
+
+			while(true)
+			{
+				int iPlhStart = str.IndexOf('{');
+				if(iPlhStart < 0) break;
+
+				int iPlhEnd = str.IndexOf('}', iPlhStart); // '{' might be at end
+				if(iPlhEnd < 0) break;
+
+				str = (str.Substring(0, iPlhStart) + str.Substring(iPlhEnd + 1));
+			}
+
+			return str;
+		}
 	}
 }
diff --git a/KeePassLib/Utility/TimeUtil.cs b/KeePassLib/Utility/TimeUtil.cs
index 227f2d3..ac9d156 100644
--- a/KeePassLib/Utility/TimeUtil.cs
+++ b/KeePassLib/Utility/TimeUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -182,5 +182,41 @@ namespace KeePassLib.Utility
 
 			return DateTime.Now;
 		}
+
+#if !KeePassLibSD
+		private static string[] m_vUSMonths = null;
+		/// <summary>
+		/// Parse a US textual date string, like e.g. "January 02, 2012".
+		/// </summary>
+		public static DateTime? ParseUSTextDate(string strDate)
+		{
+			if(strDate == null) { Debug.Assert(false); return null; }
+
+			if(m_vUSMonths == null)
+				m_vUSMonths = new string[]{ "January", "February", "March",
+					"April", "May", "June", "July", "August", "September",
+					"October", "November", "December" };
+
+			string str = strDate.Trim();
+			for(int i = 0; i < m_vUSMonths.Length; ++i)
+			{
+				if(str.StartsWith(m_vUSMonths[i], StrUtil.CaseIgnoreCmp))
+				{
+					str = str.Substring(m_vUSMonths[i].Length);
+					string[] v = str.Split(new char[]{ ',', ';' });
+					if((v == null) || (v.Length != 2)) return null;
+
+					string strDay = v[0].Trim().TrimStart('0');
+					int iDay, iYear;
+					if(int.TryParse(strDay, out iDay) &&
+						int.TryParse(v[1].Trim(), out iYear))
+						return new DateTime(iYear, i + 1, iDay);
+					else { Debug.Assert(false); return null; }
+				}
+			}
+
+			return null;
+		}
+#endif
 	}
 }
diff --git a/KeePassLib/Utility/UrlUtil.cs b/KeePassLib/Utility/UrlUtil.cs
index e143f92..2e88858 100644
--- a/KeePassLib/Utility/UrlUtil.cs
+++ b/KeePassLib/Utility/UrlUtil.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -515,5 +515,53 @@ namespace KeePassLib.Utility
 
 			return str;
 		}
+
+		/// <summary>
+		/// Get the host component of an URL.
+		/// This method is faster and more fault-tolerant than creating
+		/// an <code>Uri</code> object and querying its <code>Host</code>
+		/// property.
+		/// </summary>
+		/// <example>
+		/// For the input <code>s://u:p@d.tld:p/p?q#f</code> the return
+		/// value is <code>d.tld</code>.
+		/// </example>
+		public static string GetHost(string strUrl)
+		{
+			if(strUrl == null) { Debug.Assert(false); return string.Empty; }
+
+			StringBuilder sb = new StringBuilder();
+			bool bInExtHost = false;
+			for(int i = 0; i < strUrl.Length; ++i)
+			{
+				char ch = strUrl[i];
+				if(bInExtHost)
+				{
+					if(ch == '/')
+					{
+						if(sb.Length == 0) { } // Ignore leading '/'s
+						else break;
+					}
+					else sb.Append(ch);
+				}
+				else // !bInExtHost
+				{
+					if(ch == ':') bInExtHost = true;
+				}
+			}
+
+			string str = sb.ToString();
+			if(str.Length == 0) str = strUrl;
+
+			// Remove the login part
+			int nLoginLen = str.IndexOf('@');
+			if(nLoginLen >= 0) str = str.Substring(nLoginLen + 1);
+
+			// Remove the port
+			int iPort = str.LastIndexOf(':');
+			if(iPort >= 0) str = str.Substring(0, iPort);
+
+			return str;
+		}
 	}
 }
diff --git a/KeePassLibSD/ColorTranslator.cs b/KeePassLibSD/ColorTranslator.cs
index d166d04..ccf6687 100644
--- a/KeePassLibSD/ColorTranslator.cs
+++ b/KeePassLibSD/ColorTranslator.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/GZipStream.cs b/KeePassLibSD/GZipStream.cs
index 3f8c74c..585c1cf 100644
--- a/KeePassLibSD/GZipStream.cs
+++ b/KeePassLibSD/GZipStream.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/InvalidDataException.cs b/KeePassLibSD/InvalidDataException.cs
index af575f2..1d69f03 100644
--- a/KeePassLibSD/InvalidDataException.cs
+++ b/KeePassLibSD/InvalidDataException.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/KeePassLibSD.csproj b/KeePassLibSD/KeePassLibSD.csproj
index f1d5495..278c110 100644
--- a/KeePassLibSD/KeePassLibSD.csproj
+++ b/KeePassLibSD/KeePassLibSD.csproj
@@ -230,6 +230,9 @@
     <Compile Include="..\KeePassLib\Serialization\BinaryReaderEx.cs">
       <Link>Serialization\BinaryReaderEx.cs</Link>
     </Compile>
+    <Compile Include="..\KeePassLib\Serialization\FileLock.cs">
+      <Link>Serialization\FileLock.cs</Link>
+    </Compile>
     <Compile Include="..\KeePassLib\Serialization\FileTransactionEx.cs">
       <Link>Serialization\FileTransactionEx.cs</Link>
     </Compile>
diff --git a/KeePassLibSD/Properties/AssemblyInfo.cs b/KeePassLibSD/Properties/AssemblyInfo.cs
index 1e97eb4..2e15a1e 100644
--- a/KeePassLibSD/Properties/AssemblyInfo.cs
+++ b/KeePassLibSD/Properties/AssemblyInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Dominik Reichl")]
 [assembly: AssemblyProduct("KeePassLibSD")]
-[assembly: AssemblyCopyright("Copyright © 2003-2011 Dominik Reichl")]
+[assembly: AssemblyCopyright("Copyright © 2003-2012 Dominik Reichl")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -38,4 +38,4 @@ using System.Runtime.InteropServices;
 [assembly: Guid("1d3c6f10-e10b-47be-a2f1-af2562d7d470")]
 
 // Assembly version information
-[assembly: AssemblyVersion("2.1.7.*")]
+[assembly: AssemblyVersion("2.1.8.*")]
diff --git a/KeePassLibSD/ProtectedData.cs b/KeePassLibSD/ProtectedData.cs
index f4325ce..2ce17e5 100644
--- a/KeePassLibSD/ProtectedData.cs
+++ b/KeePassLibSD/ProtectedData.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/ProtectedMemory.cs b/KeePassLibSD/ProtectedMemory.cs
index f177074..6619da5 100644
--- a/KeePassLibSD/ProtectedMemory.cs
+++ b/KeePassLibSD/ProtectedMemory.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/SHA256.cs b/KeePassLibSD/SHA256.cs
index ea5329b..78839d1 100644
--- a/KeePassLibSD/SHA256.cs
+++ b/KeePassLibSD/SHA256.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/SecureStringEx.cs b/KeePassLibSD/SecureStringEx.cs
index 4655ec9..ae1d85e 100644
--- a/KeePassLibSD/SecureStringEx.cs
+++ b/KeePassLibSD/SecureStringEx.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/KeePassLibSD/SortedDictionary.cs b/KeePassLibSD/SortedDictionary.cs
index 7b91b83..ce646cf 100644
--- a/KeePassLibSD/SortedDictionary.cs
+++ b/KeePassLibSD/SortedDictionary.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/ShInstUtil/ShInstUtil.cpp b/ShInstUtil/ShInstUtil.cpp
index c926419..874eca2 100644
--- a/ShInstUtil/ShInstUtil.cpp
+++ b/ShInstUtil/ShInstUtil.cpp
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 
 #pragma warning(push)
 #pragma warning(disable: 4996) // SCL warning
+#include <boost/smart_ptr.hpp>
 #include <boost/algorithm/string/trim.hpp>
 #pragma warning(pop)
 
@@ -197,16 +198,16 @@ std_string FindNGen()
 	if(strRoot.size() == 0) return strNGen;
 	EnsureTerminatingSeparator(strRoot);
 
-	FILETIME ftCreation;
-	ZeroMemory(&ftCreation, sizeof(FILETIME));
-	FindNGenRec(strRoot, strNGen, ftCreation);
+	ULONGLONG ullVersion = 0;
+	FindNGenRec(strRoot, strNGen, ullVersion);
 
 	return strNGen;
 }
 
 #pragma warning(push)
 #pragma warning(disable: 4127) // Conditional expression is constant
-void FindNGenRec(const std_string& strPath, std_string& strNGenPath, FILETIME& ftCreation)
+void FindNGenRec(const std_string& strPath, std_string& strNGenPath,
+	ULONGLONG& ullVersion)
 {
 	const std_string strSearch = strPath + _T("*.*");
 	const std_string strNGen = _T("ngen.exe");
@@ -221,15 +222,15 @@ void FindNGenRec(const std_string& strPath, std_string& strNGenPath, FILETIME& f
 		if((wfd.cFileName[0] == 0) || (_tcsicmp(wfd.cFileName, _T(".")) == 0) ||
 			(_tcsicmp(wfd.cFileName, _T("..")) == 0)) { }
 		else if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
-			FindNGenRec((strPath + wfd.cFileName) + _T("\\"), strNGenPath, ftCreation);
+			FindNGenRec((strPath + wfd.cFileName) + _T("\\"), strNGenPath, ullVersion);
 		else if(_tcsicmp(wfd.cFileName, strNGen.c_str()) == 0)
 		{
-			if((wfd.ftCreationTime.dwHighDateTime > ftCreation.dwHighDateTime) ||
-				((wfd.ftCreationTime.dwHighDateTime == ftCreation.dwHighDateTime) &&
-				(wfd.ftCreationTime.dwLowDateTime > ftCreation.dwLowDateTime)))
+			const std_string strFullPath = strPath + strNGen;
+			const ULONGLONG ullThisVer = SiuGetFileVersion(strFullPath);
+			if(ullThisVer >= ullVersion)
 			{
-				strNGenPath = strPath + wfd.cFileName;
-				ftCreation = wfd.ftCreationTime;
+				strNGenPath = strFullPath;
+				ullVersion = ullThisVer;
 			}
 		}
 
@@ -240,6 +241,29 @@ void FindNGenRec(const std_string& strPath, std_string& strNGenPath, FILETIME& f
 }
 #pragma warning(pop)
 
+ULONGLONG SiuGetFileVersion(const std_string& strFilePath)
+{
+	DWORD dwDummy = 0;
+	const DWORD dwVerSize = GetFileVersionInfoSize(
+		strFilePath.c_str(), &dwDummy);
+	if(dwVerSize == 0) return 0;
+
+	boost::scoped_array<BYTE> vVerInfo(new BYTE[dwVerSize]);
+	if(vVerInfo.get() == NULL) return 0; // Out of memory
+
+	if(GetFileVersionInfo(strFilePath.c_str(), 0, dwVerSize,
+		vVerInfo.get()) == FALSE) return 0;
+
+	VS_FIXEDFILEINFO* pFileInfo = NULL;
+	UINT uFixedInfoLen = 0;
+	if(VerQueryValue(vVerInfo.get(), _T("\\"), (LPVOID*)&pFileInfo,
+		&uFixedInfoLen) == FALSE) return 0;
+	if(pFileInfo == NULL) return 0;
+
+	return ((static_cast<ULONGLONG>(pFileInfo->dwFileVersionMS) <<
+		32) | static_cast<ULONGLONG>(pFileInfo->dwFileVersionLS));
+}
+
 void CheckDotNetInstalled()
 {
 	OSVERSIONINFO osv;
diff --git a/ShInstUtil/ShInstUtil.h b/ShInstUtil/ShInstUtil.h
index 6427f27..89999be 100644
--- a/ShInstUtil/ShInstUtil.h
+++ b/ShInstUtil/ShInstUtil.h
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -97,7 +97,9 @@ std_string GetNetInstallRoot();
 std_string GetKeePassExePath();
 void EnsureTerminatingSeparator(std_string& strPath);
 std_string FindNGen();
-void FindNGenRec(const std_string& strPath, std_string& strNGenPath, FILETIME& ftCreation);
+void FindNGenRec(const std_string& strPath, std_string& strNGenPath,
+	ULONGLONG& ullVersion);
+ULONGLONG SiuGetFileVersion(const std_string& strFilePath);
 void CheckDotNetInstalled();
 
 #endif // ___SH_INST_UTIL_H___
diff --git a/ShInstUtil/ShInstUtil.rc b/ShInstUtil/ShInstUtil.rc
index 91a24c6..709da0d 100644
--- a/ShInstUtil/ShInstUtil.rc
+++ b/ShInstUtil/ShInstUtil.rc
@@ -65,8 +65,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,7,0
- PRODUCTVERSION 2,1,7,0
+ FILEVERSION 2,1,8,0
+ PRODUCTVERSION 2,1,8,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -83,12 +83,12 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "Dominik Reichl"
             VALUE "FileDescription", "ShInstUtil - KeePass Helper Utility"
-            VALUE "FileVersion", "2, 1, 7, 0"
+            VALUE "FileVersion", "2, 1, 8, 0"
             VALUE "InternalName", "ShInstUtil"
-            VALUE "LegalCopyright", "Copyright (c) 2007-2011 Dominik Reichl"
+            VALUE "LegalCopyright", "Copyright (c) 2007-2012 Dominik Reichl"
             VALUE "OriginalFilename", "ShInstUtil.exe"
             VALUE "ProductName", "ShInstUtil - KeePass Helper Utility"
-            VALUE "ProductVersion", "2, 1, 7, 0"
+            VALUE "ProductVersion", "2, 1, 8, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/ShInstUtil/ShInstUtil.vcproj b/ShInstUtil/ShInstUtil.vcproj
index 95fb441..9b33375 100644
--- a/ShInstUtil/ShInstUtil.vcproj
+++ b/ShInstUtil/ShInstUtil.vcproj
@@ -61,7 +61,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="comctl32.lib"
+				AdditionalDependencies="comctl32.lib version.lib"
 				LinkIncremental="2"
 				GenerateDebugInformation="true"
 				SubSystem="2"
@@ -135,7 +135,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="comctl32.lib"
+				AdditionalDependencies="comctl32.lib version.lib"
 				LinkIncremental="1"
 				GenerateDebugInformation="true"
 				SubSystem="2"
diff --git a/Translation/DefaultText.xml b/Translation/DefaultText.xml
index 9d930f2..adddc4f 100644
--- a/Translation/DefaultText.xml
+++ b/Translation/DefaultText.xml
@@ -10,9 +10,6 @@
 		<Data Name="AddEntry">
 			<Value>Add Entry</Value>
 		</Data>
-		<Data Name="AddEntryBtn">
-			<Value>Add Entry...</Value>
-		</Data>
 		<Data Name="AddEntryDesc">
 			<Value>Create a new password entry.</Value>
 		</Data>
@@ -145,6 +142,9 @@
 		<Data Name="AutoTypeMatchByTitle">
 			<Value>An entry matches if its title is contained in the target window title</Value>
 		</Data>
+		<Data Name="AutoTypeMatchByUrlHostInTitle">
+			<Value>An entry matches if the host component of its URL is contained in the target window title</Value>
+		</Data>
 		<Data Name="AutoTypeMatchByUrlInTitle">
 			<Value>An entry matches if its URL is contained in the target window title</Value>
 		</Data>
@@ -172,6 +172,9 @@
 		<Data Name="AutoTypeXDoToolRequiredGlobalVer">
 			<Value>For global auto-type, the 'xdotool' utility/package is required (version 2.20100818.3004 or higher!).</Value>
 		</Data>
+		<Data Name="Available">
+			<Value>Available</Value>
+		</Data>
 		<Data Name="AvailableLanguages">
 			<Value>Available Languages</Value>
 		</Data>
@@ -190,6 +193,9 @@
 		<Data Name="Browser">
 			<Value>Browser</Value>
 		</Data>
+		<Data Name="BuiltIn">
+			<Value>built-in</Value>
+		</Data>
 		<Data Name="ButtonBack">
 			<Value>< &Back</Value>
 		</Data>
@@ -217,11 +223,8 @@
 		<Data Name="CheckForUpdAtStart">
 			<Value>Check for update at KeePass startup</Value>
 		</Data>
-		<Data Name="ChkForUpdGotLatest">
-			<Value>You have the latest version.</Value>
-		</Data>
-		<Data Name="ChkForUpdNewVersion">
-			<Value>New KeePass version available!</Value>
+		<Data Name="CheckingForUpd">
+			<Value>Checking for updates</Value>
 		</Data>
 		<Data Name="ClearKeyCmdLineParams">
 			<Value>Clear master key command line parameters after using them once</Value>
@@ -253,14 +256,17 @@
 		<Data Name="Column">
 			<Value>Column</Value>
 		</Data>
+		<Data Name="Columns">
+			<Value>Columns</Value>
+		</Data>
 		<Data Name="Company">
 			<Value>Company</Value>
 		</Data>
 		<Data Name="Comparison">
 			<Value>Comparison</Value>
 		</Data>
-		<Data Name="Components">
-			<Value>Components</Value>
+		<Data Name="Component">
+			<Value>Component</Value>
 		</Data>
 		<Data Name="Condition">
 			<Value>Condition</Value>
@@ -466,6 +472,9 @@
 		<Data Name="DialogNoShowAgain">
 			<Value>Do not show this dialog again.</Value>
 		</Data>
+		<Data Name="Disable">
+			<Value>Disable</Value>
+		</Data>
 		<Data Name="Disabled">
 			<Value>Disabled</Value>
 		</Data>
@@ -529,6 +538,9 @@
 		<Data Name="EmptyRecycleBinQuestion">
 			<Value>Are you sure you want to permanently delete the items?</Value>
 		</Data>
+		<Data Name="Enable">
+			<Value>Enable</Value>
+		</Data>
 		<Data Name="Enabled">
 			<Value>Enabled</Value>
 		</Data>
@@ -565,12 +577,6 @@
 		<Data Name="EntryListAutoResizeColumns">
 			<Value>Automatically resize entry list columns when resizing the main window</Value>
 		</Data>
-		<Data Name="EntryView">
-			<Value>Entry View</Value>
-		</Data>
-		<Data Name="EntryViewHideProtectedCustomStrings">
-			<Value>Hide in-memory protected custom strings using asterisks</Value>
-		</Data>
 		<Data Name="EnvironmentVariable">
 			<Value>Environment variable</Value>
 		</Data>
@@ -922,12 +928,12 @@
 		<Data Name="InheritSettingFromParent">
 			<Value>Inherit setting from parent</Value>
 		</Data>
+		<Data Name="Installed">
+			<Value>Installed</Value>
+		</Data>
 		<Data Name="Internet">
 			<Value>Internet</Value>
 		</Data>
-		<Data Name="InvalidFileStructure">
-			<Value>Invalid file structure!</Value>
-		</Data>
 		<Data Name="InvalidKey">
 			<Value>Invalid Key</Value>
 		</Data>
@@ -973,9 +979,15 @@
 		<Data Name="KeyboardKeyCtrlLeft">
 			<Value>LCtrl</Value>
 		</Data>
+		<Data Name="KeyboardKeyEsc">
+			<Value>Esc</Value>
+		</Data>
 		<Data Name="KeyboardKeyModifiers">
 			<Value>Key Modifiers</Value>
 		</Data>
+		<Data Name="KeyboardKeyReturn">
+			<Value>Return</Value>
+		</Data>
 		<Data Name="KeyboardKeyShift">
 			<Value>Shift</Value>
 		</Data>
@@ -1003,10 +1015,10 @@
 		<Data Name="KeyFileUseExisting">
 			<Value>Use an existing file as key file</Value>
 		</Data>
-		<Data Name="KeyProvWithGuiOnSD">
-			<Value>The selected key provider cannot be used, because it might try to show a dialog and this isn't allowed on a secure desktop.</Value>
+		<Data Name="KeyProvIncmpWithSD">
+			<Value>The selected key provider cannot be used, because it is incompatible with the secure desktop.</Value>
 		</Data>
-		<Data Name="KeyProvWithGuiOnSDHint">
+		<Data Name="KeyProvIncmpWithSDHint">
 			<Value>If you want to use the selected key provider, you have to disable the secure desktop option in 'Tools' -> 'Options' -> tab 'Security'.</Value>
 		</Data>
 		<Data Name="LanguageSelected">
@@ -1126,6 +1138,9 @@
 		<Data Name="NewState">
 			<Value>New state</Value>
 		</Data>
+		<Data Name="NewVersionAvailable">
+			<Value>New version available</Value>
+		</Data>
 		<Data Name="No">
 			<Value>No</Value>
 		</Data>
@@ -1348,6 +1363,9 @@
 		<Data Name="PolicyTriggersEditDesc">
 			<Value>Allow editing triggers.</Value>
 		</Data>
+		<Data Name="PreReleaseVersion">
+			<Value>Pre-release version</Value>
+		</Data>
 		<Data Name="Print">
 			<Value>Print</Value>
 		</Data>
@@ -1372,6 +1390,9 @@
 		<Data Name="Ready">
 			<Value>Ready.</Value>
 		</Data>
+		<Data Name="Recommended">
+			<Value>recommended</Value>
+		</Data>
 		<Data Name="RecycleBin">
 			<Value>Recycle Bin</Value>
 		</Data>
@@ -1399,6 +1420,9 @@
 		<Data Name="RootDirectory">
 			<Value>Root Directory</Value>
 		</Data>
+		<Data Name="SameKeybLayout">
+			<Value>Ensure same keyboard layouts during auto-type</Value>
+		</Data>
 		<Data Name="SampleEntry">
 			<Value>Sample Entry</Value>
 		</Data>
@@ -1477,6 +1501,9 @@
 		<Data Name="SelectDifferentGroup">
 			<Value>Please select a different group.</Value>
 		</Data>
+		<Data Name="SelectedColumn">
+			<Value>Selected column</Value>
+		</Data>
 		<Data Name="SelectedLower">
 			<Value>selected</Value>
 		</Data>
@@ -1498,9 +1525,6 @@
 		<Data Name="Sequence">
 			<Value>Sequence</Value>
 		</Data>
-		<Data Name="ShowAllEntries">
-			<Value>Show All Entries</Value>
-		</Data>
 		<Data Name="ShowDerefData">
 			<Value>Show dereferenced data</Value>
 		</Data>
@@ -1510,9 +1534,6 @@
 		<Data Name="ShowEntries">
 			<Value>Show Entries</Value>
 		</Data>
-		<Data Name="ShowExpiredEntries">
-			<Value>Show Expired Entries</Value>
-		</Data>
 		<Data Name="ShowFullPathInTitleBar">
 			<Value>Show full path in title bar (instead of file name only)</Value>
 		</Data>
@@ -1549,6 +1570,9 @@
 		<Data Name="StartsWith">
 			<Value>Starts with</Value>
 		</Data>
+		<Data Name="Status">
+			<Value>Status</Value>
+		</Data>
 		<Data Name="Strikeout">
 			<Value>Strikeout</Value>
 		</Data>
@@ -1697,7 +1721,7 @@
 			<Value>Unhide Passwords</Value>
 		</Data>
 		<Data Name="UnhidePasswordsDesc">
-			<Value>Allow displaying passwords as plain text.</Value>
+			<Value>Allow displaying passwords as plain-text.</Value>
 		</Data>
 		<Data Name="UnhideSourceCharactersToo">
 			<Value>Unhide button also unhides source characters</Value>
@@ -1708,15 +1732,33 @@
 		<Data Name="UnknownError">
 			<Value>An unknown error occurred.</Value>
 		</Data>
-		<Data Name="UnknownFileVersion">
-			<Value>Unknown file version!</Value>
+		<Data Name="UpdateCheck">
+			<Value>Update Check</Value>
+		</Data>
+		<Data Name="UpdateCheckEnableQ">
+			<Value>Enable automatic update check?</Value>
+		</Data>
+		<Data Name="UpdateCheckFailedNoDl">
+			<Value>Update check failed. Version information file cannot be downloaded.</Value>
 		</Data>
-		<Data Name="UpdateCheckingFailed">
-			<Value>Update checking failed.</Value>
+		<Data Name="UpdateCheckInfo">
+			<Value>KeePass can automatically check for updates on each program start.</Value>
+		</Data>
+		<Data Name="UpdateCheckInfoPriv">
+			<Value>No personal information is sent to the KeePass server. KeePass just downloads a small version information file and compares the available version with the installed version.</Value>
+		</Data>
+		<Data Name="UpdateCheckInfoRes">
+			<Value>Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically.</Value>
+		</Data>
+		<Data Name="UpdateCheckResults">
+			<Value>The results of the update check.</Value>
 		</Data>
 		<Data Name="UpdatedUIState">
 			<Value>User interface state updated</Value>
 		</Data>
+		<Data Name="UpToDate">
+			<Value>Up to date</Value>
+		</Data>
 		<Data Name="Url">
 			<Value>URL</Value>
 		</Data>
@@ -1744,6 +1786,9 @@
 		<Data Name="UseCustomToolStripRenderer">
 			<Value>Use custom ToolStrip renderer</Value>
 		</Data>
+		<Data Name="UseFileLocks">
+			<Value>Use database lock files</Value>
+		</Data>
 		<Data Name="UseTransactedDatabaseWrites">
 			<Value>Use file transactions for writing databases</Value>
 		</Data>
@@ -1798,9 +1843,6 @@
 		<Data Name="WebSites">
 			<Value>Web Sites</Value>
 		</Data>
-		<Data Name="WebsiteVisitQuestion">
-			<Value>Do you want to visit the KeePass website now?</Value>
-		</Data>
 		<Data Name="WindowsFavorites">
 			<Value>Windows Favorites</Value>
 		</Data>
@@ -1855,6 +1897,9 @@
 		<Data Name="FileLoadFailed">
 			<Value>Failed to load the specified file!</Value>
 		</Data>
+		<Data Name="FileLockedWrite">
+			<Value>The file is locked, because the following user is currently writing to it:</Value>
+		</Data>
 		<Data Name="FileNewVerReq">
 			<Value>A newer KeePass version is required to open this file.</Value>
 		</Data>
@@ -1900,6 +1945,9 @@
 		<Data Name="OldFormat">
 			<Value>The selected file appears to be an old format</Value>
 		</Data>
+		<Data Name="TryAgainSecs">
+			<Value>Please try it again in a few seconds.</Value>
+		</Data>
 		<Data Name="UnknownHeaderId">
 			<Value>Unknown header ID!</Value>
 		</Data>
diff --git a/Translation/TrlUtil/AccelKeysCheck.cs b/Translation/TrlUtil/AccelKeysCheck.cs
index 162be8c..5b6b274 100644
--- a/Translation/TrlUtil/AccelKeysCheck.cs
+++ b/Translation/TrlUtil/AccelKeysCheck.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/Translation/TrlUtil/FormTrlMgr.cs b/Translation/TrlUtil/FormTrlMgr.cs
index 0aacb56..c30e8f0 100644
--- a/Translation/TrlUtil/FormTrlMgr.cs
+++ b/Translation/TrlUtil/FormTrlMgr.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -88,6 +88,7 @@ namespace TrlUtil
 			AddForm(l, new StatusProgressForm());
 			AddForm(l, new TanWizardForm());
 			AddForm(l, new TextEncodingForm());
+			AddForm(l, new UpdateCheckForm());
 			AddForm(l, new UrlSchemeForm());
 			AddForm(l, new UrlSchemesForm());
 
diff --git a/Translation/TrlUtil/KeePass1xLngImport.cs b/Translation/TrlUtil/KeePass1xLngImport.cs
index 593e918..b211e5e 100644
--- a/Translation/TrlUtil/KeePass1xLngImport.cs
+++ b/Translation/TrlUtil/KeePass1xLngImport.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/Translation/TrlUtil/MainForm.cs b/Translation/TrlUtil/MainForm.cs
index 1050c16..30e7d8b 100644
--- a/Translation/TrlUtil/MainForm.cs
+++ b/Translation/TrlUtil/MainForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -44,7 +44,6 @@ namespace TrlUtil
 		private string m_strFile = string.Empty;
 
 		private ImageList m_ilStr = new ImageList();
-		private Color m_clrFindBack;
 
 		private const string m_strFileFilter = "KeePass Translation (*.lngx)|*.lngx|All Files (*.*)|*.*";
 
@@ -69,7 +68,6 @@ namespace TrlUtil
 			this.Text += " " + PwDefs.VersionString;
 
 			m_trl.Forms = FormTrlMgr.CreateListOfCurrentVersion();
-			m_clrFindBack = m_tbFind.BackColor;
 			m_rtbUnusedText.SimpleTextOnly = true;
 
 			string strSearchTr = ((WinUtil.IsAtLeastWindowsVista ?
@@ -930,7 +928,7 @@ namespace TrlUtil
 
 		private void OnFindTextChanged(object sender, EventArgs e)
 		{
-			m_tbFind.BackColor = m_clrFindBack;
+			m_tbFind.ResetBackColor();
 		}
 
 		private void OnTabMainSelectedIndexChanged(object sender, EventArgs e)
diff --git a/Translation/TrlUtil/PreviewForm.cs b/Translation/TrlUtil/PreviewForm.cs
index ceab81a..ae8d778 100644
--- a/Translation/TrlUtil/PreviewForm.cs
+++ b/Translation/TrlUtil/PreviewForm.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
diff --git a/Translation/TrlUtil/Program.cs b/Translation/TrlUtil/Program.cs
index 8389f72..2c4bd53 100644
--- a/Translation/TrlUtil/Program.cs
+++ b/Translation/TrlUtil/Program.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -161,7 +161,7 @@ namespace TrlUtil
 						string strValue = xmlData.SelectSingleNode("Value").InnerText;
 						if(strValue.Contains("\""))
 						{
-							Console.WriteLine(strValue);
+							// Console.WriteLine(strValue);
 							strValue = strValue.Replace("\"", "\"\"");
 						}
 
diff --git a/Translation/TrlUtil/Properties/AssemblyInfo.cs b/Translation/TrlUtil/Properties/AssemblyInfo.cs
index bc18051..80a5c12 100644
--- a/Translation/TrlUtil/Properties/AssemblyInfo.cs
+++ b/Translation/TrlUtil/Properties/AssemblyInfo.cs
@@ -1,6 +1,6 @@
 /*
   KeePass Password Safe - The Open-Source Password Manager
-  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl at t-online.de>
+  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Dominik Reichl")]
 [assembly: AssemblyProduct("KeePass Translation Utility")]
-[assembly: AssemblyCopyright("Copyright © 2008-2011 Dominik Reichl")]
+[assembly: AssemblyCopyright("Copyright © 2008-2012 Dominik Reichl")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -38,5 +38,5 @@ using System.Runtime.InteropServices;
 [assembly: Guid("39aa6f93-a1c9-497f-bad2-cc42a61d5710")]
 
 // Assembly version information
-[assembly: AssemblyVersion("2.1.7.0")]
-[assembly: AssemblyFileVersion("2.1.7.0")]
+[assembly: AssemblyVersion("2.1.8.0")]
+[assembly: AssemblyFileVersion("2.1.8.0")]

-- 
keepass2



More information about the Pkg-cli-apps-commits mailing list