diff -N -w -u -r keepass_old/KeePass/Forms/CharPickerForm.cs keepass_new/KeePass/Forms/CharPickerForm.cs
--- keepass_old/KeePass/Forms/CharPickerForm.cs	2009-08-29 18:28:18.000000000 -0400
+++ keepass_new/KeePass/Forms/CharPickerForm.cs	2009-11-15 12:26:57.727833000 -0500
@@ -122,9 +122,7 @@
 
 		private void OnBtnOK(object sender, EventArgs e)
 		{
-			byte[] pbUtf8 = m_secWord.ToUtf8();
-			m_psSelected = new ProtectedString(true, pbUtf8);
-			Array.Clear(pbUtf8, 0, pbUtf8.Length);
+			m_psSelected = m_secWord.GetProtectedString();
 		}
 
 		private void OnBtnCancel(object sender, EventArgs e)
diff -N -w -u -r keepass_old/KeePass/Forms/KeyCreationForm.cs keepass_new/KeePass/Forms/KeyCreationForm.cs
--- keepass_old/KeePass/Forms/KeyCreationForm.cs	2009-10-16 15:18:44.000000000 -0400
+++ keepass_new/KeePass/Forms/KeyCreationForm.cs	2009-11-15 12:27:45.409560000 -0500
@@ -164,7 +164,7 @@
 					return false;
 				}
 
-				byte[] pb = m_secPassword.ToUtf8();
+				byte[] pb = m_secPassword.GetProtectedString().ReadUtf8();
 
 				uint uMinQual = Program.Config.Security.MasterPassword.MinimumQuality;
 				if(QualityEstimation.EstimatePasswordBits(pb) < uMinQual)
@@ -297,7 +297,7 @@
 
 		private void ProcessTextChangedPassword(object sender, EventArgs e)
 		{
-			byte[] pbUTF8 = m_secPassword.ToUtf8();
+			byte[] pbUTF8 = m_secPassword.GetProtectedString().ReadUtf8();
 			uint uBits = QualityEstimation.EstimatePasswordBits(pbUTF8);
 			MemUtil.ZeroByteArray(pbUTF8);
 
diff -N -w -u -r keepass_old/KeePass/Forms/KeyPromptForm.cs keepass_new/KeePass/Forms/KeyPromptForm.cs
--- keepass_old/KeePass/Forms/KeyPromptForm.cs	2009-10-17 11:43:18.000000000 -0400
+++ keepass_new/KeePass/Forms/KeyPromptForm.cs	2009-11-15 12:28:03.918619000 -0500
@@ -204,7 +204,7 @@
 
 			if(m_cbPassword.Checked) // Use a password
 			{
-				byte[] pb = m_secPassword.ToUtf8();
+				byte[] pb = m_secPassword.GetProtectedString().ReadUtf8();
 				m_pKey.AddUserKey(new KcpPassword(pb));
 				Array.Clear(pb, 0, pb.Length);
 			}
diff -N -w -u -r keepass_old/KeePass/Forms/MainForm.cs keepass_new/KeePass/Forms/MainForm.cs
--- keepass_old/KeePass/Forms/MainForm.cs	2009-11-08 10:37:26.000000000 -0500
+++ keepass_new/KeePass/Forms/MainForm.cs	2009-11-15 12:32:15.516009000 -0500
@@ -701,6 +701,8 @@
 				RefreshEntriesList();
 				UpdateUIState(true);
 			}
+			if (!AppPolicy.Try(AppPolicyId.CopyToClipboard))//don't decrypt the password if we arn't allowed to do so by policy...
+				return;
 
 			if(ClipboardUtil.CopyAndMinimize(pe.Strings.ReadSafe(PwDefs.PasswordField),
 				true, this, pe, m_docMgr.ActiveDatabase))
diff -N -w -u -r keepass_old/KeePass/Forms/PwEntryForm.cs keepass_new/KeePass/Forms/PwEntryForm.cs
--- keepass_old/KeePass/Forms/PwEntryForm.cs	2009-11-09 14:33:10.000000000 -0500
+++ keepass_new/KeePass/Forms/PwEntryForm.cs	2009-11-15 15:59:59.732434000 -0500
@@ -259,10 +259,7 @@
 				m_vStrings.Set(PwDefs.UserNameField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectUserName,
 					m_tbUserName.Text));
 
-				byte[] pb = m_secPassword.ToUtf8();
-				m_vStrings.Set(PwDefs.PasswordField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectPassword,
-					pb));
-				MemUtil.ZeroByteArray(pb);
+				m_vStrings.Set(PwDefs.PasswordField, new ProtectedString(m_secPassword.GetProtectedString()));
 
 				m_vStrings.Set(PwDefs.UrlField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectUrl,
 					m_tbUrl.Text));
@@ -274,10 +271,9 @@
 				m_tbTitle.Text = m_vStrings.ReadSafe(PwDefs.TitleField);
 				m_tbUserName.Text = m_vStrings.ReadSafe(PwDefs.UserNameField);
 
-				byte[] pb = m_vStrings.GetSafe(PwDefs.PasswordField).ReadUtf8();
-				m_secPassword.SetPassword(pb);
-				m_secRepeat.SetPassword(pb);
-				MemUtil.ZeroByteArray(pb);
+				ProtectedString pstr = m_vStrings.GetSafe(PwDefs.PasswordField);
+				m_secPassword.SetProtectedString(pstr);
+				m_secRepeat.SetProtectedString(pstr);
 
 				m_tbUrl.Text = m_vStrings.ReadSafe(PwDefs.UrlField);
 				m_rtNotes.Text = m_vStrings.ReadSafe(PwDefs.NotesField);
@@ -577,7 +573,7 @@
 		{
 			if(m_bInitializing) return;
 
-			byte[] pb = m_secPassword.ToUtf8();
+			byte[] pb = m_secPassword.GetProtectedString().ReadUtf8();
 			uint uBits = QualityEstimation.EstimatePasswordBits(pb);
 			MemUtil.ZeroByteArray(pb);
 			m_lblQualityBitsText.Text = uBits.ToString() + " " + KPRes.Bits;
@@ -686,7 +682,7 @@
 					m_pwEntry.History.Remove(m_pwEntry.History.GetAt(
 						m_pwEntry.History.UCount - 1)); // Undo backup
 			}
-
+			m_pwEntry.Touch(true, true); // Touch *after* backup
 			if(this.EntrySaved != null) this.EntrySaved(this, EventArgs.Empty);
 		}
 
@@ -1263,10 +1259,10 @@
 		{
 			PwGeneratorForm pgf = new PwGeneratorForm();
 
-			byte[] pbCurPassword = m_secPassword.ToUtf8();
-			bool bAtLeastOneChar = (pbCurPassword.Length > 0);
-			ProtectedString ps = new ProtectedString(true, pbCurPassword);
-			Array.Clear(pbCurPassword, 0, pbCurPassword.Length);
+
+			ProtectedString ps = m_secPassword.GetProtectedString();
+			bool bAtLeastOneChar = ! ps.IsEmpty;
+
 			PwProfile opt = PwProfile.DeriveFromPassword(ps);
 
 			pgf.InitEx(bAtLeastOneChar ? opt : null, true, false);
@@ -1277,10 +1273,8 @@
 				PwGenerator.Generate(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_secPassword.SetProtectedString(psNew);
+				m_secRepeat.SetProtectedString(psNew);
 			}
 
 			EnableControlsEx();
@@ -1291,10 +1285,7 @@
 			PwProfile pwp = null;
 			if(e.ItemName == DeriveFromPrevious)
 			{
-				byte[] pbCur = m_secPassword.ToUtf8();
-				ProtectedString psCur = new ProtectedString(true, pbCur);
-				Array.Clear(pbCur, 0, pbCur.Length);
-				pwp = PwProfile.DeriveFromPassword(psCur);
+				pwp = PwProfile.DeriveFromPassword(m_secPassword.GetProtectedString());
 			}
 			else
 			{
@@ -1312,10 +1303,8 @@
 			{
 				ProtectedString psNew = new ProtectedString(true);
 				PwGenerator.Generate(psNew, pwp, null, Program.PwGeneratorPool);
-				byte[] pbNew = psNew.ReadUtf8();
-				m_secPassword.SetPassword(pbNew);
-				m_secRepeat.SetPassword(pbNew);
-				Array.Clear(pbNew, 0, pbNew.Length);
+				m_secPassword.SetProtectedString(psNew);
+				m_secRepeat.SetProtectedString(psNew);
 			}
 			else { Debug.Assert(false); }
 		}
@@ -1480,11 +1469,8 @@
 			string strRef = CreateFieldReference();
 			if(strRef.Length == 0) return;
 
-			string strPw = Encoding.UTF8.GetString(m_secPassword.ToUtf8());
-			string strRep = Encoding.UTF8.GetString(m_secRepeat.ToUtf8());
-
-			m_secPassword.SetPassword(Encoding.UTF8.GetBytes(strPw + strRef));
-			m_secRepeat.SetPassword(Encoding.UTF8.GetBytes(strRep + strRef));
+			m_secPassword.AppendProtectedString(strRef);
+			m_secRepeat.AppendProtectedString(strRef);
 		}
 
 		private void OnFieldRefInUrl(object sender, EventArgs e)
diff -N -w -u -r keepass_old/KeePass/UI/SecureEdit.cs keepass_new/KeePass/UI/SecureEdit.cs
--- keepass_old/KeePass/UI/SecureEdit.cs	2009-06-03 17:38:50.000000000 -0400
+++ keepass_new/KeePass/UI/SecureEdit.cs	2009-11-15 15:49:40.584223000 -0500
@@ -37,13 +37,7 @@
 		private TextBox m_tbPassword = null;
 		private EventHandler m_evTextChanged = null;
 		
-		// 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 control, 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 KeePassLib.Security.ProtectedString m_string;
 
 		private bool m_bBlockTextChanged = false;
 
@@ -53,8 +47,7 @@
 		{
 			get
 			{
-				if(m_secString != null) return (uint)m_secString.Length;
-				return (uint)m_strAlternativeSecString.Length;
+				return (uint)m_string.Length;
 			}
 		}
 
@@ -73,8 +66,7 @@
 		/// </summary>
 		public SecureEdit()
 		{
-			try { m_secString = new SecureString(); }
-			catch(NotSupportedException) { } // Windows 98 / ME
+			m_string = new KeePassLib.Security.ProtectedString(true);
 		}
 
 		~SecureEdit()
@@ -101,8 +93,7 @@
 			// Initialize to zero-length string
 			m_tbPassword.Text = string.Empty;
 
-			if(m_secString != null) m_secString.Clear();
-			else m_strAlternativeSecString = string.Empty;
+			m_string.Clear();
 
 			EnableProtection(bHidePassword);
 
@@ -200,7 +191,7 @@
 			if(m_tbPassword.UseSystemPasswordChar == false)
 			{
 				m_bBlockTextChanged = true;
-				m_tbPassword.Text = GetAsString();
+				m_tbPassword.Text = m_string.ReadString();
 				m_bBlockTextChanged = false;
 
 				if(m_evTextChanged != null) m_evTextChanged(m_tbPassword, EventArgs.Empty);
@@ -208,10 +199,7 @@
 			}
 
 			m_bBlockTextChanged = true;
-			if(m_secString != null)
-				m_tbPassword.Text = new string(m_chPasswordChar, m_secString.Length);
-			else
-				m_tbPassword.Text = new string(m_chPasswordChar, m_strAlternativeSecString.Length);
+			m_tbPassword.Text = new string(m_chPasswordChar, m_string.Length);
 			m_bBlockTextChanged = false;
 
 			m_tbPassword.SelectionStart = nSelStart;
@@ -220,113 +208,31 @@
 			if(m_evTextChanged != null) m_evTextChanged(m_tbPassword, EventArgs.Empty);
 		}
 
-		public byte[] ToUtf8()
-		{
-			Debug.Assert(sizeof(char) == 2);
-
-			if(m_secString != null)
+		public KeePassLib.Security.ProtectedString GetProtectedString()
 			{
-				char[] vChars = new char[m_secString.Length];
-				IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString);
-				for(int i = 0; i < m_secString.Length; ++i)
-					vChars[i] = (char)Marshal.ReadInt16(p, i * 2);
-				Marshal.ZeroFreeGlobalAllocUnicode(p);
-
-				byte[] pb = Encoding.UTF8.GetBytes(vChars);
-				Array.Clear(vChars, 0, vChars.Length);
-
-				return pb;
-			}
-			else return Encoding.UTF8.GetBytes(m_strAlternativeSecString);
+			return new KeePassLib.Security.ProtectedString(m_string);
 		}
 
-		private string GetAsString()
+		public void SetProtectedString(KeePassLib.Security.ProtectedString p_str)
 		{
-			if(m_secString != null)
-			{
-				IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString);
-				string str = Marshal.PtrToStringUni(p);
-				Marshal.ZeroFreeGlobalAllocUnicode(p);
-
-				return str;
-			}
-			else return m_strAlternativeSecString;
+			m_string = new KeePassLib.Security.ProtectedString(p_str);
+			ShowCurrentPassword(0, 0);
 		}
-
-		private void RemoveInsert(int nLeftRem, int nRightRem, string strInsert)
+		public void AppendProtectedString(string toAppend)
 		{
-			Debug.Assert(nLeftRem >= 0);
-
-			if(m_secString != null)
-			{
-				while(m_secString.Length > (nLeftRem + nRightRem))
-					m_secString.RemoveAt(nLeftRem);
-
-				for(int i = 0; i < strInsert.Length; ++i)
-					m_secString.InsertAt(nLeftRem + i, strInsert[i]);
+			m_string.AppendString(toAppend);
+			ShowCurrentPassword(0, 0);
 			}
-			else
+		private void RemoveInsert(int nLeftRem, int nRightRem, string strInsert)
 			{
-				StringBuilder sb = new StringBuilder(m_strAlternativeSecString);
-
-				while(sb.Length > (nLeftRem + nRightRem))
-					sb.Remove(nLeftRem, 1);
-
-				sb.Insert(nLeftRem, strInsert);
-
-				m_strAlternativeSecString = sb.ToString();
-			}
+			m_string.RemoveInsert(nLeftRem, nRightRem, strInsert);
 		}
 
 		public bool ContentsEqualTo(SecureEdit secOther)
 		{
 			Debug.Assert(secOther != null); if(secOther == null) return false;
 
-			byte[] pbThis = this.ToUtf8();
-			byte[] pbOther = secOther.ToUtf8();
-
-			bool bEqual = true;
-
-			if(pbThis.Length != pbOther.Length) bEqual = false;
-			else
-			{
-				for(int i = 0; i < pbThis.Length; ++i)
-				{
-					if(pbThis[i] != pbOther[i])
-					{
-						bEqual = false;
-						break;
-					}
-				}
-			}
-
-			Array.Clear(pbThis, 0, pbThis.Length);
-			Array.Clear(pbOther, 0, pbOther.Length);
-
-			return bEqual;
-		}
-
-		public void SetPassword(byte[] pbUtf8)
-		{
-			Debug.Assert(pbUtf8 != null);
-			if(pbUtf8 == null) throw new ArgumentNullException("pbUTF8");
-
-			if(m_secString != null)
-			{
-				m_secString.Clear();
-
-				UTF8Encoding utf8 = new UTF8Encoding();
-				char[] vChars = utf8.GetChars(pbUtf8);
-
-				for(int i = 0; i < vChars.Length; ++i)
-				{
-					m_secString.AppendChar(vChars[i]);
-					vChars[i] = char.MinValue;
-				}
-			}
-			else m_strAlternativeSecString = Encoding.UTF8.GetString(pbUtf8);
-
-			ShowCurrentPassword(0, 0);
+			return secOther.m_string.Equals(m_string);
 		}
 
 		private void OnGotFocus(object sender, EventArgs e)
diff -N -w -u -r keepass_old/KeePassLib/Collections/ProtectedStringDictionary.cs keepass_new/KeePassLib/Collections/ProtectedStringDictionary.cs
--- keepass_old/KeePassLib/Collections/ProtectedStringDictionary.cs	2009-08-21 16:59:42.000000000 -0400
+++ keepass_new/KeePassLib/Collections/ProtectedStringDictionary.cs	2009-11-15 13:46:51.709559000 -0500
@@ -104,7 +104,7 @@
 			{
 				ProtectedString ps = dict.Get(kvp.Key);
 				if(ps == null) return false;
-				if(ps.ReadString() != kvp.Value.ReadString()) return false;
+				if(! ps.Equals(kvp)) return false;
 			}
 
 			return true;
diff -N -w -u -r keepass_old/KeePassLib/PwGroup.cs keepass_new/KeePassLib/PwGroup.cs
--- keepass_old/KeePassLib/PwGroup.cs	2009-10-10 10:58:48.000000000 -0400
+++ keepass_new/KeePassLib/PwGroup.cs	2009-11-15 15:46:35.218087000 -0500
@@ -37,6 +37,21 @@
 		public const bool DefaultAutoTypeEnabled = true;
 		public const bool DefaultSearchingEnabled = true;
 
+		public event EventHandler<GroupTouchedArgs> GroupTouched;
+		public sealed class GroupTouchedArgs : EventArgs
+	{
+		private bool m_modified;
+
+		public bool was_modified { get { return m_modified; } }
+
+		/// <summary>
+		/// Default constructor.
+		/// </summary>
+		public GroupTouchedArgs(bool modified)
+		{
+			m_modified = modified;
+		}
+	}
 		private PwObjectList<PwGroup> m_listGroups = new PwObjectList<PwGroup>();
 		private PwObjectList<PwEntry> m_listEntries = new PwObjectList<PwEntry>();
 		private PwGroup m_pParentGroup = null;
@@ -450,7 +465,8 @@
 			++m_uUsageCount;
 
 			if(bModified) m_tLastMod = m_tLastAccess;
-
+			if (GroupTouched != null)
+				GroupTouched(this, new GroupTouchedArgs(bModified));
 			if(bTouchParents && (m_pParentGroup != null))
 				m_pParentGroup.Touch(bModified, true);
 		}
@@ -1197,6 +1213,7 @@
 			if(bTakeOwnership) pe.ParentGroup = this;
 
 			if(bUpdateLocationChangedOfEntry) pe.LocationChanged = DateTime.Now;
+			Touch(true);
 		}
 	}
 }
diff -N -w -u -r keepass_old/KeePassLib/Security/ProtectedString.cs keepass_new/KeePassLib/Security/ProtectedString.cs
--- keepass_old/KeePassLib/Security/ProtectedString.cs	2009-10-25 18:29:56.000000000 -0400
+++ keepass_new/KeePassLib/Security/ProtectedString.cs	2009-11-15 17:26:04.565490000 -0500
@@ -195,9 +195,67 @@
 			catch(NotSupportedException) { } // Windows 98 / ME
 
 			m_bIsProtected = psTemplate.m_bIsProtected;
-			SetString(psTemplate.ReadString());
-		}
+			if (psTemplate.m_secString != null)
+				this.m_secString = psTemplate.m_secString.Copy();
+			this.m_strAlternativeSecString = psTemplate.m_strAlternativeSecString;
+			this.m_strPlainText = psTemplate.m_strPlainText;
+			this.m_bIsProtected = psTemplate.m_bIsProtected;
+			if (psTemplate.m_xbEncrypted != null)
+				this.m_xbEncrypted = psTemplate.m_xbEncrypted.Copy();
+			
+		}
+		private static bool securestrings_are_equal(SecureString s1, SecureString s2)
+		{
+			if (s1 != s2 && (s1 == null || s2 == null) )
+				return false;
+			if (s1.Length != s2.Length)
+				return false;
+			IntPtr ptr1 = Marshal.SecureStringToGlobalAllocUnicode(s1);
+			IntPtr ptr2 = Marshal.SecureStringToGlobalAllocUnicode(s2);
+			char b1 = (char)1;
+			char b2 = (char)1;
+			int pos = 0;
+			bool failed_match = false;
+			while (b1 != 0 && b2 != 0)
+			{
+				b1 = (char)Marshal.ReadInt16(ptr1, pos*2);
+				b2 = (char)Marshal.ReadInt16(ptr2, pos*2);
+				if (b1 != b2)
+				{
+					failed_match = true;
+					break;
+				}
+				pos++;
+		}
+			Marshal.ZeroFreeGlobalAllocUnicode(ptr1);
+			Marshal.ZeroFreeGlobalAllocUnicode(ptr2);
+			return !failed_match;
+		}
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+		public override Boolean Equals(object obj)
+		{
+			if (obj.GetType() != typeof(ProtectedString))
+				return false;
+			ProtectedString compare_to = (ProtectedString)obj;
+
+			if ( (m_xbEncrypted == null || compare_to.m_xbEncrypted == null) && compare_to.m_xbEncrypted != m_xbEncrypted)
+				return false;
+			if (m_xbEncrypted != null)
+				return m_xbEncrypted.Equals(compare_to.m_xbEncrypted);
+
+
+			if (m_secString != null || compare_to.m_secString != null)
+				return securestrings_are_equal(m_secString, compare_to.m_secString);
+
+			if (compare_to.m_strAlternativeSecString != this.m_strAlternativeSecString)
+				return false;
 
+
+			return true;
+		}
 		/// <summary>
 		/// Construct a new protected string. The string is initialized
 		/// to the value passed in the <c>XorredBuffer</c> object.
@@ -284,28 +342,41 @@
 
 			// String must not contain any null character
 			Debug.Assert(strNewValue.IndexOf((char)0) < 0);
-
+			AppendString(strNewValue);
+		}
+		/// <summary>
+		/// Append a new string value to the object.
+		/// </summary>
+		/// <param name="strAppend">New string to append. 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 AppendString(string strAppend)
+		{
+			Debug.Assert(m_xbEncrypted == null);
+			Debug.Assert(strAppend != null); if (strAppend == null) throw new ArgumentNullException("strAppend");
 			if(m_bIsProtected)
 			{
 				if(m_secString != null)
 				{
 					char ch;
-					for(int i = 0; i < strNewValue.Length; ++i)
+					for (int i = 0; i < strAppend.Length; ++i)
 					{
-						ch = strNewValue[i];
+						ch = strAppend[i];
 						if(ch == 0) throw new ArgumentException();
 
 						m_secString.AppendChar(ch);
 					}
 				}
-				else m_strAlternativeSecString = strNewValue;
+				else m_strAlternativeSecString += strAppend;
 			}
 			else // Currently not protected
 			{
-				m_strPlainText = strNewValue;
+				m_strPlainText += strAppend;
 			}
 		}
-
 		/// <summary>
 		/// Convert the protected string to a normal string object.
 		/// Be careful with this function, the returned string object
@@ -391,6 +462,39 @@
 			return Encoding.UTF8.GetBytes(m_strPlainText); // Unprotected string
 		}
 
+		public void RemoveInsert(int nLeftRem, int nRightRem, string strInsert)
+		{
+			Debug.Assert(nLeftRem >= 0);
+			if (m_xbEncrypted != null)
+			{
+				byte[] pb = m_xbEncrypted.ReadPlainText();
+				SetString(Encoding.UTF8.GetString(pb, 0, pb.Length));
+			}
+
+			
+			if(m_bIsProtected && m_secString != null)
+			{
+				while(m_secString.Length > (nLeftRem + nRightRem))
+					m_secString.RemoveAt(nLeftRem);
+
+				for(int i = 0; i < strInsert.Length; ++i)
+					m_secString.InsertAt(nLeftRem + i, strInsert[i]);
+			}
+			else
+			{
+				String str = m_bIsProtected ? m_strAlternativeSecString : m_strPlainText;
+				StringBuilder sb = new StringBuilder(str);
+
+				while(sb.Length > (nLeftRem + nRightRem))
+					sb.Remove(nLeftRem, 1);
+
+				sb.Insert(nLeftRem, strInsert);
+				if (m_bIsProtected)
+					m_strAlternativeSecString = sb.ToString();
+				else
+					m_strPlainText = sb.ToString();
+			}
+		}
 		/// <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
@@ -416,10 +520,29 @@
 			}
 			else // Not using XorredBuffer
 			{
-				byte[] pbData = ReadUtf8();
+				byte[] randomPad;
+				byte[] pbData;
+#if !KeePassLibSD
+				if (m_bIsProtected && m_secString != null)
+				{
+					IntPtr ptr = Marshal.SecureStringToGlobalAllocUnicode(m_secString);
+					int str_len=0;
+					str_len = m_secString.Length;
+
+					randomPad = crsRandomSource.GetRandomBytes((uint)str_len*2);
+					Debug.Assert(randomPad.Length == str_len*2);
+					pbData = new byte[str_len*2];
+					char [] read_char = new char[1];
+					int arr_pos = 0,encoded_len=0;
+					for (int pos = 0; pos < str_len; pos++)
+					{
+						read_char[0] = (char)Marshal.ReadInt16(ptr, pos * 2);
+						encoded_len=Encoding.UTF8.GetBytes(read_char,0,1,pbData,pos);
+						for (int i = 0; i < encoded_len;i++)
+							pbData[arr_pos + i] ^= randomPad[arr_pos+i];
+						arr_pos += encoded_len;
+					}
+					Marshal.ZeroFreeGlobalAllocUnicode(ptr);
+					byte[] ret_arr = new byte[arr_pos];
+					Array.Copy(pbData, ret_arr, arr_pos);
+					return ret_arr;
+				}
+#endif
+				pbData = ReadUtf8();
 				uint uLen = (uint)pbData.Length;
 
-				byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
+				randomPad = crsRandomSource.GetRandomBytes(uLen);
 				Debug.Assert(randomPad.Length == uLen);
 
 				for(uint i = 0; i < uLen; i++)
diff -N -w -u -r keepass_old/KeePassLib/Security/XorredBuffer.cs keepass_new/KeePassLib/Security/XorredBuffer.cs
--- keepass_old/KeePassLib/Security/XorredBuffer.cs	2009-01-01 15:06:06.000000000 -0500
+++ keepass_new/KeePassLib/Security/XorredBuffer.cs	2009-11-15 14:23:04.013211000 -0500
@@ -64,7 +64,28 @@
 			m_pbData = pbProtectedData;
 			m_pbXorPad = pbXorPad;
 		}
-
+		public XorredBuffer Copy()
+		{
+			return new XorredBuffer((byte [])m_pbData.Clone(), (byte [])m_pbXorPad.Clone());
+		}
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+		public override bool Equals(object obj)
+		{
+			if (obj.GetType() != typeof(XorredBuffer))
+				return false;
+			XorredBuffer compare_to = (XorredBuffer)obj;
+			if (compare_to.Length != Length)
+				return false;
+			XorredBuffer dupe = compare_to.Copy();
+			dupe.ChangeKey(m_pbXorPad);
+			for (int i = 0; i < m_pbData.Length; i++)
+				if (dupe.m_pbData[i] != m_pbData[i])
+					return false;
+			return true;
+		}
 		private void Decrypt()
 		{
 			Debug.Assert((m_pbData.Length == m_pbXorPad.Length) || (m_pbData.Length == 0));
