/// <summary>
        /// Maintenance task to ensure that the local node has valid successor node.  Roughly equivalent
        /// to what is called out in the Chord paper.
        /// </summary>
        /// <param name="sender">The worker thread the task is running on.</param>
        /// <param name="ea">Args (ignored here).</param>
        private void StabilizeSuccessors(object sender, DoWorkEventArgs ea)
        {
            BackgroundWorker me = (BackgroundWorker)sender;

            while (!me.CancellationPending)
            {
                try
                {
                    // check in successor and if it's bad, replace it with
                    // the next live entry in the successor cache
                    ChordNode succPredNode = ChordServer.GetPredecessor(this.Successor);
                    if (succPredNode != null)
                    {
                        if (ChordServer.IsIDInRange(succPredNode.ID, this.ID, this.Successor.ID))
                        {
                            this.Successor = succPredNode;
                        }

                        // ignoring return because bad node will be detected on next invocation
                        ChordServer.CallNotify(this.Successor, ChordServer.LocalNode);
                        GetSuccessorCache(this.Successor);
                    }
                    else
                    {
                        bool successorCacheHelped = false;
                        foreach (ChordNode entry in this.m_SuccessorCache)
                        {
                            ChordInstance instance = ChordServer.GetInstance(entry);
                            if (ChordServer.IsInstanceValid(instance))
                            {
                                this.Successor = entry;
                                ChordServer.CallNotify(this.Successor, ChordServer.LocalNode);
                                GetSuccessorCache(this.Successor);
                                successorCacheHelped = true;
                                break;
                            }
                        }

                        // if we get here, then we got no help and have no other recourse than to re-join using the initial seed...
                        if (!successorCacheHelped)
                        {
                            ChordServer.Log(LogLevel.Error, "StabilizeSuccessors", "Ring consistency error, Re-Joining Chord ring.");
                            Join(this.m_SeedNode, this.Host, this.Port);
                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    ChordServer.Log(LogLevel.Error, "Maintenance", "Error occured during StabilizeSuccessors ({0})", e.Message);
                }

                // TODO: this could be tweaked and/or made configurable elsewhere or passed in as arguments
                Thread.Sleep(5000);
            }
        }