/// <summary>
        /// Creates a new SelfOptimizingDynamicSpatialIndex.
        /// </summary>
        /// <param name="geoFactory">An <see cref="IGeometryFactory"/> instance.</param>
        /// <param name="restructureStrategy">The strategy used to restructure the index.</param>
        /// <param name="restructureHeuristic">The heuristic to control when the index is restructured.</param>
        /// <param name="insertStrategy">The strategy used to insert entries into the index.</param>
        /// <param name="nodeSplitStrategy">The strategy used to split index nodes.</param>
        /// <param name="indexHeuristic">A heuristic used to balance the index for optimum efficiency.</param>
        /// <param name="idleMonitor">A monitor to determine idle conditions on the executing machine.</param>
        public SelfOptimizingDynamicSpatialIndex(IGeometryFactory geoFactory,
                                                 IIndexRestructureStrategy <IExtents, TItem> restructureStrategy,
                                                 RestructuringHuristic restructureHeuristic,
                                                 IItemInsertStrategy <IExtents, TItem> insertStrategy,
                                                 INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy,
                                                 DynamicRTreeBalanceHeuristic indexHeuristic,
                                                 IdleMonitor idleMonitor)
            : base(geoFactory, insertStrategy, nodeSplitStrategy, indexHeuristic)
        {
            _periodMilliseconds = restructureHeuristic.WhenToRestructure == RestructureOpportunity.Periodic
                                                                        ? (Int32)(restructureHeuristic.Period / 1000.0)
                                                                        : -1;

            _restructureStrategy    = restructureStrategy;
            _restructuringHeuristic = restructureHeuristic;
            _idleMonitor            = idleMonitor;

            _userIdleEvent    = new AutoResetEvent(false);
            _machineIdleEvent = new AutoResetEvent(false);
            _terminateEvent   = new ManualResetEvent(false);

            if (restructureHeuristic.WhenToRestructure != RestructureOpportunity.None)
            {
                _restructureThread = new Thread(doRestructure);
                _restructureThread.Start();
            }

            RestructureOpportunity idle = RestructureOpportunity.OnMachineIdle | RestructureOpportunity.OnUserIdle;

            if (((Int32)(restructureHeuristic.WhenToRestructure & idle)) > 0)
            {
                if (_idleMonitor == null)
                {
                    throw new ArgumentNullException("idleMonitor",
                                                    "If the restructuring heuristic has a value of anything but " +
                                                    "None for WhenToRestructure, the idleMonitor cannot be null.");
                }

                _idleMonitor.UserIdle    += _idleMonitor_UserIdle;
                _idleMonitor.UserBusy    += _idleMonitor_UserBusy;
                _idleMonitor.MachineIdle += _idleMonitor_MachineIdle;
                _idleMonitor.MachineBusy += _idleMonitor_MachineBusy;
            }
        }
 /// <summary>
 /// Creates a new restructuring heuristic with no period.
 /// </summary>
 /// <param name="whenToRestructure">A RestructureOpportunity enumeration value.</param>
 /// <param name="executionPercentage">
 /// A percentage value (0 to 100) which specifies the percent
 /// of the time that a restructure could run that it actually is run.
 /// </param>
 /// <param name="period">A value in milliseconds after which a restructure is triggered.</param>
 public RestructuringHuristic(RestructureOpportunity whenToRestructure, Double executionPercentage, Double period)
 {
     _whenToRestructure   = whenToRestructure;
     _executionPercentage = executionPercentage;
     _period = period;
 }
 /// <summary>
 /// Creates a new restructuring heuristic with no period.
 /// </summary>
 /// <param name="whenToRestructure">A RestructureOpportunity enumeration value.</param>
 /// <param name="executionPercentage">
 /// A percentage value (0 to 100) which specifies the percent
 /// of the time that a restructure could run that it actually is run.
 /// </param>
 public RestructuringHuristic(RestructureOpportunity whenToRestructure, Double executionPercentage)
     : this(whenToRestructure, executionPercentage, -1)
 {
 }
		/// <summary>
		/// Creates a new restructuring heuristic with no period.
		/// </summary>
		/// <param name="whenToRestructure">A RestructureOpportunity enumeration value.</param>
		/// <param name="executionPercentage">
		/// A percentage value (0 to 100) which specifies the percent 
		/// of the time that a restructure could run that it actually is run.
		/// </param>
		/// <param name="period">A value in milliseconds after which a restructure is triggered.</param>
		public RestructuringHuristic(RestructureOpportunity whenToRestructure, Double executionPercentage, Double period)
		{
			_whenToRestructure = whenToRestructure;
			_executionPercentage = executionPercentage;
			_period = period;
		}
		/// <summary>
		/// Creates a new restructuring heuristic with no period.
		/// </summary>
		/// <param name="whenToRestructure">A RestructureOpportunity enumeration value.</param>
		/// <param name="executionPercentage">
		/// A percentage value (0 to 100) which specifies the percent 
		/// of the time that a restructure could run that it actually is run.
		/// </param>
		public RestructuringHuristic(RestructureOpportunity whenToRestructure, Double executionPercentage)
			: this(whenToRestructure, executionPercentage, -1)
		{
		}