/// <summary>
        /// Override of base: calls base to add parent and then registers actions and events.
        /// </summary>
        /// <param name="parent"></param>
        public override void AddParent(MobileControlSystemController parent)
        {
            base.AddParent(parent);

            // we add actions to the messaging system with a path, and a related action. Custom action
            // content objects can be handled in the controller's LineReceived method - and perhaps other
            // sub-controller parsing could be attached to these classes, so that the systemController
            // doesn't need to know about everything.

            // Source Changes and room off
            Parent.AddAction(string.Format(@"/room/{0}/status", Room.Key), new Action(() => SendFullStatus(Room)));

            var routeRoom = Room as IRunRouteAction;

            if (routeRoom != null)
            {
                Parent.AddAction(string.Format(@"/room/{0}/source", Room.Key), new Action <SourceSelectMessageContent>(c =>
                                                                                                                       routeRoom.RunRouteAction(c.SourceListItem)));
            }

            var defaultRoom = Room as IRunDefaultPresentRoute;

            if (defaultRoom != null)
            {
                Parent.AddAction(string.Format(@"/room/{0}/defaultsource", Room.Key), new Action(() => defaultRoom.RunDefaultPresentRoute()));
            }

            var volumeRoom = Room as IHasCurrentVolumeControls;

            if (volumeRoom != null)
            {
                Parent.AddAction(string.Format(@"/room/{0}/volumes/master/level", Room.Key), new Action <ushort>(u =>
                                                                                                                 (volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(u)));
                Parent.AddAction(string.Format(@"/room/{0}/volumes/master/muteToggle", Room.Key), new Action(() =>
                                                                                                             volumeRoom.CurrentVolumeControls.MuteToggle()));
                volumeRoom.CurrentVolumeDeviceChange += new EventHandler <VolumeDeviceChangeEventArgs>(Room_CurrentVolumeDeviceChange);

                // Registers for initial volume events, if possible
                var currentVolumeDevice = volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
                if (currentVolumeDevice != null)
                {
                    currentVolumeDevice.MuteFeedback.OutputChange        += MuteFeedback_OutputChange;
                    currentVolumeDevice.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
                }
            }

            var sscRoom = Room as IHasCurrentSourceInfoChange;

            if (sscRoom != null)
            {
                sscRoom.CurrentSourceChange += new SourceInfoChangeHandler(Room_CurrentSingleSourceChange);
            }

            var vcRoom = Room as IHasVideoCodec;

            if (vcRoom != null && vcRoom.VideoCodec != null)
            {
                var codec = vcRoom.VideoCodec;
                var key   = vcRoom.VideoCodec.Key + "-" + parent.Key;
                VCMessenger = new VideoCodecBaseMessenger(key, vcRoom.VideoCodec, "/device/videoCodec");
                VCMessenger.RegisterWithAppServer(Parent);

                vcRoom.IsSharingFeedback.OutputChange += new EventHandler <FeedbackEventArgs>(IsSharingFeedback_OutputChange);
            }

            var acRoom = Room as IHasAudioCodec;

            if (acRoom != null && acRoom.AudioCodec != null)
            {
                var codec = acRoom.AudioCodec;
                var key   = acRoom.AudioCodec.Key + "-" + parent.Key;
                ACMessenger = new AudioCodecBaseMessenger(key, acRoom.AudioCodec, "/device/audioCodec");
                ACMessenger.RegisterWithAppServer(Parent);
            }

            var defCallRm = Room as IRunDefaultCallRoute;

            if (defCallRm != null)
            {
                Parent.AddAction(string.Format(@"/room/{0}/activityVideo", Room.Key), new Action(() => defCallRm.RunDefaultCallRoute()));
            }

            Parent.AddAction(string.Format(@"/room/{0}/shutdownStart", Room.Key), new Action(() => Room.StartShutdown(eShutdownType.Manual)));
            Parent.AddAction(string.Format(@"/room/{0}/shutdownEnd", Room.Key), new Action(() => Room.ShutdownPromptTimer.Finish()));
            Parent.AddAction(string.Format(@"/room/{0}/shutdownCancel", Room.Key), new Action(() => Room.ShutdownPromptTimer.Cancel()));

            Room.OnFeedback.OutputChange            += OnFeedback_OutputChange;
            Room.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
            Room.IsWarmingUpFeedback.OutputChange   += IsWarmingUpFeedback_OutputChange;

            Room.ShutdownPromptTimer.HasStarted   += ShutdownPromptTimer_HasStarted;
            Room.ShutdownPromptTimer.HasFinished  += ShutdownPromptTimer_HasFinished;
            Room.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
        }
 /// <summary>
 /// Set the parent.  Does nothing else.  Override to add functionality such
 /// as adding actions to parent
 /// </summary>
 /// <param name="parent"></param>
 public virtual void AddParent(MobileControlSystemController parent)
 {
     Parent = parent;
 }