/// <summary>
        /// Perform the next step
        /// </summary>
        /// <param name="s">Null if it's the initial response</param>
        /// <param name="doc">Document to create Steps in</param>
        /// <returns>XML to send to the XMPP server.</returns>
        public override Step step(Step s, XmlDocument doc)
        {
            byte[] outBytes;
            byte[] inBytes = null;

            Step returnStep;

            if (s == null)
            {
                // First step.
                returnStep = new Auth(doc);
                ((Auth)returnStep).Mechanism = MechanismType.GSSAPI;

                SetCredentials();
            }
            else
            {
                returnStep = new Response(doc);
                inBytes = s.Bytes;
            }

            kerbClient.ExecuteKerberos(inBytes, out outBytes);
            returnStep.Bytes = outBytes;

            return returnStep;
        }
        /// <summary>
        /// Process the next DIGEST-MD5 step.
        /// </summary>
        /// <param name="s">The previous step.  Null for the first step</param>
        /// <param name="doc">Document to create next step in.</param>
        /// <returns></returns>
        /// <exception cref="AuthenticationFailedException">Thrown if authentication fails</exception>
        public override Step step(Step s, XmlDocument doc)
        {
            Step resp = null;

            if (s == null)
            { // first step
                Auth a = new Auth(doc);
                a.Mechanism = MechanismType.DIGEST_MD5;
                return a;
            }

            Debug.Assert(s is Challenge);
            populateDirectives(ENC.GetString(s.Bytes));
            validateStartDirectives();

            resp = new Response(doc);
            if (this["rspauth"] == null)  // we haven't authenticated yet
            {
                generateResponseString();
                resp.Bytes = generateResponse();
            }
            else // we have authenticated
            {
                // make sure what is in rspauth is correct
                if (!validateResponseAuth())
                {
                    throw new AuthenticationFailedException();
                }
            }
            return resp;
        }