/// <summary>
        /// Generic Deserialize method that will attempt to deserialize any class
        /// in the GCheckout.AutoGen namespace.
        /// </summary>
        /// <param name="Xml">The XML that should be made into an object.</param>
        /// <returns>The reconstituted object.</returns>
        public static object Deserialize(Stream Xml)
        {
            long originalPos = Xml.Position;
              //Keep the XmlReader from closing the stream on a failure.
              StreamWrapper wrap = new StreamWrapper(Xml);
              wrap.Position = 0;

              try {
            //get the name of the node, this is what we will use for the lookup.
            string nodeName = GetTopElement(wrap);

            string nameSpace = typeof(AutoGen.Hello).Namespace;
            Type[] types
              = System.Reflection.Assembly.GetExecutingAssembly().GetTypes();
            Type reflectedType = GetReflectedType(types, nameSpace, nodeName);

            //ok either the type is supported or it is not
            //if we could not find the correct type then we must have either
            //an incorrect dll for the message, or the message
            //is not a Google Checkout message. Return null if the type
            //can't be deserialized.
            if (reflectedType != null) {
              XmlSerializer myDeserializer = new XmlSerializer(reflectedType);
              object retVal = myDeserializer.Deserialize(wrap);
              wrap.Position = originalPos;
              return retVal;
            }
            else {
              System.Diagnostics.Debug.WriteLine("Deserialize was not able" +
            "To locate a message of type:" + nodeName + "");
              wrap.Position = originalPos;
              return null;
            }
              }
              catch (Exception e) {
            wrap.Position = 0;
            string passedXml;
            using (StreamReader reader = new StreamReader(wrap)) {
              passedXml = reader.ReadToEnd();
            }

            bool containsBom = false;
            if (wrap != null && wrap.Length >= 3) {
              byte[] theBom = Encoding.UTF8.GetPreamble();
              wrap.Position = 0;
              //try to determine we have a bom in the message,
              //which may cause the deserializer to fail.
              if (wrap.ReadByte() == theBom[0]
            && wrap.ReadByte() == theBom[1]
            && wrap.ReadByte() == theBom[2]) {
            containsBom = true;
              }
            }

            wrap.Position = originalPos;

            throw new ApplicationException(
              string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}.",
              passedXml, containsBom), e);
              }
        }