public void Constructor_ConstructWithValueType()
		{
			Padlock p = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(10, p);

			using (p.Lock())
			{
				Assert.AreEqual(i.Value, 10);
			}
		}
		public void Constructor_ConstructWithReferenceType()
		{
			Padlock p = new Padlock();

			//Uri is a random reference type;
			ThreadShared<Uri> i = new ThreadShared<Uri>(new Uri("http://example.com"), p);

			using (p.Lock())
			{
				Assert.AreEqual(i.Value, new Uri("http://example.com"));
			}
		}
		public void ValueGettersAreEqual()
		{
			Padlock p1 = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(0, p1);

			using (p1.Lock())
			{
				Assert.AreEqual(i.Value, i._);
				i.Value++;

				Assert.AreEqual(i.Value, i._);
				Assert.AreEqual(i.Value, 1);
				Assert.AreEqual(i._, 1);

				i._++;
				Assert.AreEqual(i.Value, i._);
				Assert.AreEqual(i.Value, 2);
				Assert.AreEqual(i._, 2);
			}
		}
		public void ExceptionThrownWhileLockHeld()
		{
			Padlock p1 = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(0, p1);

			try
			{
				using (p1.Lock())
				{
					i.Value++;
					throw new InvalidOperationException();
				}
			}
			catch (InvalidOperationException) {	}

			//Locks should have been released.  Create a new thread
			//to obtain the lock to ensure no deadlocks ensue.

			Thread secondThread = new Thread(delegate()
				{
					using (p1.Lock())
					{
						i.Value++;
					}
				});

			secondThread.Start();
			secondThread.Join();

			using (p1.Lock())
			{
				Assert.AreEqual(i.Value, 2);
			}
		}
		public void OnePadlockToMultipleResources()
		{
			Padlock p1 = new Padlock();
			ThreadShared<int> i1 = new ThreadShared<int>(0, p1);
			ThreadShared<int> i2 = new ThreadShared<int>(0, p1);

			//Can access both ThreadShared in same block...
			using (p1.Lock())
			{
				i1.Value++;
				i2.Value++;
			}

			//... or individually
			using (p1.Lock())
			{
				i1.Value++;
			}

			using (p1.Lock())
			{
				i2.Value++;
			}

			using(p1.Lock())
			{
				Assert.AreEqual(i1.Value, 2);
				Assert.AreEqual(i2.Value, 2);
				Assert.AreEqual(i1.Value, i2.Value);
			}
		}
		private void RecursiveFunction(int maxRecursionDepth, int currentDepth, Padlock p, ThreadShared<int> i)
		{
			if (currentDepth < maxRecursionDepth)
			{
				using (p.Lock())
				{
					i.Value++;
					RecursiveFunction(maxRecursionDepth, ++currentDepth, p, i);
				}
			}
		}
		public void LockTakenRecursively()
		{
			Padlock p1 = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(0, p1);
			RecursiveFunction(5, 0, p1, i);

			using (p1.Lock())
			{
				Assert.AreEqual(i.Value, 5);
			}
		}
		public void TwoLocksBothTaken()
		{
			Padlock p1 = new Padlock();
			Padlock p2 = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(0, p1, p2);

			using (p1.Lock())
			{
				using (p2.Lock())
				{
					i.Value++;
					Assert.AreEqual(i.Value, 1);
				}
			}
		}
		public void TwoLocksSecondNotTaken()
		{
			Padlock p1 = new Padlock();
			Padlock p2 = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(0, p1, p2);

			//Access value outside of both locks.
			using (p1.Lock())
			{
				i.Value++;
			}
		}
		public void OneLockTaken()
		{
			Padlock p1 = new Padlock();
			ThreadShared<int> i = new ThreadShared<int>(0, p1);

			using (p1.Lock())
			{
				i.Value++;
				Assert.AreEqual(i.Value, 1);
			}
		}