/// <summary>Determines the next step to establish a direct connection.</summary>
 /// <remarks>Determines the next step to establish a direct connection.</remarks>
 /// <param name="plan">the planned route</param>
 /// <param name="fact">the currently established route</param>
 /// <returns>
 /// one of the constants defined in this class, indicating
 /// either the next step to perform, or success, or failure
 /// </returns>
 protected internal virtual int DirectStep(RouteInfo plan, RouteInfo fact)
 {
     if (fact.GetHopCount() > 1)
     {
         return(Unreachable);
     }
     if (!plan.GetTargetHost().Equals(fact.GetTargetHost()))
     {
         return(Unreachable);
     }
     // If the security is too low, we could now suggest to layer
     // a secure protocol on the direct connection. Layering on direct
     // connections has not been supported in HttpClient 3.x, we don't
     // consider it here until there is a real-life use case for it.
     // Should we tolerate if security is better than planned?
     // (plan.isSecure() && !fact.isSecure())
     if (plan.IsSecure() != fact.IsSecure())
     {
         return(Unreachable);
     }
     // Local address has to match only if the plan specifies one.
     if ((plan.GetLocalAddress() != null) && !plan.GetLocalAddress().Equals(fact.GetLocalAddress
                                                                                ()))
     {
         return(Unreachable);
     }
     return(Complete);
 }
        /// <summary>Determines the next step to establish a connection via proxy.</summary>
        /// <remarks>Determines the next step to establish a connection via proxy.</remarks>
        /// <param name="plan">the planned route</param>
        /// <param name="fact">the currently established route</param>
        /// <returns>
        /// one of the constants defined in this class, indicating
        /// either the next step to perform, or success, or failure
        /// </returns>
        protected internal virtual int ProxiedStep(RouteInfo plan, RouteInfo fact)
        {
            if (fact.GetHopCount() <= 1)
            {
                return(Unreachable);
            }
            if (!plan.GetTargetHost().Equals(fact.GetTargetHost()))
            {
                return(Unreachable);
            }
            int phc = plan.GetHopCount();
            int fhc = fact.GetHopCount();

            if (phc < fhc)
            {
                return(Unreachable);
            }
            for (int i = 0; i < fhc - 1; i++)
            {
                if (!plan.GetHopTarget(i).Equals(fact.GetHopTarget(i)))
                {
                    return(Unreachable);
                }
            }
            // now we know that the target matches and proxies so far are the same
            if (phc > fhc)
            {
                return(TunnelProxy);
            }
            // need to extend the proxy chain
            // proxy chain and target are the same, check tunnelling and layering
            if ((fact.IsTunnelled() && !plan.IsTunnelled()) || (fact.IsLayered() && !plan.IsLayered
                                                                    ()))
            {
                return(Unreachable);
            }
            if (plan.IsTunnelled() && !fact.IsTunnelled())
            {
                return(TunnelTarget);
            }
            if (plan.IsLayered() && !fact.IsLayered())
            {
                return(LayerProtocol);
            }
            // tunnel and layering are the same, remains to check the security
            // Should we tolerate if security is better than planned?
            // (plan.isSecure() && !fact.isSecure())
            if (plan.IsSecure() != fact.IsSecure())
            {
                return(Unreachable);
            }
            return(Complete);
        }