diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj
index a7fdc014..d925d883 100644
--- a/src/KeePassLib2Android/KeePassLib2Android.csproj
+++ b/src/KeePassLib2Android/KeePassLib2Android.csproj
@@ -113,7 +113,6 @@
     
     
     
-    
     
     
     
diff --git a/src/KeePassLib2Android/Serialization/AsynchronousBufferedXmlReader.cs b/src/KeePassLib2Android/Serialization/AsynchronousBufferedXmlReader.cs
deleted file mode 100644
index d10ba1cb..00000000
--- a/src/KeePassLib2Android/Serialization/AsynchronousBufferedXmlReader.cs
+++ /dev/null
@@ -1,367 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-using System.Threading;
-using System.Xml;
-using System.Diagnostics;
-
-namespace KeePassLib.Serialization
-{
-	public class AsynchronousBufferedXmlReader : XmlReader
-	{
-		/// 
-		/// An element which indicates the end of the XML document has been reached.
-		/// 
-		private static readonly Element EndMarker = new Element();
-
-		/// 
-		/// The next buffered element available for reading.
-		/// Volatility: only read/written to by non-buffering thread. Passed to the buffer thread as an initial parameter.
-		/// 
-		Element mBufferQueueHead = new Element(); // Start off with the pre-document element. No content, yet.
-
-		private readonly Thread mWorkerThread;
-		private readonly AutoResetEvent mWaitForBuffer = new AutoResetEvent(false);
-		/// 
-		/// True while the reader thread is stalled waiting for buffering.
-		/// Volaitlity: Only written by read thread. Only read by buffer thread
-		/// 
-		private volatile bool mWaitingForBuffer;
-
-#if TRACE
-		private Stopwatch mReadWaitTimer = new Stopwatch();
-		private Stopwatch mBufferCompletedTimer = new Stopwatch();
-#endif
-
-		/// 
-		/// Testing helper method
-		/// 
-		/// 
-		/// 
-		public static XmlReader FullyBuffer(Stream input)
-		{
-			var reader = new AsynchronousBufferedXmlReader();
-			reader.ReadStreamWorker(input);
-			return reader;
-		}
-
-		private AsynchronousBufferedXmlReader()
-		{
-			// Once the end is reached, it stays there.
-			EndMarker.NextElement = EndMarker;
-		}
-
-		public AsynchronousBufferedXmlReader(Stream input) : this()
-		{
-			mWorkerThread = new Thread(ReadStreamWorker) { Name = GetType().Name };
-			mWorkerThread.Start(input);
-		}
-
-		#region Buffering
-		private void ReadStreamWorker(object state)
-		{
-			var input = (Stream)state;
-
-			var xr = XmlReader.Create(input, KdbxFile.CreateStdXmlReaderSettings());
-
-			/// 
-			/// The last buffered element available for reading.
-			/// 
-			Element bufferQueueTail = mBufferQueueHead;
-
-			/// 
-			/// The element currently being buffered. Not yet available for reading.
-			/// 
-			Element currentElement = null;
-
-			while (xr.Read())
-			{
-				switch (xr.NodeType)
-				{
-					case XmlNodeType.Element:
-						// Start a new element
-						if (currentElement != null)
-						{
-							// Add the previous current element to the tail of the buffer
-							bufferQueueTail.NextElement = currentElement;
-							bufferQueueTail = currentElement;
-							if (mWaitingForBuffer) mWaitForBuffer.Set(); // Signal that a new element is available in the buffer
-						}
-
-						currentElement = new Element { Name = xr.Name };
-
-						// Process attributes - current optimisation, all elements have 0 or 1 attribute
-						if (xr.MoveToNextAttribute())
-						{
-#if DEBUG
-							Debug.Assert(xr.AttributeCount == 1);
-							currentElement.AttributeName = xr.Name;
-#endif
-							currentElement.AttributeValue = xr.Value;
-						}
-
-						currentElement.IsEmpty = xr.IsEmptyElement;
-
-						break;
-
-					case XmlNodeType.Text:
-						currentElement.Value = xr.Value;
-						currentElement.IsEmpty = true; // Mark as empty because it will have no end element written for it
-						break;
-
-					case XmlNodeType.EndElement:
-						Debug.Assert(currentElement != null, "Ending an element that was never started");
-						
-						// If this is an element with children (not one with a value) add an end element marker to the queue
-						if (currentElement.Value == null || currentElement.Name != xr.Name)
-						{
-							bufferQueueTail.NextElement = currentElement;
-							bufferQueueTail = currentElement;
-							if (mWaitingForBuffer) mWaitForBuffer.Set(); // Signal that a new element is available in the buffer
-
-							currentElement = new Element { Name = xr.Name, IsEndElement = true };
-						}
-						break;
-				}
-			}
-
-			// Conclude the document, add the final element to the buffer and mark the ending
-			currentElement.NextElement = EndMarker;
-			bufferQueueTail.NextElement = currentElement;
-			bufferQueueTail = currentElement;
-			mWaitForBuffer.Set(); // Signal that final element is available in the buffer (regardless of wait flag, to avoid race condition)
-#if TRACE
-			mBufferCompletedTimer.Start();
-#endif
-		}
-		#endregion
-
-		private class Element
-		{
-			/// 
-			/// Link to the next buffered element.
-			/// Volatility: Written to by buffer thread only. Read by both threads
-			/// 
-			public volatile Element NextElement;
-			
-			public string Name;
-			
-			/// 
-			/// If this element marks the end of an xml element with child nodes, the IsEndElement will be true, and Value must be null.
-			/// 
-			public bool IsEndElement;
-
-			/// 
-			/// Set true if this represents an empty element
-			/// 
-			public bool IsEmpty;
-
-			/// 
-			/// If Value is non-null, then there will be no corresponding Element with IsEndElement created.
-			/// 
-			public string Value;
-
-			// Currently KDBX has a maximum of one attribute per element, so no need for a dictionary here, and the name is only used for debug asserts
-#if DEBUG
-			public string AttributeName;
-#endif
-			public string AttributeValue;
-		}
-
-		#region Custom XmlReader implementation for usage by KdbxFile only
-		public override bool Read()
-		{
-			Element nextElement;
-			while ((nextElement = mBufferQueueHead.NextElement) == null)
-			{
-#if TRACE
-				mReadWaitTimer.Start();
-#endif
-				mWaitingForBuffer = true;
-				mWaitForBuffer.WaitOne();
-				mWaitingForBuffer = false;
-
-#if TRACE
-				mReadWaitTimer.Stop();
-#endif
-			}
-			mBufferQueueHead = mBufferQueueHead.NextElement;
-
-
-#if TRACE
-			if (mBufferQueueHead == EndMarker)
-			{
-				Debug.WriteLine(String.Format("Asynchronous Buffered XmlReader waited for a total of: {0}ms, buffer completed {1}ms ahead of read", mReadWaitTimer.ElapsedMilliseconds, mBufferCompletedTimer.ElapsedMilliseconds));
-			}
-#endif
-			return mBufferQueueHead != EndMarker;
-		}
-
-		public override string ReadElementString()
-		{
-			var result = mBufferQueueHead.Value ?? String.Empty; // ReadElementString returns empty strings for null content
-			Read(); // Read element string always skips to the start of the next element
-			return result;
-		}
-
-		public override XmlNodeType NodeType
-		{
-			get 
-			{
-				return mBufferQueueHead.IsEndElement ? XmlNodeType.EndElement : XmlNodeType.Element;
-			}
-		}
-
-		public override bool IsEmptyElement
-		{
-			get
-			{
-				return mBufferQueueHead.IsEmpty;
-			}
-		}
-
-		public override string Name
-		{
-			get
-			{
-				return mBufferQueueHead.Name;
-			}
-		}
-
-		public override bool HasAttributes
-		{
-			get
-			{
-				return mBufferQueueHead.AttributeValue != null;
-			}
-		}
-
-		public override bool MoveToAttribute(string name)
-		{
-#if DEBUG
-			Debug.Assert(mBufferQueueHead.AttributeName == name);
-#endif
-
-			return true;
-		}
-
-		public override string Value
-		{
-			get
-			{
-				return mBufferQueueHead.AttributeValue;
-			}
-		}
-
-
-		public override bool MoveToElement()
-		{
-			return true;
-		}
-		#endregion
-
-		#region Unimplemented XmlReader overrides
-
-		public override int AttributeCount
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override string BaseURI
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override void Close()
-		{
-			throw new NotImplementedException();
-		}
-
-		public override int Depth
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override bool EOF
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override string GetAttribute(int i)
-		{
-			throw new NotImplementedException();
-		}
-
-		public override string GetAttribute(string name, string namespaceURI)
-		{
-			throw new NotImplementedException();
-		}
-
-		public override string GetAttribute(string name)
-		{
-			throw new NotImplementedException();
-		}
-
-		public override bool HasValue
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override string LocalName
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override string LookupNamespace(string prefix)
-		{
-			throw new NotImplementedException();
-		}
-
-		public override bool MoveToAttribute(string name, string ns)
-		{
-			throw new NotImplementedException();
-		}
-
-		public override bool MoveToFirstAttribute()
-		{
-			throw new NotImplementedException();
-		}
-
-		public override bool MoveToNextAttribute()
-		{
-			throw new NotImplementedException();
-		}
-
-		public override XmlNameTable NameTable
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override string NamespaceURI
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override string Prefix
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override bool ReadAttributeValue()
-		{
-			throw new NotImplementedException();
-		}
-
-		public override ReadState ReadState
-		{
-			get { throw new NotImplementedException(); }
-		}
-
-		public override void ResolveEntity()
-		{
-			throw new NotImplementedException();
-		}
-		#endregion
-	}
-}
diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
index 65c2aa55..03456962 100644
--- a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
+++ b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
@@ -70,8 +70,6 @@ namespace KeePassLib.Serialization
 			Debug.Assert(sSource != null);
 			if(sSource == null) throw new ArgumentNullException("sSource");
 
-			var stopWatch = Stopwatch.StartNew();
-
 			m_format = kdbFormat;
 			m_slLogger = slLogger;
 
@@ -129,33 +127,7 @@ namespace KeePassLib.Serialization
 				}
 				else m_randomStream = null; // No random stream for plain-text files
 
-				Debug.WriteLine(String.Format("Crypto setup: {0}ms", stopWatch.ElapsedMilliseconds));
-				stopWatch.Restart();
-
-				/*
-				var memStream = new MemoryStream((int)hashedStream.Length);
-				CopyStream(readerStream, memStream);
-				readerStream = memStream;
-				Debug.WriteLine(String.Format("CopyStream: {0}ms", stopWatch.ElapsedMilliseconds));
-
-
-				stopWatch.Restart();
-				 */
-
-				//var bufferedXmlReader = AsynchronousBufferedXmlReader.FullyBuffer(readerStream);
-				//Debug.WriteLine(String.Format("ReadToBuffer: {0}ms", stopWatch.ElapsedMilliseconds));
-
-				if (Java.Lang.Runtime.GetRuntime().AvailableProcessors() > 1)
-				{
-					ReadDocumentStreamed(new AsynchronousBufferedXmlReader(readerStream), hashedStream);
-					Debug.WriteLine(String.Format("ReadDocumentStreamed: {0}ms  multi-threaded", stopWatch.ElapsedMilliseconds));
-				}
-				else
-				{
-					ReadXmlStreamed(readerStream, hashedStream);
-					Debug.WriteLine(String.Format("ReadXmlStreamed: {0}ms single-threaded", stopWatch.ElapsedMilliseconds));
-				}
-				stopWatch.Restart();
+				ReadXmlStreamed(readerStream, hashedStream);
 				// ReadXmlDom(readerStream);
 
 				readerStream.Close();
@@ -166,26 +138,9 @@ namespace KeePassLib.Serialization
 			{
 				throw new CryptographicException(KLRes.FileCorrupted);
 			}
-			finally 
-			{
-				
-				CommonCleanUpRead(sSource, hashedStream);
-				Debug.WriteLine(String.Format("Close and Clean Up: {0}ms", stopWatch.ElapsedMilliseconds));
-			}
+			finally { CommonCleanUpRead(sSource, hashedStream); }
 		}
 
-		/*
-		public static void CopyStream(Stream input, Stream output)
-		{
-			byte[] buffer = new byte[32768];
-			int read;
-			while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
-			{
-				output.Write(buffer, 0, read);
-			}
-			output.Seek(0, SeekOrigin.Begin);
-		}*/
-
 		private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream)
 		{
 			hashedStream.Close();
diff --git a/src/keepass2android/Database.cs b/src/keepass2android/Database.cs
index 6e03e980..c8eee74d 100644
--- a/src/keepass2android/Database.cs
+++ b/src/keepass2android/Database.cs
@@ -120,8 +120,6 @@ namespace keepass2android
 		
 		public void LoadData(Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status)
 		{
-			var stopWatch = System.Diagnostics.Stopwatch.StartNew();
-			
 			mIoc = iocInfo;
 
 			KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase();
@@ -140,14 +138,8 @@ namespace keepass2android
 				}
 			}
 
-			System.Diagnostics.Debug.WriteLine(String.Format("LoadData Pre-open: {0}ms", stopWatch.ElapsedMilliseconds));
-			stopWatch.Restart();
-
 			pwDatabase.Open(iocInfo, key, status);
 
-			System.Diagnostics.Debug.WriteLine(String.Format("LoadData Open: {0}ms", stopWatch.ElapsedMilliseconds));
-			stopWatch.Restart();
-
 			if (iocInfo.IsLocalFile())
 			{
 				mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(iocInfo.Path);
@@ -163,8 +155,6 @@ namespace keepass2android
 			Loaded = true;
 			pm = pwDatabase;
 			searchHelper = new SearchDbHelper(ctx);
-
-			System.Diagnostics.Debug.WriteLine(String.Format("LoadData Post-open: {0}ms", stopWatch.ElapsedMilliseconds));
 		}
 
 		bool quickUnlockEnabled = false;
@@ -197,7 +187,12 @@ namespace keepass2android
 
 		public PwGroup Search(SearchParameters searchParams)
 		{
-			return searchHelper.search(this, searchParams);
+			return Search(searchParams, null);
+		}
+
+		public PwGroup Search(SearchParameters searchParams, IDictionary resultContexts)
+		{
+			return searchHelper.search(this, searchParams, resultContexts);
 		}