/// <summary>
        /// This function is called by the underlying timers.
        /// </summary>
        /// <param name="whichTimer">Reference to the timer that caused this function call.</param>
        private void AlarmClockThreadFinishedHdl(AlarmClockThread whichTimer)
        {
            AlarmClock whichClock = null;

            lock (this.lockObj)
            {
                if (this.targetFunctions.ContainsKey(whichTimer) &&
                    this.parameters.ContainsKey(whichTimer) &&
                    this.alarmClocks.ContainsKey(whichTimer) &&
                    this.clockTimerMap.ContainsKey(this.alarmClocks[whichTimer]) &&
                    this.clockTimerMap[this.alarmClocks[whichTimer]] == whichTimer)
                {
                    whichClock = this.alarmClocks[whichTimer];
                }
            }

            if (whichClock != null)
            {
                TraceManager.WriteAllTrace(string.Format("AlarmClock-{0} timeout", whichClock.testID), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                this.alarmClkFinishedIface.AlarmClockFinished(whichClock);
            }
            else
            {
                throw new DssException("Invalid timer call.");
            }
        }
        /// <see cref="IDisposable.Dispose"/>
        public void Dispose()
        {
            if (this.dssThread != RCThread.CurrentThread)
            {
                throw new DssException("AlarmClockManager.Dispose must be called from the DSS-thread!");
            }

            /// Stop and dispose every unused timer.
            int numOfTimers = this.timers.Length;

            for (int i = 0; i < numOfTimers; i++)
            {
                AlarmClockThread timer = this.timers.Get();
                TraceManager.WriteAllTrace(string.Format("Get timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                timer.Stop();
                timer.Dispose();
                this.timers.Push(timer);
                TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
            }

            /// Stop and dispose every timer that are currently in use.
            foreach (KeyValuePair <AlarmClockThread, AlarmClock> item in this.alarmClocks)
            {
                AlarmClockThread timer = item.Key;
                timer.Stop();
                timer.Dispose();
            }
        }
        /// <see cref="IAlarmClockInvoke.CancelAlarmClock"/>
        public void CancelAlarmClock(AlarmClock whichClock)
        {
            if (this.dssThread != RCThread.CurrentThread)
            {
                throw new DssException("AlarmClockManager.CancelAlarmClock must be called from the DSS-thread!");
            }

            lock (this.lockObj)
            {
                if (this.clockTimerMap.ContainsKey(whichClock))
                {
                    AlarmClockThread correspondingTimer = this.clockTimerMap[whichClock];
                    correspondingTimer.Stop();
                }
                else
                {
                    TraceManager.WriteAllTrace("Warning! Invalid alarm clock cancel!", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                }
            }
        }
        /// <see cref="IAlarmClockInvoke.InvokeIfNecessary"/>
        public void InvokeIfNecessary(AlarmClock whichClock, bool invoke)
        {
            if (this.dssThread != RCThread.CurrentThread)
            {
                throw new DssException("AlarmClockManager.InvokeIfNecessary must be called from the DSS-thread!");
            }

            lock (this.lockObj)
            {
                if (this.clockTimerMap.ContainsKey(whichClock))
                {
                    AlarmClockThread correspondingTimer = this.clockTimerMap[whichClock];
                    if (this.alarmClocks.ContainsKey(correspondingTimer) &&
                        this.alarmClocks[correspondingTimer] == whichClock &&
                        this.targetFunctions.ContainsKey(correspondingTimer) &&
                        this.parameters.ContainsKey(correspondingTimer))
                    {
                        TraceManager.WriteAllTrace(string.Format("Invoking alarm clock @ {0}", DssRoot.Time), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                        if (invoke)
                        {
                            this.targetFunctions[correspondingTimer](whichClock, this.parameters[correspondingTimer]);
                        }
                        this.clockTimerMap.Remove(whichClock);
                        this.alarmClocks.Remove(correspondingTimer);
                        this.targetFunctions.Remove(correspondingTimer);
                        this.parameters.Remove(correspondingTimer);

                        this.timers.Push(correspondingTimer); /// Put the timer back to the FIFO
                        TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    }
                    else
                    {
                        TraceManager.WriteAllTrace("Warning! Invalid alarm clock invocation!", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    }
                }
                else
                {
                    TraceManager.WriteAllTrace("Warning! Invalid alarm clock invocation!", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                }
            }
        }
        /// <summary>
        /// Asks the AlarmClockManager to call the given function at the given time with the given parameter.
        /// </summary>
        /// <param name="when">The time when the call must be performed.</param>
        /// <param name="funcToCall">The function that must be called.</param>
        /// <param name="param">The parameter of the function to call with.</param>
        /// <returns>A reference to the allocated alarm clock.</returns>
        public AlarmClock SetAlarmClock(int when, AlarmFunction funcToCall, object param)
        {
            if (this.dssThread != RCThread.CurrentThread)
            {
                throw new DssException("AlarmClockManager.SetAlarmClock must be called from the DSS-thread!");
            }
            if (funcToCall == null)
            {
                throw new ArgumentNullException("funcToCall");
            }
            if (when < 0)
            {
                throw new ArgumentOutOfRangeException("when");
            }

            int currentTime = DssRoot.Time;

            if (when > currentTime)
            {
                /// Delayed invoke
                lock (this.lockObj)
                {
                    if (this.timers.Length == 0)
                    {
                        /// No free timer found --> create a new one
                        AlarmClockThread newTimer = new AlarmClockThread();
                        this.currentCapacity++;
                        this.timers = new Fifo <AlarmClockThread>(currentCapacity);
                        this.timers.Push(newTimer);
                        TraceManager.WriteAllTrace(string.Format("Delayed: New timer: {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                        TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    }
                    else
                    {
                        TraceManager.WriteAllTrace("Delayed: clock reuse", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    }

                    AlarmClockThread timerToUse = this.timers.Get();
                    TraceManager.WriteAllTrace(string.Format("Get timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    AlarmClock retClock = new AlarmClock(when, this);
                    this.targetFunctions.Add(timerToUse, funcToCall);
                    this.parameters.Add(timerToUse, param);
                    this.alarmClocks.Add(timerToUse, retClock);
                    this.clockTimerMap.Add(retClock, timerToUse);

                    timerToUse.Start(when - currentTime, this.AlarmClockThreadFinishedHdl, this.AlarmClockThreadFinishedHdl);
                    TraceManager.WriteAllTrace(string.Format("AlarmClock-{0} started", retClock.testID), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    return(retClock);
                }
            }
            else
            {
                /// Immediate invoke
                lock (this.lockObj)
                {
                    if (this.timers.Length == 0)
                    {
                        /// No free timer found --> create a new one
                        AlarmClockThread newTimer = new AlarmClockThread();
                        this.currentCapacity++;
                        this.timers = new Fifo <AlarmClockThread>(currentCapacity);
                        this.timers.Push(newTimer);
                        TraceManager.WriteAllTrace(string.Format("Immediate: New timer: {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                        TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    }
                    else
                    {
                        TraceManager.WriteAllTrace("Immediate: clock reuse", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    }

                    AlarmClockThread timerToUse = this.timers.Get();
                    TraceManager.WriteAllTrace(string.Format("Get timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    AlarmClock retClock = new AlarmClock(when, this);
                    this.targetFunctions.Add(timerToUse, funcToCall);
                    this.parameters.Add(timerToUse, param);
                    this.alarmClocks.Add(timerToUse, retClock);
                    this.clockTimerMap.Add(retClock, timerToUse);

                    TraceManager.WriteAllTrace(string.Format("AlarmClock-{0} started immediately", retClock.testID), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO);
                    this.alarmClkFinishedIface.AlarmClockFinished(retClock);
                    return(retClock);
                }
            }
        }