static SoapHeaderCollection ReadHeaders (SoapTypeStubInfo typeStubInfo, SoapBindingUse methodUse, XmlTextReader xmlReader)
		{
			SoapHeaderCollection headers = new SoapHeaderCollection ();
			while (! (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == WebServiceHelper.SoapEnvelopeNamespace))
			{
				if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Header" 
				    && xmlReader.NamespaceURI == WebServiceHelper.SoapEnvelopeNamespace && !xmlReader.IsEmptyElement)
				{
					xmlReader.ReadStartElement ();
					xmlReader.MoveToContent ();
					
					while (xmlReader.NodeType != XmlNodeType.Element && xmlReader.NodeType != XmlNodeType.EndElement)
						xmlReader.Skip ();
						
					xmlReader.MoveToContent ();
					
					if (xmlReader.NodeType == XmlNodeType.Element) {
						XmlQualifiedName qname = new XmlQualifiedName (xmlReader.LocalName, xmlReader.NamespaceURI);
						XmlSerializer headerSerializer = typeStubInfo.GetHeaderSerializer (qname, methodUse);
						if (headerSerializer != null)
						{
							SoapHeader header = (SoapHeader) headerSerializer.Deserialize (xmlReader);
							headers.Add (header);
						}
						else
						{
							XmlDocument doc = new XmlDocument ();
							XmlElement elem = (XmlElement) doc.ReadNode (xmlReader);
							headers.Add (new SoapUnknownHeader (elem));
						}
					}
					
					while (xmlReader.NodeType != XmlNodeType.EndElement)
						xmlReader.Skip ();
						
					xmlReader.ReadEndElement ();
				}
				else
					xmlReader.Skip ();
			}
			return headers;
		}
		public static void WriteSoapMessage (XmlTextWriter xtw, SoapTypeStubInfo info, SoapBindingUse methodUse, XmlSerializer bodySerializer, object bodyContent, SoapHeaderCollection headers)
		{
			xtw.WriteStartDocument ();
			xtw.WriteStartElement ("soap", "Envelope", WebServiceHelper.SoapEnvelopeNamespace);
			xtw.WriteAttributeString ("xmlns", "xsi", null, XmlSchema.InstanceNamespace);
			xtw.WriteAttributeString ("xmlns", "xsd", null, XmlSchema.Namespace);

			// Serialize headers
			if (headers != null)
			{
				foreach (SoapHeader header in headers) 
				{
					XmlSerializer ser = info.GetHeaderSerializer (header.GetType(), methodUse);
					xtw.WriteStartElement ("soap", "Header", WebServiceHelper.SoapEnvelopeNamespace);
					ser.Serialize (xtw, header);
					xtw.WriteEndElement ();
				}
			}

			// Serialize body
			xtw.WriteStartElement ("soap", "Body", WebServiceHelper.SoapEnvelopeNamespace);
			
			if (methodUse == SoapBindingUse.Encoded)
				xtw.WriteAttributeString ("encodingStyle", WebServiceHelper.SoapEnvelopeNamespace, "http://schemas.xmlsoap.org/soap/encoding/");
				
			bodySerializer.Serialize (xtw, bodyContent);

			xtw.WriteEndElement ();
			xtw.WriteEndElement ();
			xtw.Flush ();
		}