/// <summary>
        /// Enter a critical section.
        /// </summary>
        /// <param name="obj">The object to use.</param>
        /// <returns>The disposable section holding the lock.</returns>
        public static IDisposable Enter(object obj)
        {
            bool isLockTaken = false;

            try
            {
                Monitor.Enter(obj, ref isLockTaken);

                // If we got this far shoud always be true.
                Debug.Assert(isLockTaken, "Lock is taken.");
#if DEBUG
                lock (RgLocks)
                {
                    if (HeldLocks == null)
                    {
                        HeldLocks = new Stack <LockInfo>();
                    }

                    LockInfo lockInfo          = FindLock(obj);
                    LockInfo potentionDeadlock = null;
                    foreach (LockInfo currentLock in HeldLocks)
                    {
                        // Recursive lock ok.
                        if (currentLock == lockInfo)
                        {
                            potentionDeadlock = null;
                            continue;
                        }

                        if (currentLock.IsDependent(lockInfo))
                        {
                            potentionDeadlock = currentLock;
                        }
                    }

                    Debug.Assert(potentionDeadlock == null, "Potention Deadlock");
                    bool isRec = lockInfo.OwningThread != -1;
                    Debug.Assert(lockInfo.OwningThread == -1 || lockInfo.OwningThread == Thread.CurrentThread.ManagedThreadId, "Lock owned or managed thread does not own lock.");
                    lockInfo.OwningThread = Thread.CurrentThread.ManagedThreadId;
                    if (HeldLocks.Count != 0 && potentionDeadlock == null && !isRec)
                    {
                        lockInfo.AddDependent(HeldLocks.Peek());
                    }

                    HeldLocks.Push(lockInfo);
                    return(new ExitOnDispose(obj, lockInfo, isRec));
                }
#else
                return(new ExitOnDispose(obj));
#endif
            }
            catch
            {
                // If for some resons we messed up, release lock.
                if (isLockTaken)
                {
                    Monitor.Exit(obj);
                }

                throw;
            }
        }