/// <summary>
        /// <see cref="Case.SetupInternal"/>
        /// </summary>
        protected override void SetupInternal()
        {
            base.SetupInternal();

            Bind(new LinkSessionConnected {
                LinkName = Name
            },
                 OnLinkSessionConnected);
            Bind(new LinkSessionDisconnected {
                LinkName = Name
            },
                 OnLinkSessionDisconnected);

            if (HasChannelStrategy)
            {
                ChannelStrategy.Link = this;
                ChannelStrategy.Setup();
            }
            if (HasHeartbeatStrategy)
            {
                HeartbeatStrategy.Link = this;
                HeartbeatStrategy.Setup();

                Bind(Hub.HeartbeatEvent, OnHeartbeatEvent);
            }
        }
        /// <summary>
        /// <see cref="Case.TeardownInternal"/>
        /// </summary>
        protected override void TeardownInternal()
        {
            if (HasHeartbeatStrategy)
            {
                HeartbeatStrategy.Teardown();
                HeartbeatStrategy.Link = null;
            }
            if (HasChannelStrategy)
            {
                ChannelStrategy.Teardown();
                ChannelStrategy.Link = null;
            }

            base.TeardownInternal();
        }
        /// <summary>
        /// Frees managed or unmanaged resources.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }

            if (HasChannelStrategy)
            {
                ChannelStrategy.Release();
            }

            rwlock.Dispose();

            base.Dispose(disposing);
        }
        /// <summary>
        /// Called when a new link session is ready for open.
        /// </summary>
        public void InitiateSession(LinkSession session)
        {
            if (HasChannelStrategy)
            {
                ChannelStrategy.BeforeSessionSetup(session);
            }
            if (HasHeartbeatStrategy)
            {
                HeartbeatStrategy.BeforeSessionSetup(session);
            }

            if (HasChannelStrategy)
            {
                ChannelStrategy.InitiateHandshake(session);
            }
            else
            {
                OnLinkSessionConnectedInternal(true, session);
            }
        }