Index: /branches/eraser6/DefaultPlugins/EraseFirstLast16KB.cs
===================================================================
--- /branches/eraser6/DefaultPlugins/EraseFirstLast16KB.cs	(revision 327)
+++ /branches/eraser6/DefaultPlugins/EraseFirstLast16KB.cs	(revision 328)
@@ -4,5 +4,7 @@
 
 using Eraser.Manager;
+using Eraser.Util;
 using System.IO;
+using System.Threading;
 
 namespace Eraser.DefaultPlugins
@@ -12,5 +14,5 @@
 		public override string Name
 		{
-			get { return "First/last 16KB Erasure"; }
+			get { return S._("First/last 16KB Erasure"); }
 		}
 
@@ -50,24 +52,37 @@
 			//less.
 			if (erasureLength != long.MaxValue)
-				throw new ArgumentException("The amount of data erased should not be " +
-					"limited, since this is a self-limiting erasure method.");
+				throw new ArgumentException(S._("The amount of data erased should not be " +
+					"limited, since this is a self-limiting erasure method."));
 
-			ErasureMethod method = Method;
+			try
+			{
+				//Acquire a lock on the cached method object and set it if unset.
+				cachedMethodSemaphore.WaitOne();
+				if (cachedMethod == null)
+					cachedMethod = Method;
 
-			//If the target stream is shorter than 16kb, just forward it to the default
-			//function.
-			if (strm.Length < dataSize)
+				//If the target stream is shorter than 16kb, just forward it to the default
+				//function.
+				if (strm.Length < dataSize)
+				{
+					cachedMethod.Erase(strm, erasureLength, prng, callback);
+					return;
+				}
+
+				//Seek to the beginning and write 16kb.
+				strm.Seek(0, SeekOrigin.Begin);
+				cachedMethod.Erase(strm, dataSize, prng, callback);
+
+				//Seek to the end - 16kb, and write.
+				strm.Seek(-dataSize, SeekOrigin.End);
+				cachedMethod.Erase(strm, long.MaxValue, prng, callback);
+			}
+			finally
 			{
-				method.Erase(strm, erasureLength, prng, callback);
-				return;
+				//Check if no other threads are using the cached erasure method.
+				if (cachedMethodSemaphore.Release() == int.MaxValue - 1)
+					//If so, we no longer need to cache.
+					cachedMethod = null;
 			}
-
-			//Seek to the beginning and write 16kb.
-			strm.Seek(0, SeekOrigin.Begin);
-			method.Erase(strm, dataSize, prng, callback);
-
-			//Seek to the end - 16kb, and write.
-			strm.Seek(-dataSize, SeekOrigin.End);
-			method.Erase(strm, long.MaxValue, prng, callback);
 		}
 
@@ -76,12 +91,18 @@
 			get
 			{
-				//Try to retrieve the default erasure method.
+				//If there are threads locking the cached method variable just
+				//return that
+				if (cachedMethod != null)
+					return cachedMethod;
+
+				//Try to retrieve the set erasure method
 				ErasureMethod defaultMethod = ErasureMethodManager.GetInstance(
-					ManagerLibrary.Instance.Settings.DefaultFileErasureMethod);
+					(Guid)DefaultPlugin.Settings["FL16Method"]);
 
-				//If we are the default, use the default pseudorandom pass.
-				if (defaultMethod.GUID == GUID)
-					defaultMethod = ErasureMethodManager.GetInstance(new Guid(
-						"{BF8BA267-231A-4085-9BF9-204DE65A6641}"));
+				//If we have no default or we are the default then throw an exception
+				if (defaultMethod == null || defaultMethod.GUID == GUID)
+					throw new InvalidOperationException(S._("The First/last 16KB erasure method " +
+						"requires another erasure method to erase the file.\n\nThis can " +
+						"be set in the Plugin Settings dialog."));
 
 				return defaultMethod;
@@ -93,4 +114,16 @@
 		/// </summary>
 		private const long dataSize = 16 * 1024;
+
+		/// <summary>
+		/// The cached erasure method. This is used when erasing so that the properties
+		/// of this class is not inconsistent in the event that the method of erasure
+		/// changes while executing.
+		/// </summary>
+		ErasureMethod cachedMethod = null;
+
+		/// <summary>
+		/// Tracks the number of erasures locking the cached method variable.
+		/// </summary>
+		Semaphore cachedMethodSemaphore = new Semaphore(int.MaxValue, int.MaxValue);
 	}
 }
