[coop] Temporarily restore MonoThreadInfo when TLS destructor runs. Fixes #43099
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Description / MessageContractExporter.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Description
5 {
6     using System;
7     using System.Collections.Generic;
8     using System.Diagnostics.CodeAnalysis;
9     using System.Globalization;
10     using System.IO;
11     using System.Reflection;
12     using System.Runtime;
13     using System.Runtime.Serialization;
14     using System.ServiceModel;
15     using System.ServiceModel.Dispatcher;
16     using System.Xml;
17     using System.Xml.Schema;
18     using System.Xml.Serialization;
19     using WsdlNS = System.Web.Services.Description;
20
21     abstract class MessageContractExporter
22     {
23         readonly protected WsdlContractConversionContext contractContext;
24         readonly protected WsdlExporter exporter;
25         readonly protected OperationDescription operation;
26         readonly protected IOperationBehavior extension;
27
28         static internal void ExportMessageBinding(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext, Type messageContractExporterType, OperationDescription operation)
29         {
30             new MessageBindingExporter(exporter, endpointContext).ExportMessageBinding(operation, messageContractExporterType);
31
32         }
33
34         protected abstract object OnExportMessageContract();
35         protected abstract void ExportHeaders(int messageIndex, object state);
36         protected abstract void ExportBody(int messageIndex, object state);
37
38         protected abstract void ExportKnownTypes();
39         protected abstract bool IsRpcStyle();
40         protected abstract bool IsEncoded();
41         protected abstract object GetExtensionData();
42
43         protected MessageExportContext ExportedMessages
44         {
45             get { return GetMessageExportContext(exporter); }
46         }
47
48         void AddElementToSchema(XmlSchemaElement element, string elementNs, XmlSchemaSet schemaSet)
49         {
50             OperationDescription parentOperation = this.operation;
51             if (parentOperation.OperationMethod != null)
52             {
53                 XmlQualifiedName qname = new XmlQualifiedName(element.Name, elementNs);
54
55                 OperationElement existingElement;
56                 if (ExportedMessages.ElementTypes.TryGetValue(qname, out existingElement))
57                 {
58                     if (existingElement.Operation.OperationMethod == parentOperation.OperationMethod)
59                         return;
60                     if (!SchemaHelper.IsMatch(element, existingElement.Element))
61                     {
62                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CannotHaveTwoOperationsWithTheSameElement5, parentOperation.OperationMethod.DeclaringType, parentOperation.OperationMethod.Name, qname, existingElement.Operation.OperationMethod.DeclaringType, existingElement.Operation.Name)));
63                     }
64                     return;
65                 }
66                 else
67                 {
68                     ExportedMessages.ElementTypes.Add(qname, new OperationElement(element, parentOperation));
69                 }
70             }
71             SchemaHelper.AddElementToSchema(element, SchemaHelper.GetSchema(elementNs, schemaSet), schemaSet);
72         }
73
74         static MessageExportContext GetMessageExportContext(WsdlExporter exporter)
75         {
76             object messageExportContext;
77             if (!exporter.State.TryGetValue(typeof(MessageExportContext), out messageExportContext))
78             {
79                 messageExportContext = new MessageExportContext();
80                 exporter.State[typeof(MessageExportContext)] = messageExportContext;
81             }
82             return (MessageExportContext)messageExportContext;
83         }
84
85         protected MessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
86         {
87             this.exporter = exporter;
88             this.contractContext = context;
89             this.operation = operation;
90             this.extension = extension;
91         }
92
93         internal void ExportMessageContract()
94         {
95             if (extension == null)
96                 return;
97
98             object state = OnExportMessageContract();
99
100             OperationFormatter.Validate(operation, IsRpcStyle(), IsEncoded());
101             ExportKnownTypes();
102
103             for (int messageIndex = 0; messageIndex < operation.Messages.Count; messageIndex++)
104                 ExportMessage(messageIndex, state);
105
106             if (!operation.IsOneWay)
107             {
108                 ExportFaults(state);
109             }
110
111             foreach (XmlSchema schema in exporter.GeneratedXmlSchemas.Schemas())
112                 EnsureXsdImport(schema.TargetNamespace, contractContext.WsdlPortType.ServiceDescription);
113         }
114
115         void ExportMessage(int messageIndex, object state)
116         {
117             try
118             {
119                 MessageDescription description = operation.Messages[messageIndex];
120                 WsdlNS.Message wsdlMessage;
121
122                 if (CreateMessage(description, messageIndex, out wsdlMessage))
123                 {
124                     if (description.IsUntypedMessage)
125                     {
126                         ExportAnyMessage(wsdlMessage, description.Body.ReturnValue ?? description.Body.Parts[0]);
127                         return;
128                     }
129                     bool isRequest = (messageIndex == 0);
130                     StreamFormatter streamFormatter = StreamFormatter.Create(description, operation.Name, isRequest);
131                     if (streamFormatter != null)
132                     {
133                         ExportStreamBody(wsdlMessage, streamFormatter.WrapperName, streamFormatter.WrapperNamespace, streamFormatter.PartName, streamFormatter.PartNamespace, IsRpcStyle(), false /*IsOperationInherited(operation)*/);
134                     }
135                     else
136                     {
137                         ExportBody(messageIndex, state);
138                     }
139                 }
140                 if (!description.IsUntypedMessage)
141                 {
142                     ExportHeaders(messageIndex, state);
143                 }
144             }
145             finally
146             {
147                 Compile();
148             }
149         }
150
151         protected virtual void ExportFaults(object state)
152         {
153             foreach (FaultDescription fault in operation.Faults)
154             {
155                 ExportFault(fault);
156             }
157         }
158
159         protected bool IsOperationInherited()
160         {
161             return operation.DeclaringContract != contractContext.Contract;
162         }
163
164         void ExportAnyMessage(WsdlNS.Message message, MessagePartDescription part)
165         {
166             XmlSchemaSet schemas = this.exporter.GeneratedXmlSchemas;
167             XmlSchema schema = SchemaHelper.GetSchema(DataContractSerializerMessageContractImporter.GenericMessageTypeName.Namespace, schemas);
168
169             if (!schema.SchemaTypes.Contains(DataContractSerializerMessageContractImporter.GenericMessageTypeName))
170             {
171                 XmlSchemaComplexType genericMessageType = new XmlSchemaComplexType();
172                 genericMessageType.Name = DataContractSerializerMessageContractImporter.GenericMessageTypeName.Name;
173                 XmlSchemaSequence bodySequence = new XmlSchemaSequence();
174                 genericMessageType.Particle = bodySequence;
175
176                 XmlSchemaAny anyElement = new XmlSchemaAny();
177                 anyElement.MinOccurs = 0;
178                 anyElement.MaxOccurs = decimal.MaxValue;
179                 anyElement.Namespace = "##any";
180
181                 bodySequence.Items.Add(anyElement);
182
183                 SchemaHelper.AddTypeToSchema(genericMessageType, schema, schemas);
184             }
185             string partName = string.IsNullOrEmpty(part.UniquePartName) ? part.Name : part.UniquePartName;
186             WsdlNS.MessagePart wsdlPart = AddMessagePart(message, partName, XmlQualifiedName.Empty, DataContractSerializerMessageContractImporter.GenericMessageTypeName);
187             part.UniquePartName = wsdlPart.Name;
188         }
189
190         protected void ExportStreamBody(WsdlNS.Message message, string wrapperName, string wrapperNs, string partName, string partNs, bool isRpc, bool skipSchemaExport)
191         {
192             XmlSchemaSet schemas = this.exporter.GeneratedXmlSchemas;
193             XmlSchema schema = SchemaHelper.GetSchema(DataContractSerializerMessageContractImporter.StreamBodyTypeName.Namespace, schemas);
194             if (!schema.SchemaTypes.Contains(DataContractSerializerMessageContractImporter.StreamBodyTypeName))
195             {
196                 XmlSchemaSimpleType streamBodyType = new XmlSchemaSimpleType();
197                 streamBodyType.Name = DataContractSerializerMessageContractImporter.StreamBodyTypeName.Name;
198                 XmlSchemaSimpleTypeRestriction contentRestriction = new XmlSchemaSimpleTypeRestriction();
199                 contentRestriction.BaseTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Base64Binary).QualifiedName;
200                 streamBodyType.Content = contentRestriction;
201                 SchemaHelper.AddTypeToSchema(streamBodyType, schema, schemas);
202             }
203             XmlSchemaSequence wrapperSequence = null;
204             if (!isRpc && wrapperName != null)
205                 wrapperSequence = ExportWrappedPart(message, wrapperName, wrapperNs, schemas, skipSchemaExport);
206             MessagePartDescription streamPart = new MessagePartDescription(partName, partNs);
207             ExportMessagePart(message, streamPart, DataContractSerializerMessageContractImporter.StreamBodyTypeName, null/*xsdType*/, false/*isOptional*/, false/*isNillable*/, skipSchemaExport, !isRpc, wrapperNs, wrapperSequence, schemas);
208         }
209
210         void ExportFault(FaultDescription fault)
211         {
212             WsdlNS.Message faultMessage = new WsdlNS.Message();
213             faultMessage.Name = GetFaultMessageName(fault.Name);
214
215             XmlQualifiedName elementName = ExportFaultElement(fault);
216             this.contractContext.WsdlPortType.ServiceDescription.Messages.Add(faultMessage);
217             AddMessagePart(faultMessage, "detail", elementName, null);
218
219             // create a wsdl:fault to put inside the wsdl:portType/wsdl:operation
220             WsdlNS.OperationFault operationFault = contractContext.GetOperationFault(fault);
221             WsdlExporter.WSAddressingHelper.AddActionAttribute(fault.Action, operationFault, this.exporter.PolicyVersion);
222             operationFault.Message = new XmlQualifiedName(faultMessage.Name, faultMessage.ServiceDescription.TargetNamespace);
223         }
224
225         XmlQualifiedName ExportFaultElement(FaultDescription fault)
226         {
227             XmlSchemaType xsdType;
228             XmlQualifiedName typeName = ExportType(fault.DetailType, fault.Name, operation.Name, out xsdType);
229             XmlQualifiedName elementName;
230             if (XmlName.IsNullOrEmpty(fault.ElementName))
231             {
232                 elementName = DataContractExporter.GetRootElementName(fault.DetailType);
233                 if (elementName == null)
234                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxFaultTypeAnonymous, operation.Name, fault.DetailType.FullName)));
235             }
236             else
237                 elementName = new XmlQualifiedName(fault.ElementName.EncodedName, fault.Namespace);
238             ExportGlobalElement(elementName.Name, elementName.Namespace, true/*isNillable*/, typeName, xsdType, this.exporter.GeneratedXmlSchemas);
239             return elementName;
240         }
241
242         protected XsdDataContractExporter DataContractExporter
243         {
244             get
245             {
246                 object dataContractExporter;
247                 if (!exporter.State.TryGetValue(typeof(XsdDataContractExporter), out dataContractExporter))
248                 {
249                     dataContractExporter = new XsdDataContractExporter(this.exporter.GeneratedXmlSchemas);
250                     exporter.State.Add(typeof(XsdDataContractExporter), dataContractExporter);
251                 }
252                 return (XsdDataContractExporter)dataContractExporter;
253             }
254         }
255
256         protected XmlQualifiedName ExportType(Type type, string partName, string operationName, out XmlSchemaType xsdType)
257         {
258             xsdType = null;
259             if (type == null)
260                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxExportMustHaveType, operationName, partName)));
261             if (type == typeof(void))
262                 return null;
263
264             DataContractExporter.Export(type);
265             XmlQualifiedName typeName = DataContractExporter.GetSchemaTypeName(type);
266             if (IsNullOrEmpty(typeName))
267                 xsdType = DataContractExporter.GetSchemaType(type);
268             return typeName;
269         }
270
271         protected XmlSchemaSet SchemaSet
272         {
273             get
274             {
275                 return exporter.GeneratedXmlSchemas;
276             }
277         }
278
279         static protected WsdlNS.MessagePart AddMessagePart(WsdlNS.Message message, string partName, XmlQualifiedName elementName, XmlQualifiedName typeName)
280         {
281             if (message.Parts[partName] != null)
282             {
283                 if (IsNullOrEmpty(elementName))
284                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxPartNameMustBeUniqueInRpc, partName)));
285                 int i = 1;
286                 while (message.Parts[partName + i] != null)
287                 {
288                     if (i == Int32.MaxValue)
289                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxTooManyPartsWithSameName, partName)));
290                     i++;
291                 }
292                 partName = partName + i.ToString(CultureInfo.InvariantCulture);
293             }
294             WsdlNS.MessagePart part = new WsdlNS.MessagePart();
295             part.Name = partName;
296             part.Element = elementName;
297             part.Type = typeName;
298             message.Parts.Add(part);
299             EnsureXsdImport(IsNullOrEmpty(elementName) ? typeName.Namespace : elementName.Namespace, message.ServiceDescription);
300             return part;
301         }
302
303         static void EnsureXsdImport(string ns, WsdlNS.ServiceDescription wsdl)
304         {
305             string refNs = wsdl.TargetNamespace;
306             if (!refNs.EndsWith("/", StringComparison.Ordinal))
307                 refNs = refNs + "/Imports";
308             else
309                 refNs += "Imports";
310             if (refNs == ns)
311                 refNs = wsdl.TargetNamespace;
312
313             XmlSchema xsd = GetContainedSchema(wsdl, refNs);
314             if (xsd != null)
315             {
316                 foreach (object include in xsd.Includes)
317                 {
318                     XmlSchemaImport import = include as XmlSchemaImport;
319                     if (import != null && SchemaHelper.NamespacesEqual(import.Namespace, ns))
320                         return;
321                 }
322             }
323             else
324             {
325                 xsd = new XmlSchema();
326                 xsd.TargetNamespace = refNs;
327                 wsdl.Types.Schemas.Add(xsd);
328             }
329
330             XmlSchemaImport imp = new XmlSchemaImport();
331             if (ns != null && ns.Length > 0)
332                 imp.Namespace = ns;
333             xsd.Includes.Add(imp);
334         }
335
336         static XmlSchema GetContainedSchema(WsdlNS.ServiceDescription wsdl, string ns)
337         {
338             foreach (XmlSchema xsd in wsdl.Types.Schemas)
339                 if (SchemaHelper.NamespacesEqual(xsd.TargetNamespace, ns))
340                     return xsd;
341
342             return null;
343         }
344
345
346         static protected bool IsNullOrEmpty(XmlQualifiedName qname)
347         {
348             return qname == null || qname.IsEmpty;
349         }
350
351         protected void ExportGlobalElement(string elementName, string elementNs, bool isNillable, XmlQualifiedName typeName, XmlSchemaType xsdType, XmlSchemaSet schemaSet)
352         {
353 #if DEBUG
354             Fx.Assert(NamingHelper.IsValidNCName(elementName), "Name value has to be a valid NCName.");
355             if (xsdType == null)
356                 Fx.Assert(NamingHelper.IsValidNCName(typeName.Name), "Name value has to be a valid NCName.");
357 #endif
358             XmlSchemaElement element = new XmlSchemaElement();
359             element.Name = elementName;
360             if (xsdType != null)
361                 element.SchemaType = xsdType;
362             else
363                 element.SchemaTypeName = typeName;
364             element.IsNillable = isNillable;
365             AddElementToSchema(element, elementNs, schemaSet);
366         }
367
368         void ExportLocalElement(string wrapperNs, string elementName, string elementNs, XmlQualifiedName typeName, XmlSchemaType xsdType, bool multiple, bool isOptional, bool isNillable, XmlSchemaSequence sequence, XmlSchemaSet schemaSet)
369         {
370 #if DEBUG
371             Fx.Assert(NamingHelper.IsValidNCName(elementName), "Name value has to be a valid NCName.");
372             if (xsdType == null)
373                 Fx.Assert(NamingHelper.IsValidNCName(typeName.Name), "Name value has to be a valid NCName.");
374 #endif
375             XmlSchema schema = SchemaHelper.GetSchema(wrapperNs, schemaSet);
376             XmlSchemaElement element = new XmlSchemaElement();
377             if (elementNs == wrapperNs)
378             {
379                 element.Name = elementName;
380                 if (xsdType != null)
381                     element.SchemaType = xsdType;
382                 else
383                 {
384                     element.SchemaTypeName = typeName;
385                     SchemaHelper.AddImportToSchema(element.SchemaTypeName.Namespace, schema);
386                 }
387                 SchemaHelper.AddElementForm(element, schema);
388                 element.IsNillable = isNillable;
389             }
390             else
391             {
392                 element.RefName = new XmlQualifiedName(elementName, elementNs);
393
394                 SchemaHelper.AddImportToSchema(elementNs, schema);
395                 ExportGlobalElement(elementName, elementNs, isNillable, typeName, xsdType, schemaSet);
396             }
397             if (multiple)
398                 element.MaxOccurs = Decimal.MaxValue;
399             if (isOptional)
400                 element.MinOccurs = 0;
401             sequence.Items.Add(element);
402         }
403
404         static readonly XmlSchemaSequence emptySequence = new XmlSchemaSequence();
405         protected XmlSchemaSequence ExportWrappedPart(WsdlNS.Message message, string elementName, string elementNs, XmlSchemaSet schemaSet, bool skipSchemaExport)
406         {
407 #if DEBUG
408             Fx.Assert(NamingHelper.IsValidNCName(elementName), "Name value has to be a valid NCName.");
409 #endif
410             AddMessagePart(message, "parameters", new XmlQualifiedName(elementName, elementNs), XmlQualifiedName.Empty);
411             if (skipSchemaExport)
412                 return emptySequence; //return empty to denote it is wrapped part
413
414
415             XmlSchemaElement wrapperGlobalElement = new XmlSchemaElement();
416             wrapperGlobalElement.Name = elementName;
417
418             XmlSchemaComplexType wrapperType = new XmlSchemaComplexType();
419             wrapperGlobalElement.SchemaType = wrapperType; // generating an anonymous type for wrapper
420
421             XmlSchemaSequence rootSequence = new XmlSchemaSequence();
422             wrapperType.Particle = rootSequence;
423
424             AddElementToSchema(wrapperGlobalElement, elementNs, schemaSet);
425
426             return rootSequence;
427         }
428
429         protected bool CreateMessage(MessageDescription message, int messageIndex, out WsdlNS.Message wsdlMessage)
430         {
431             wsdlMessage = null;
432             bool isNewMessage = true;
433
434             if (ExportedMessages.WsdlMessages.ContainsKey(new MessageDescriptionDictionaryKey(contractContext.Contract, message)))
435                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleCallsToExportContractWithSameContract)));
436
437             TypedMessageKey typedMessageKey = null;
438             OperationMessageKey messageKey = null;
439             if (message.IsTypedMessage)
440             {
441                 typedMessageKey = new TypedMessageKey(message.MessageType, operation.DeclaringContract.Namespace, this.GetExtensionData());
442                 if (ExportedMessages.TypedMessages.TryGetValue(typedMessageKey, out wsdlMessage))
443                     isNewMessage = false;
444             }
445             else if (operation.OperationMethod != null)
446             {
447                 messageKey = new OperationMessageKey(operation, messageIndex);
448                 if (ExportedMessages.ParameterMessages.TryGetValue(messageKey, out wsdlMessage))
449                     isNewMessage = false;
450             }
451
452             WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
453             if (isNewMessage)
454             {
455                 wsdlMessage = new WsdlNS.Message();
456                 wsdlMessage.Name = GetMessageName(message);
457                 wsdl.Messages.Add(wsdlMessage);
458                 if (message.IsTypedMessage)
459                     ExportedMessages.TypedMessages.Add(typedMessageKey, wsdlMessage);
460                 else if (messageKey != null)
461                     ExportedMessages.ParameterMessages.Add(messageKey, wsdlMessage);
462             }
463
464             //Add Name to OperationMessage
465             WsdlNS.OperationMessage wsdlOperationMessage = contractContext.GetOperationMessage(message);
466             wsdlOperationMessage.Message = new XmlQualifiedName(wsdlMessage.Name, wsdlMessage.ServiceDescription.TargetNamespace);
467             this.ExportedMessages.WsdlMessages.Add(new MessageDescriptionDictionaryKey(contractContext.Contract, message), wsdlMessage);
468
469             return isNewMessage;
470         }
471
472
473         protected bool CreateHeaderMessage(MessageDescription message, out WsdlNS.Message wsdlMessage)
474         {
475             wsdlMessage = null;
476
477             if (ExportedMessages.WsdlHeaderMessages.ContainsKey(new MessageDescriptionDictionaryKey(contractContext.Contract, message)))
478                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleCallsToExportContractWithSameContract)));
479
480             TypedMessageKey typedMessageKey = null;
481             if (message.IsTypedMessage)
482             {
483                 typedMessageKey = new TypedMessageKey(message.MessageType, operation.DeclaringContract.Namespace, GetExtensionData());
484                 if (ExportedMessages.TypedHeaderMessages.TryGetValue(typedMessageKey, out wsdlMessage))
485                 {
486                     this.ExportedMessages.WsdlHeaderMessages.Add(new MessageDescriptionDictionaryKey(contractContext.Contract, message), wsdlMessage);
487                     return false;
488                 }
489             }
490
491             string messageName = GetHeaderMessageName(message);
492             wsdlMessage = new WsdlNS.Message();
493             wsdlMessage.Name = messageName;
494             contractContext.WsdlPortType.ServiceDescription.Messages.Add(wsdlMessage);
495             if (message.IsTypedMessage)
496                 ExportedMessages.TypedHeaderMessages.Add(typedMessageKey, wsdlMessage);
497
498             this.ExportedMessages.WsdlHeaderMessages.Add(new MessageDescriptionDictionaryKey(contractContext.Contract, message), wsdlMessage);
499
500             return true;
501         }
502
503         string GetMessageName(MessageDescription messageDescription)
504         {
505             string messageNameBase = XmlName.IsNullOrEmpty(messageDescription.MessageName) ? null : messageDescription.MessageName.EncodedName;
506
507             //If there wasn't one in the Message Description we create one.
508             if (string.IsNullOrEmpty(messageNameBase))
509             {
510                 string portTypeName = contractContext.WsdlPortType.Name;
511                 string operationName = contractContext.GetOperation(operation).Name;
512
513                 string callbackString = operation.IsServerInitiated() ? "Callback" : string.Empty;
514                 // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_'
515                 if (messageDescription.Direction == MessageDirection.Input)
516                     messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture,
517                                         "{0}_{1}_Input{2}Message", portTypeName, operationName, callbackString);
518                 else
519                     messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture,
520                                         "{0}_{1}_Output{2}Message", portTypeName, operationName, callbackString);
521             }
522
523             WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
524             return GetUniqueMessageName(wsdl, messageNameBase);
525         }
526
527         string GetHeaderMessageName(MessageDescription messageDescription)
528         {
529             WsdlNS.Message wsdlBodyMessage = this.ExportedMessages.WsdlMessages[new MessageDescriptionDictionaryKey(this.contractContext.Contract, messageDescription)];
530
531             string messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture,
532                                         "{0}_Headers", wsdlBodyMessage.Name);
533
534             WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
535             return GetUniqueMessageName(wsdl, messageNameBase);
536         }
537
538         protected string GetFaultMessageName(string faultName)
539         {
540             string portTypeName = contractContext.WsdlPortType.Name;
541             string operationName = contractContext.GetOperation(operation).Name;
542             // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_'
543             string faultNameBase = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}_{2}_FaultMessage", portTypeName, operationName, faultName);
544
545             WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
546             return GetUniqueMessageName(wsdl, faultNameBase);
547         }
548
549         static bool DoesMessageNameExist(string messageName, object wsdlObject)
550         {
551             return ((WsdlNS.ServiceDescription)wsdlObject).Messages[messageName] != null;
552         }
553         string GetUniqueMessageName(WsdlNS.ServiceDescription wsdl, string messageNameBase)
554         {
555             return NamingHelper.GetUniqueName(messageNameBase, DoesMessageNameExist, wsdl);
556         }
557
558         protected void ExportMessagePart(WsdlNS.Message message, MessagePartDescription part, XmlQualifiedName typeName, XmlSchemaType xsdType, bool isOptional, bool isNillable, bool skipSchemaExport, bool generateElement, string wrapperNs, XmlSchemaSequence wrapperSequence, XmlSchemaSet schemaSet)
559         {
560             if (IsNullOrEmpty(typeName) && xsdType == null)
561                 return;
562 #if DEBUG
563             if (xsdType == null)
564                 Fx.Assert(NamingHelper.IsValidNCName(typeName.Name), "Name value has to be a valid NCName.");
565 #endif
566             string elementName = part.Name;
567             string partName = string.IsNullOrEmpty(part.UniquePartName) ? elementName : part.UniquePartName;
568
569             WsdlNS.MessagePart wsdlPart = null;
570             if (generateElement)
571             {
572                 if (wrapperSequence != null)
573                 {
574                     if (!skipSchemaExport)
575                         ExportLocalElement(wrapperNs, partName, part.Namespace, typeName, xsdType, part.Multiple, isOptional, isNillable, wrapperSequence, schemaSet);
576                 }
577                 else
578                 {
579                     if (!skipSchemaExport)
580                         ExportGlobalElement(elementName, part.Namespace, isNillable, typeName, xsdType, schemaSet);
581                     wsdlPart = AddMessagePart(message, partName, new XmlQualifiedName(elementName, part.Namespace), XmlQualifiedName.Empty);
582                 }
583             }
584             else
585             {
586                 if (String.IsNullOrEmpty(typeName.Name))
587                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxAnonymousTypeNotSupported, message.Name, partName)));
588
589                 wsdlPart = AddMessagePart(message, partName, XmlQualifiedName.Empty, typeName);
590             }
591             if (wsdlPart != null)
592             {
593                 part.UniquePartName = wsdlPart.Name;
594             }
595         }
596
597         protected void AddParameterOrder(MessageDescription message)
598         {
599             if (operation == null)
600                 return;
601
602             WsdlNS.Operation wsdlOperation = contractContext.GetOperation(operation);
603             if (wsdlOperation != null)
604             {
605                 if (wsdlOperation.ParameterOrder == null)
606                 {
607                     wsdlOperation.ParameterOrder = new string[GetParameterCount()];
608                 }
609
610                 if (wsdlOperation.ParameterOrder.Length == 0)
611                     return;
612
613                 foreach (MessagePartDescription part in message.Body.Parts)
614                 {
615                     ParameterInfo paramInfo = part.AdditionalAttributesProvider as ParameterInfo;
616                     if (paramInfo != null && paramInfo.Position >= 0)
617                         wsdlOperation.ParameterOrder[paramInfo.Position] = part.Name;
618                 }
619             }
620         }
621
622         int GetParameterCount()
623         {
624             int count = -1;
625             foreach (MessageDescription message in operation.Messages)
626             {
627                 foreach (MessagePartDescription part in message.Body.Parts)
628                 {
629                     ParameterInfo paramInfo = part.AdditionalAttributesProvider as ParameterInfo;
630                     if (paramInfo == null)
631                         return 0;
632                     if (count < paramInfo.Position)
633                         count = paramInfo.Position;
634                 }
635             }
636             return count + 1;
637         }
638
639         protected virtual void Compile()
640         {
641             foreach (XmlSchema schema in SchemaSet.Schemas())
642                 SchemaSet.Reprocess(schema);
643             SchemaHelper.Compile(SchemaSet, exporter.Errors);
644         }
645
646         class MessageBindingExporter
647         {
648             WsdlEndpointConversionContext endpointContext;
649             MessageExportContext exportedMessages;
650             EnvelopeVersion soapVersion;
651             WsdlExporter exporter;
652
653
654             internal MessageBindingExporter(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext)
655             {
656                 this.endpointContext = endpointContext;
657                 this.exportedMessages = (MessageExportContext)exporter.State[typeof(MessageExportContext)];
658                 this.soapVersion = SoapHelper.GetSoapVersion(endpointContext.WsdlBinding);
659                 this.exporter = exporter;
660             }
661
662             internal void ExportMessageBinding(OperationDescription operation, Type messageContractExporterType)
663             {
664
665                 WsdlNS.OperationBinding wsdlOperationBinding = endpointContext.GetOperationBinding(operation);
666
667
668                 bool isRpc, isEncoded;
669                 if (!GetStyleAndUse(operation, messageContractExporterType, out isRpc, out isEncoded))
670                     return;
671
672                 WsdlNS.SoapOperationBinding soapOperationBinding = SoapHelper.GetOrCreateSoapOperationBinding(endpointContext, operation, exporter);
673
674                 if (soapOperationBinding == null)
675                     return;
676
677                 soapOperationBinding.Style = isRpc ? WsdlNS.SoapBindingStyle.Rpc : WsdlNS.SoapBindingStyle.Document;
678                 if (isRpc)
679                 {
680                     WsdlNS.SoapBinding soapBinding = (WsdlNS.SoapBinding)endpointContext.WsdlBinding.Extensions.Find(typeof(WsdlNS.SoapBinding));
681                     soapBinding.Style = soapOperationBinding.Style;
682                 }
683                 soapOperationBinding.SoapAction = operation.Messages[0].Action;
684
685                 foreach (MessageDescription message in operation.Messages)
686                 {
687                     WsdlNS.MessageBinding wsdlMessageBinding = endpointContext.GetMessageBinding(message);
688
689                     WsdlNS.Message headerMessage;
690                     if (this.exportedMessages.WsdlHeaderMessages.TryGetValue(new MessageDescriptionDictionaryKey(this.endpointContext.Endpoint.Contract, message), out headerMessage))
691                     {
692                         XmlQualifiedName wsdlHeaderMessageName = new XmlQualifiedName(headerMessage.Name, headerMessage.ServiceDescription.TargetNamespace);
693
694                         foreach (MessageHeaderDescription header in message.Headers)
695                         {
696                             if (header.IsUnknownHeaderCollection)
697                                 continue;
698                             ExportMessageHeaderBinding(header, wsdlHeaderMessageName, isEncoded, wsdlMessageBinding);
699                         }
700                     }
701
702                     ExportMessageBodyBinding(message, isRpc, isEncoded, wsdlMessageBinding);
703                 }
704
705                 foreach (FaultDescription fault in operation.Faults)
706                 {
707                     ExportFaultBinding(fault, isEncoded, wsdlOperationBinding);
708                 }
709             }
710
711             void ExportFaultBinding(FaultDescription fault, bool isEncoded, WsdlNS.OperationBinding operationBinding)
712             {
713                 SoapHelper.CreateSoapFaultBinding(fault.Name, endpointContext, endpointContext.GetFaultBinding(fault), isEncoded);
714             }
715
716             void ExportMessageBodyBinding(MessageDescription messageDescription, bool isRpc, bool isEncoded, WsdlNS.MessageBinding messageBinding)
717             {
718                 WsdlNS.SoapBodyBinding bodyBinding = SoapHelper.GetOrCreateSoapBodyBinding(endpointContext, messageBinding, exporter);
719
720                 if (bodyBinding == null)
721                     return;
722
723                 bodyBinding.Use = isEncoded ? WsdlNS.SoapBindingUse.Encoded : WsdlNS.SoapBindingUse.Literal;
724                 if (isRpc)
725                 {
726                     string ns;
727                     if (!ExportedMessages.WrapperNamespaces.TryGetValue(new MessageDescriptionDictionaryKey(endpointContext.ContractConversionContext.Contract, messageDescription), out ns))
728                         ns = messageDescription.Body.WrapperNamespace;
729                     bodyBinding.Namespace = ns;
730                 }
731                 if (isEncoded)
732                     bodyBinding.Encoding = XmlSerializerOperationFormatter.GetEncoding(soapVersion);
733             }
734
735             void ExportMessageHeaderBinding(MessageHeaderDescription header, XmlQualifiedName messageName, bool isEncoded, WsdlNS.MessageBinding messageBinding)
736             {
737 #if DEBUG
738                 Fx.Assert(NamingHelper.IsValidNCName(messageName.Name), "Name value has to be a valid NCName.");
739 #endif
740                 WsdlNS.SoapHeaderBinding headerBinding = SoapHelper.CreateSoapHeaderBinding(endpointContext, messageBinding);
741                 headerBinding.Part = string.IsNullOrEmpty(header.UniquePartName) ? header.Name : header.UniquePartName;
742                 headerBinding.Message = messageName;
743                 headerBinding.Use = isEncoded ? WsdlNS.SoapBindingUse.Encoded : WsdlNS.SoapBindingUse.Literal;
744                 if (isEncoded)
745                     headerBinding.Encoding = XmlSerializerOperationFormatter.GetEncoding(soapVersion);
746             }
747
748             static bool GetStyleAndUse(OperationDescription operation, Type messageContractExporterType, out bool isRpc, out bool isEncoded)
749             {
750                 isRpc = isEncoded = false;
751                 if (messageContractExporterType == typeof(DataContractSerializerMessageContractExporter) || messageContractExporterType == null)
752                 {
753                     DataContractSerializerOperationBehavior dataContractSerializerBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
754                     if (dataContractSerializerBehavior != null)
755                     {
756                         isRpc = dataContractSerializerBehavior.DataContractFormatAttribute.Style == OperationFormatStyle.Rpc;
757                         isEncoded = false;
758                         return true;
759                     }
760                     if (messageContractExporterType == typeof(DataContractSerializerMessageContractExporter))
761                         return false;
762                 }
763                 if (messageContractExporterType == typeof(XmlSerializerMessageContractExporter) || messageContractExporterType == null)
764                 {
765                     XmlSerializerOperationBehavior xmlSerializerBehavior = operation.Behaviors.Find<XmlSerializerOperationBehavior>();
766                     if (xmlSerializerBehavior != null)
767                     {
768                         isRpc = xmlSerializerBehavior.XmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc;
769                         isEncoded = xmlSerializerBehavior.XmlSerializerFormatAttribute.IsEncoded;
770                         return true;
771                     }
772                     return false;
773                 }
774                 return false;
775             }
776
777             MessageExportContext ExportedMessages
778             {
779                 get { return GetMessageExportContext(exporter); }
780             }
781         }
782
783         protected class MessageExportContext
784         {
785             readonly internal Dictionary<MessageDescriptionDictionaryKey, WsdlNS.Message> WsdlMessages = new Dictionary<MessageDescriptionDictionaryKey, System.Web.Services.Description.Message>();
786             readonly internal Dictionary<MessageDescriptionDictionaryKey, WsdlNS.Message> WsdlHeaderMessages = new Dictionary<MessageDescriptionDictionaryKey, System.Web.Services.Description.Message>();
787             readonly internal Dictionary<MessageDescriptionDictionaryKey, string> WrapperNamespaces = new Dictionary<MessageDescriptionDictionaryKey, string>();
788             readonly internal Dictionary<TypedMessageKey, WsdlNS.Message> TypedMessages = new Dictionary<TypedMessageKey, WsdlNS.Message>();
789             readonly internal Dictionary<TypedMessageKey, WsdlNS.Message> TypedHeaderMessages = new Dictionary<TypedMessageKey, WsdlNS.Message>();
790             readonly internal Dictionary<OperationMessageKey, WsdlNS.Message> ParameterMessages = new Dictionary<OperationMessageKey, WsdlNS.Message>();
791             readonly internal Dictionary<XmlQualifiedName, OperationElement> ElementTypes = new Dictionary<XmlQualifiedName, OperationElement>();
792         }
793
794         protected sealed class MessageDescriptionDictionaryKey
795         {
796             public readonly ContractDescription Contract;
797             public readonly MessageDescription MessageDescription;
798
799             public MessageDescriptionDictionaryKey(ContractDescription contract, MessageDescription MessageDescription)
800             {
801                 this.Contract = contract;
802                 this.MessageDescription = MessageDescription;
803             }
804
805             public override bool Equals(object obj)
806             {
807                 MessageDescriptionDictionaryKey key = obj as MessageDescriptionDictionaryKey;
808                 if (key != null && key.MessageDescription == this.MessageDescription && key.Contract == this.Contract)
809                     return true;
810                 return false;
811             }
812
813             public override int GetHashCode()
814             {
815                 return this.Contract.GetHashCode() ^ this.MessageDescription.GetHashCode();
816             }
817         }
818
819         internal sealed class TypedMessageKey
820         {
821             Type type;
822             string contractNS;
823             object extensionData;
824
825             public TypedMessageKey(Type type, string contractNS, object extensionData)
826             {
827                 this.type = type;
828                 this.contractNS = contractNS;
829                 this.extensionData = extensionData;
830             }
831
832             public override bool Equals(object obj)
833             {
834                 TypedMessageKey key = obj as TypedMessageKey;
835                 if (key != null && key.type == this.type &&
836                     key.contractNS == this.contractNS &&
837                     key.extensionData.Equals(this.extensionData))
838                     return true;
839                 return false;
840             }
841
842             [SuppressMessage(FxCop.Category.Usage, "CA2303:FlagTypeGetHashCode", Justification = "The hashcode is not used for identity purposes for embedded types.")]
843             public override int GetHashCode()
844             {
845                 return type.GetHashCode();
846             }
847         }
848
849         internal sealed class OperationMessageKey
850         {
851             MethodInfo methodInfo;
852             int messageIndex;
853             ContractDescription declaringContract;
854
855             public OperationMessageKey(OperationDescription operation, int messageIndex)
856             {
857                 this.methodInfo = operation.OperationMethod;
858                 this.messageIndex = messageIndex;
859                 this.declaringContract = operation.DeclaringContract;
860             }
861
862             public override bool Equals(object obj)
863             {
864                 OperationMessageKey key = obj as OperationMessageKey;
865                 if (key != null && key.methodInfo == this.methodInfo &&
866                     key.messageIndex == this.messageIndex &&
867                     key.declaringContract.Name == this.declaringContract.Name &&
868                     key.declaringContract.Namespace == this.declaringContract.Namespace)
869                     return true;
870                 return false;
871             }
872
873             public override int GetHashCode()
874             {
875                 return methodInfo.GetHashCode() ^ messageIndex;
876             }
877         }
878
879         internal sealed class OperationElement
880         {
881             XmlSchemaElement element;
882             OperationDescription operation;
883             internal OperationElement(XmlSchemaElement element, OperationDescription operation)
884             {
885                 this.element = element;
886                 this.operation = operation;
887             }
888             internal XmlSchemaElement Element { get { return element; } }
889             internal OperationDescription Operation { get { return operation; } }
890         }
891     }
892
893     class DataContractSerializerMessageContractExporter : MessageContractExporter
894     {
895         internal DataContractSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
896             : base(exporter, context, operation, extension)
897         {
898         }
899
900         protected override void Compile()
901         {
902             XmlSchema wsdl = StockSchemas.CreateWsdl();
903             XmlSchema soap = StockSchemas.CreateSoap();
904             XmlSchema soapEncoding = StockSchemas.CreateSoapEncoding();
905             XmlSchema fakeXsdSchema = StockSchemas.CreateFakeXsdSchema();
906
907             SchemaSet.Add(wsdl);
908             SchemaSet.Add(soap);
909             SchemaSet.Add(soapEncoding);
910             SchemaSet.Add(fakeXsdSchema);
911             base.Compile();
912             SchemaSet.Remove(wsdl);
913             SchemaSet.Remove(soap);
914             SchemaSet.Remove(soapEncoding);
915             SchemaSet.Remove(fakeXsdSchema);
916         }
917
918         protected override bool IsRpcStyle()
919         {
920             return ((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute.Style == OperationFormatStyle.Rpc;
921         }
922
923         protected override bool IsEncoded()
924         {
925             return false;
926         }
927
928         protected override object OnExportMessageContract()
929         {
930             return null;
931         }
932
933         protected override void ExportHeaders(int messageIndex, object state)
934         {
935             MessageDescription description = operation.Messages[messageIndex];
936
937             if (description.Headers.Count > 0)
938             {
939                 WsdlNS.Message wsdlMessage;
940                 if (CreateHeaderMessage(description, out wsdlMessage))
941                 {
942                     foreach (MessageHeaderDescription header in description.Headers)
943                     {
944                         if (header.IsUnknownHeaderCollection)
945                             continue;
946                         XmlSchemaType xsdType;
947                         bool isQueryable;
948                         Type dataContractType = DataContractSerializerOperationFormatter.GetSubstituteDataContractType(header.Type, out isQueryable);
949                         XmlQualifiedName typeName = ExportType(dataContractType, header.Name, operation.Name, out xsdType);
950                         ExportMessagePart(wsdlMessage, header, typeName, xsdType, true/*isOptional*/, IsTypeNullable(header.Type), false/*IsOperationInherited(operation)*/, true /*generateElement*/, null/*wrapperNamespace*/, null/*wrapperSequence*/, SchemaSet);
951                     }
952                 }
953             }
954         }
955
956         static internal bool IsTypeNullable(Type type)
957         {
958             return !type.IsValueType ||
959                     (type.IsGenericType &&
960                     type.GetGenericTypeDefinition() == typeof(Nullable<>));
961         }
962
963         protected override void ExportBody(int messageIndex, object state)
964         {
965             MessageDescription description = operation.Messages[messageIndex];
966             WsdlNS.Message wsdlMessage = this.ExportedMessages.WsdlMessages[new MessageDescriptionDictionaryKey(this.contractContext.Contract, description)];
967
968             DataContractFormatAttribute dataContractFormatAttribute = ((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute;
969             XmlSchemaSequence wrapperSequence = null;
970             bool isWrapped = description.Body.WrapperName != null;
971             //bool isOperationInherited = IsOperationInherited(operation);
972             if (dataContractFormatAttribute.Style == OperationFormatStyle.Document && isWrapped)
973                 wrapperSequence = ExportWrappedPart(wsdlMessage, description.Body.WrapperName, description.Body.WrapperNamespace, SchemaSet, false /*isOperationInherited*/);
974             XmlSchemaType xsdType;
975             if (OperationFormatter.IsValidReturnValue(description.Body.ReturnValue))
976             {
977                 bool isQueryable;
978                 Type dataContractType = DataContractSerializerOperationFormatter.GetSubstituteDataContractType(description.Body.ReturnValue.Type, out isQueryable);
979                 XmlQualifiedName typeName = ExportType(dataContractType, description.Body.ReturnValue.Name, operation.Name, out xsdType);
980                 ExportMessagePart(wsdlMessage, description.Body.ReturnValue, typeName, xsdType, true/*isOptional*/, IsTypeNullable(description.Body.ReturnValue.Type), false/*isOperationInherited*/, dataContractFormatAttribute.Style != OperationFormatStyle.Rpc, description.Body.WrapperNamespace, wrapperSequence, SchemaSet);
981             }
982
983             foreach (MessagePartDescription bodyPart in description.Body.Parts)
984             {
985                 bool isQueryable;
986                 Type dataContractType = DataContractSerializerOperationFormatter.GetSubstituteDataContractType(bodyPart.Type, out isQueryable);
987                 XmlQualifiedName typeName = ExportType(dataContractType, bodyPart.Name, operation.Name, out xsdType);
988                 ExportMessagePart(wsdlMessage, bodyPart, typeName, xsdType, true/*isOptional*/, IsTypeNullable(bodyPart.Type), false/*isOperationInherited*/, dataContractFormatAttribute.Style != OperationFormatStyle.Rpc, description.Body.WrapperNamespace, wrapperSequence, SchemaSet);
989             }
990             if (dataContractFormatAttribute.Style == OperationFormatStyle.Rpc)
991             {
992                 AddParameterOrder(description);
993             }
994         }
995
996         protected override void ExportKnownTypes()
997         {
998             foreach (Type knownType in operation.KnownTypes)
999             {
1000                 DataContractExporter.Export(knownType);
1001             }
1002         }
1003
1004         protected override object GetExtensionData()
1005         {
1006             return new ExtensionData(((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute);
1007         }
1008         class ExtensionData
1009         {
1010             DataContractFormatAttribute dcFormatAttr;
1011             internal ExtensionData(DataContractFormatAttribute dcFormatAttr)
1012             {
1013                 this.dcFormatAttr = dcFormatAttr;
1014             }
1015
1016             public override bool Equals(object obj)
1017             {
1018                 if (object.ReferenceEquals(dcFormatAttr, obj))
1019                     return true;
1020                 ExtensionData otherExtensionData = obj as ExtensionData;
1021                 if (otherExtensionData == null)
1022                     return false;
1023                 return dcFormatAttr.Style == otherExtensionData.dcFormatAttr.Style;
1024             }
1025
1026             public override int GetHashCode()
1027             {
1028                 return 1; //This is never called
1029             }
1030         }
1031     }
1032
1033     class XmlSerializerMessageContractExporter : MessageContractExporter
1034     {
1035         internal XmlSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
1036             : base(exporter, context, operation, extension)
1037         {
1038         }
1039
1040         protected override bool IsRpcStyle()
1041         {
1042             return ((XmlSerializerOperationBehavior)extension).XmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc;
1043         }
1044
1045         protected override bool IsEncoded()
1046         {
1047             return ((XmlSerializerOperationBehavior)extension).XmlSerializerFormatAttribute.IsEncoded;
1048         }
1049
1050         protected override object OnExportMessageContract()
1051         {
1052             object result = Reflector.ReflectOperation(operation);
1053             if (result == null)
1054             {
1055                 // If result is null, that means that XmlSerializerFormatAttribute wasn't available in reflection, 
1056                 // so we need to get it from the XmlSerializerOperationBehavior instead
1057                 XmlSerializerOperationBehavior serializerBehavior = this.extension as XmlSerializerOperationBehavior;
1058                 if (serializerBehavior != null)
1059                 {
1060                     result = Reflector.ReflectOperation(operation, serializerBehavior.XmlSerializerFormatAttribute);
1061                 }
1062             }
1063             return result;
1064         }
1065
1066         protected override void ExportHeaders(int messageIndex, object state)
1067         {
1068             string portTypeName = contractContext.WsdlPortType.Name;
1069             string portTypeNs = contractContext.WsdlPortType.ServiceDescription.TargetNamespace;
1070
1071             MessageDescription description = operation.Messages[messageIndex];
1072             if (description.Headers.Count > 0)
1073             {
1074
1075                 XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector = (XmlSerializerOperationBehavior.Reflector.OperationReflector)state;
1076                 XmlMembersMapping membersMapping = null;
1077                 if (messageIndex == 0)
1078                 {
1079                     membersMapping = operationReflector.Request.HeadersMapping;
1080                 }
1081                 else
1082                 {
1083                     membersMapping = operationReflector.Reply.HeadersMapping;
1084                 }
1085
1086                 if (membersMapping != null)
1087                 {
1088                     WsdlNS.Message wsdlMessage;
1089                     if (CreateHeaderMessage(description, out wsdlMessage))
1090                     {
1091                         ExportMembersMapping(membersMapping, wsdlMessage, false /*IsOperationInherited(operation)*/, operationReflector.IsEncoded, false/*isRpc*/, false/*isWrapped*/, true/*isHeader*/);
1092                     }
1093                 }
1094             }
1095         }
1096
1097         protected override void ExportBody(int messageIndex, object state)
1098         {
1099             MessageDescription description = operation.Messages[messageIndex];
1100             string portTypeName = contractContext.WsdlPortType.Name;
1101             string portTypeNs = contractContext.WsdlPortType.ServiceDescription.TargetNamespace;
1102             MessageDescriptionDictionaryKey key = new MessageDescriptionDictionaryKey(this.contractContext.Contract, description);
1103             WsdlNS.Message wsdlMessage = this.ExportedMessages.WsdlMessages[key];
1104
1105             XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector = (XmlSerializerOperationBehavior.Reflector.OperationReflector)state;
1106             XmlMembersMapping membersMapping = null;
1107             if (messageIndex == 0)
1108             {
1109                 membersMapping = operationReflector.Request.BodyMapping;
1110             }
1111             else
1112             {
1113                 membersMapping = operationReflector.Reply.BodyMapping;
1114             }
1115
1116             if (membersMapping != null)
1117             {
1118                 bool isDocWrapped = !operationReflector.IsRpc && description.Body.WrapperName != null;
1119                 ExportMembersMapping(membersMapping, wsdlMessage, false /*IsOperationInherited(operation)*/, operationReflector.IsEncoded, operationReflector.IsRpc, isDocWrapped, false/*isHeader*/);
1120                 if (operationReflector.IsRpc)
1121                 {
1122                     AddParameterOrder(operation.Messages[messageIndex]);
1123                     this.ExportedMessages.WrapperNamespaces.Add(key, membersMapping.Namespace);
1124                 }
1125             }
1126         }
1127
1128         protected override void ExportFaults(object state)
1129         {
1130             XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector = (XmlSerializerOperationBehavior.Reflector.OperationReflector)state;
1131             if (operationReflector.Attribute.SupportFaults)
1132             {
1133                 foreach (FaultDescription fault in operation.Faults)
1134                 {
1135                     ExportFault(fault, operationReflector);
1136                 }
1137                 Compile();
1138             }
1139             else
1140             {
1141                 base.ExportFaults(state);
1142             }
1143         }
1144
1145         void ExportFault(FaultDescription fault, XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector)
1146         {
1147             WsdlNS.Message faultMessage = new WsdlNS.Message();
1148             faultMessage.Name = GetFaultMessageName(fault.Name);
1149
1150             XmlQualifiedName elementName = ExportFaultElement(fault, operationReflector);
1151             this.contractContext.WsdlPortType.ServiceDescription.Messages.Add(faultMessage);
1152             AddMessagePart(faultMessage, "detail", elementName, null);
1153
1154             // create a wsdl:fault to put inside the wsdl:portType/wsdl:operation
1155             WsdlNS.OperationFault operationFault = contractContext.GetOperationFault(fault);
1156             WsdlExporter.WSAddressingHelper.AddActionAttribute(fault.Action, operationFault, this.exporter.PolicyVersion);
1157             operationFault.Message = new XmlQualifiedName(faultMessage.Name, faultMessage.ServiceDescription.TargetNamespace);
1158         }
1159
1160         XmlQualifiedName ExportFaultElement(FaultDescription fault, XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector)
1161         {
1162             XmlQualifiedName elementName;
1163             XmlMembersMapping mapping = operationReflector.ImportFaultElement(fault, out elementName);
1164             if (operationReflector.IsEncoded)
1165                 SoapExporter.ExportMembersMapping(mapping);
1166             else
1167                 XmlExporter.ExportMembersMapping(mapping);
1168             return elementName;
1169         }
1170
1171         protected override void ExportKnownTypes()
1172         {
1173         }
1174
1175         protected override object GetExtensionData()
1176         {
1177             return new ExtensionData(((XmlSerializerOperationBehavior)this.extension).XmlSerializerFormatAttribute);
1178         }
1179
1180         class ExtensionData
1181         {
1182             XmlSerializerFormatAttribute xsFormatAttr;
1183             internal ExtensionData(XmlSerializerFormatAttribute xsFormatAttr)
1184             {
1185                 this.xsFormatAttr = xsFormatAttr;
1186             }
1187
1188             public override bool Equals(object obj)
1189             {
1190                 if (object.ReferenceEquals(xsFormatAttr, obj))
1191                     return true;
1192                 ExtensionData otherExtensionData = obj as ExtensionData;
1193                 if (otherExtensionData == null)
1194                     return false;
1195                 return xsFormatAttr.Style == otherExtensionData.xsFormatAttr.Style &&
1196                     xsFormatAttr.Use == otherExtensionData.xsFormatAttr.Use;
1197             }
1198             public override int GetHashCode()
1199             {
1200                 return 1; //This is never called
1201             }
1202         }
1203         void ExportMembersMapping(XmlMembersMapping membersMapping, WsdlNS.Message message, bool skipSchemaExport, bool isEncoded, bool isRpc, bool isDocWrapped, bool isHeader)
1204         {
1205             if (!skipSchemaExport)
1206             {
1207                 if (isEncoded)
1208                     SoapExporter.ExportMembersMapping(membersMapping);
1209                 else
1210                     XmlExporter.ExportMembersMapping(membersMapping, !isRpc);
1211             }
1212
1213
1214             if (isDocWrapped)
1215             {
1216                 if (isHeader)
1217                 {
1218                     Fx.Assert("Header cannot be Document Wrapped");
1219                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Header cannot be Document Wrapped")));
1220                 }
1221                 AddMessagePart(message, "parameters", new XmlQualifiedName(membersMapping.XsdElementName, membersMapping.Namespace), XmlQualifiedName.Empty);
1222                 return;
1223             }
1224             bool generateElement = !isRpc && !isEncoded;
1225             for (int i = 0; i < membersMapping.Count; i++)
1226             {
1227                 XmlMemberMapping member = membersMapping[i];
1228
1229                 string partName = (isHeader || generateElement) ? NamingHelper.XmlName(member.MemberName) : member.XsdElementName;
1230                 if (generateElement)
1231                     AddMessagePart(message, partName, new XmlQualifiedName(member.XsdElementName, member.Namespace), XmlQualifiedName.Empty);
1232                 else
1233                 {
1234                     if (string.IsNullOrEmpty(member.TypeName))
1235                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxAnonymousTypeNotSupported, message.Name, partName)));
1236
1237                     AddMessagePart(message, partName, XmlQualifiedName.Empty, new XmlQualifiedName(member.TypeName, member.TypeNamespace));
1238                 }
1239             }
1240         }
1241
1242         XmlSerializerOperationBehavior.Reflector Reflector
1243         {
1244             get
1245             {
1246                 object reflector;
1247                 if (!exporter.State.TryGetValue(typeof(XmlSerializerOperationBehavior.Reflector), out reflector))
1248                 {
1249                     reflector = new XmlSerializerOperationBehavior.Reflector(contractContext.Contract.Namespace, contractContext.Contract.ContractType);
1250                     exporter.State.Add(typeof(XmlSerializerOperationBehavior.Reflector), reflector);
1251                 }
1252                 return (XmlSerializerOperationBehavior.Reflector)reflector;
1253             }
1254         }
1255
1256         SoapSchemaExporter SoapExporter
1257         {
1258             get
1259             {
1260                 object soapExporter;
1261                 if (!exporter.State.TryGetValue(typeof(SoapSchemaExporter), out soapExporter))
1262                 {
1263                     soapExporter = new SoapSchemaExporter(Schemas);
1264                     exporter.State.Add(typeof(SoapSchemaExporter), soapExporter);
1265                 }
1266                 return (SoapSchemaExporter)soapExporter;
1267             }
1268         }
1269
1270         XmlSchemaExporter XmlExporter
1271         {
1272             get
1273             {
1274                 object xmlExporter;
1275                 if (!exporter.State.TryGetValue(typeof(XmlSchemaExporter), out xmlExporter))
1276                 {
1277                     xmlExporter = new XmlSchemaExporter(Schemas);
1278                     exporter.State.Add(typeof(XmlSchemaExporter), xmlExporter);
1279                 }
1280                 return (XmlSchemaExporter)xmlExporter;
1281             }
1282         }
1283
1284         XmlSchemas Schemas
1285         {
1286             get
1287             {
1288                 object schemas;
1289                 if (!exporter.State.TryGetValue(typeof(XmlSchemas), out schemas))
1290                 {
1291                     schemas = new XmlSchemas();
1292                     foreach (XmlSchema schema in this.SchemaSet.Schemas())
1293                         if (!((XmlSchemas)schemas).Contains(schema.TargetNamespace))
1294                             ((XmlSchemas)schemas).Add(schema);
1295                     exporter.State.Add(typeof(XmlSchemas), schemas);
1296                 }
1297                 return (XmlSchemas)schemas;
1298             }
1299         }
1300
1301         protected override void Compile()
1302         {
1303             XmlSchema wsdl = StockSchemas.CreateWsdl();
1304             XmlSchema soap = StockSchemas.CreateSoap();
1305             XmlSchema soapEncoding = StockSchemas.CreateSoapEncoding();
1306             XmlSchema fakeXsdSchema = StockSchemas.CreateFakeXsdSchema();
1307
1308             MoveSchemas();
1309             SchemaSet.Add(wsdl);
1310             SchemaSet.Add(soap);
1311             SchemaSet.Add(soapEncoding);
1312             SchemaSet.Add(fakeXsdSchema);
1313             base.Compile();
1314             SchemaSet.Remove(wsdl);
1315             SchemaSet.Remove(soap);
1316             SchemaSet.Remove(soapEncoding);
1317             SchemaSet.Remove(fakeXsdSchema);
1318         }
1319
1320         void MoveSchemas()
1321         {
1322             XmlSchemas schemas = this.Schemas;
1323             XmlSchemaSet schemaSet = this.SchemaSet;
1324             if (schemas != null)
1325             {
1326                 schemas.Compile(
1327                      delegate(object sender, ValidationEventArgs args)
1328                      {
1329                          SchemaHelper.HandleSchemaValidationError(sender, args, exporter.Errors);
1330                      },
1331                      false/*fullCompile*/
1332                 );
1333                 foreach (XmlSchema srcSchema in schemas)
1334                 {
1335                     if (!schemaSet.Contains(srcSchema))
1336                     {
1337                         schemaSet.Add(srcSchema);
1338                         schemaSet.Reprocess(srcSchema);
1339                     }
1340                 }
1341             }
1342         }
1343     }
1344
1345     static class StockSchemas
1346     {
1347
1348         internal static XmlSchema CreateWsdl()
1349         {
1350             return XmlSchema.Read(new StringReader(wsdl), null);
1351         }
1352         internal static XmlSchema CreateSoap()
1353         {
1354             return XmlSchema.Read(new StringReader(soap), null);
1355         }
1356
1357         internal static XmlSchema CreateSoapEncoding()
1358         {
1359             return XmlSchema.Read(new StringReader(soapEncoding), null);
1360         }
1361
1362         internal static XmlSchema CreateFakeSoapEncoding()
1363         {
1364             return XmlSchema.Read(new StringReader(fakeSoapEncoding), null);
1365         }
1366
1367         internal static XmlSchema CreateFakeXsdSchema()
1368         {
1369             return XmlSchema.Read(new StringReader(fakeXsd), null);
1370         }
1371
1372         internal static XmlSchema CreateFakeXmlSchema()
1373         {
1374             return XmlSchema.Read(new StringReader(fakeXmlSchema), null);
1375         }
1376
1377         internal static bool IsKnownSchema(string ns)
1378         {
1379             return ns == XmlSchema.Namespace || ns == "http://schemas.xmlsoap.org/wsdl/soap/" || ns == "http://schemas.xmlsoap.org/soap/encoding/";
1380         }
1381
1382         internal const string WsdlNamespace = "http://schemas.xmlsoap.org/wsdl/";
1383         internal const string SoapNamespace = "http://schemas.xmlsoap.org/wsdl/soap/";
1384         internal const string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
1385
1386         const string wsdl = @"<?xml version='1.0' encoding='UTF-8' ?> 
1387 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
1388            xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
1389            targetNamespace='http://schemas.xmlsoap.org/wsdl/'
1390            elementFormDefault='qualified' >
1391    
1392   <xs:complexType mixed='true' name='tDocumentation' >
1393     <xs:sequence>
1394       <xs:any minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1395     </xs:sequence>
1396   </xs:complexType>
1397
1398   <xs:complexType name='tDocumented' >
1399     <xs:annotation>
1400       <xs:documentation>
1401       This type is extended by  component types to allow them to be documented
1402       </xs:documentation>
1403     </xs:annotation>
1404     <xs:sequence>
1405       <xs:element name='documentation' type='wsdl:tDocumentation' minOccurs='0' />
1406     </xs:sequence>
1407   </xs:complexType>
1408  <!-- allow extensibility via elements and attributes on all elements swa124 -->
1409  <xs:complexType name='tExtensibleAttributesDocumented' abstract='true' >
1410     <xs:complexContent>
1411       <xs:extension base='wsdl:tDocumented' >
1412         <xs:annotation>
1413           <xs:documentation>
1414           This type is extended by component types to allow attributes from other namespaces to be added.
1415           </xs:documentation>
1416         </xs:annotation>
1417         <xs:sequence>
1418           <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1419         </xs:sequence>
1420         <xs:anyAttribute namespace='##other' processContents='lax' />   
1421       </xs:extension>
1422     </xs:complexContent>
1423   </xs:complexType>
1424   <xs:complexType name='tExtensibleDocumented' abstract='true' >
1425     <xs:complexContent>
1426       <xs:extension base='wsdl:tDocumented' >
1427         <xs:annotation>
1428           <xs:documentation>
1429           This type is extended by component types to allow elements from other namespaces to be added.
1430           </xs:documentation>
1431         </xs:annotation>
1432         <xs:sequence>
1433           <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1434         </xs:sequence>
1435         <xs:anyAttribute namespace='##other' processContents='lax' />   
1436       </xs:extension>
1437     </xs:complexContent>
1438   </xs:complexType>
1439   <!-- original wsdl removed as part of swa124 resolution
1440   <xs:complexType name='tExtensibleAttributesDocumented' abstract='true' >
1441     <xs:complexContent>
1442       <xs:extension base='wsdl:tDocumented' >
1443         <xs:annotation>
1444           <xs:documentation>
1445           This type is extended by component types to allow attributes from other namespaces to be added.
1446           </xs:documentation>
1447         </xs:annotation>
1448         <xs:anyAttribute namespace='##other' processContents='lax' />    
1449       </xs:extension>
1450     </xs:complexContent>
1451   </xs:complexType>
1452
1453   <xs:complexType name='tExtensibleDocumented' abstract='true' >
1454     <xs:complexContent>
1455       <xs:extension base='wsdl:tDocumented' >
1456         <xs:annotation>
1457           <xs:documentation>
1458           This type is extended by component types to allow elements from other namespaces to be added.
1459           </xs:documentation>
1460         </xs:annotation>
1461         <xs:sequence>
1462           <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1463         </xs:sequence>
1464       </xs:extension>
1465     </xs:complexContent>
1466   </xs:complexType>
1467  -->
1468   <xs:element name='definitions' type='wsdl:tDefinitions' >
1469     <xs:key name='message' >
1470       <xs:selector xpath='wsdl:message' />
1471       <xs:field xpath='@name' />
1472     </xs:key>
1473     <xs:key name='portType' >
1474       <xs:selector xpath='wsdl:portType' />
1475       <xs:field xpath='@name' />
1476     </xs:key>
1477     <xs:key name='binding' >
1478       <xs:selector xpath='wsdl:binding' />
1479       <xs:field xpath='@name' />
1480     </xs:key>
1481     <xs:key name='service' >
1482       <xs:selector xpath='wsdl:service' />
1483       <xs:field xpath='@name' />
1484     </xs:key>
1485     <xs:key name='import' >
1486       <xs:selector xpath='wsdl:import' />
1487       <xs:field xpath='@namespace' />
1488     </xs:key>
1489   </xs:element>
1490
1491   <xs:group name='anyTopLevelOptionalElement' >
1492     <xs:annotation>
1493       <xs:documentation>
1494       Any top level optional element allowed to appear more then once - any child of definitions element except wsdl:types. Any extensibility element is allowed in any place.
1495       </xs:documentation>
1496     </xs:annotation>
1497     <xs:choice>
1498       <xs:element name='import' type='wsdl:tImport' />
1499       <xs:element name='types' type='wsdl:tTypes' />                     
1500       <xs:element name='message'  type='wsdl:tMessage' >
1501         <xs:unique name='part' >
1502           <xs:selector xpath='wsdl:part' />
1503           <xs:field xpath='@name' />
1504         </xs:unique>
1505       </xs:element>
1506       <xs:element name='portType' type='wsdl:tPortType' />
1507       <xs:element name='binding'  type='wsdl:tBinding' />
1508       <xs:element name='service'  type='wsdl:tService' >
1509         <xs:unique name='port' >
1510           <xs:selector xpath='wsdl:port' />
1511           <xs:field xpath='@name' />
1512         </xs:unique>
1513       </xs:element>
1514     </xs:choice>
1515   </xs:group>
1516
1517   <xs:complexType name='tDefinitions' >
1518     <xs:complexContent>
1519       <xs:extension base='wsdl:tExtensibleDocumented' >
1520         <xs:sequence>
1521           <xs:group ref='wsdl:anyTopLevelOptionalElement'  minOccurs='0'   maxOccurs='unbounded' />
1522         </xs:sequence>
1523         <xs:attribute name='targetNamespace' type='xs:anyURI' use='optional' />
1524         <xs:attribute name='name' type='xs:NCName' use='optional' />
1525       </xs:extension>
1526     </xs:complexContent>
1527   </xs:complexType>
1528    
1529   <xs:complexType name='tImport' >
1530     <xs:complexContent>
1531       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1532         <xs:attribute name='namespace' type='xs:anyURI' use='required' />
1533         <xs:attribute name='location' type='xs:anyURI' use='required' />
1534       </xs:extension>
1535     </xs:complexContent>
1536   </xs:complexType>
1537    
1538   <xs:complexType name='tTypes' >
1539     <xs:complexContent>   
1540       <xs:extension base='wsdl:tExtensibleDocumented' />
1541     </xs:complexContent>   
1542   </xs:complexType>
1543      
1544   <xs:complexType name='tMessage' >
1545     <xs:complexContent>   
1546       <xs:extension base='wsdl:tExtensibleDocumented' >
1547         <xs:sequence>
1548           <xs:element name='part' type='wsdl:tPart' minOccurs='0' maxOccurs='unbounded' />
1549         </xs:sequence>
1550         <xs:attribute name='name' type='xs:NCName' use='required' />
1551       </xs:extension>
1552     </xs:complexContent>   
1553   </xs:complexType>
1554
1555   <xs:complexType name='tPart' >
1556     <xs:complexContent>   
1557       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1558         <xs:attribute name='name' type='xs:NCName' use='required' />
1559         <xs:attribute name='element' type='xs:QName' use='optional' />
1560         <xs:attribute name='type' type='xs:QName' use='optional' />    
1561       </xs:extension>
1562     </xs:complexContent>   
1563   </xs:complexType>
1564
1565   <xs:complexType name='tPortType' >
1566     <xs:complexContent>   
1567       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1568         <xs:sequence>
1569           <xs:element name='operation' type='wsdl:tOperation' minOccurs='0' maxOccurs='unbounded' />
1570         </xs:sequence>
1571         <xs:attribute name='name' type='xs:NCName' use='required' />
1572       </xs:extension>
1573     </xs:complexContent>   
1574   </xs:complexType>
1575    
1576   <xs:complexType name='tOperation' >
1577     <xs:complexContent>   
1578       <xs:extension base='wsdl:tExtensibleDocumented' >
1579         <xs:sequence>
1580           <xs:choice>
1581             <xs:group ref='wsdl:request-response-or-one-way-operation' />
1582             <xs:group ref='wsdl:solicit-response-or-notification-operation' />
1583           </xs:choice>
1584         </xs:sequence>
1585         <xs:attribute name='name' type='xs:NCName' use='required' />
1586         <xs:attribute name='parameterOrder' type='xs:NMTOKENS' use='optional' />
1587       </xs:extension>
1588     </xs:complexContent>   
1589   </xs:complexType>
1590     
1591   <xs:group name='request-response-or-one-way-operation' >
1592     <xs:sequence>
1593       <xs:element name='input' type='wsdl:tParam' />
1594       <xs:sequence minOccurs='0' >
1595         <xs:element name='output' type='wsdl:tParam' />
1596         <xs:element name='fault' type='wsdl:tFault' minOccurs='0' maxOccurs='unbounded' />
1597       </xs:sequence>
1598     </xs:sequence>
1599   </xs:group>
1600
1601   <xs:group name='solicit-response-or-notification-operation' >
1602     <xs:sequence>
1603       <xs:element name='output' type='wsdl:tParam' />
1604       <xs:sequence minOccurs='0' >
1605         <xs:element name='input' type='wsdl:tParam' />
1606         <xs:element name='fault' type='wsdl:tFault' minOccurs='0' maxOccurs='unbounded' />
1607       </xs:sequence>
1608     </xs:sequence>
1609   </xs:group>
1610         
1611   <xs:complexType name='tParam' >
1612     <xs:complexContent>
1613       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1614         <xs:attribute name='name' type='xs:NCName' use='optional' />
1615         <xs:attribute name='message' type='xs:QName' use='required' />
1616       </xs:extension>
1617     </xs:complexContent>
1618   </xs:complexType>
1619
1620   <xs:complexType name='tFault' >
1621     <xs:complexContent>
1622       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1623         <xs:attribute name='name' type='xs:NCName'  use='required' />
1624         <xs:attribute name='message' type='xs:QName' use='required' />
1625       </xs:extension>
1626     </xs:complexContent>
1627   </xs:complexType>
1628      
1629   <xs:complexType name='tBinding' >
1630     <xs:complexContent>
1631       <xs:extension base='wsdl:tExtensibleDocumented' >
1632         <xs:sequence>
1633           <xs:element name='operation' type='wsdl:tBindingOperation' minOccurs='0' maxOccurs='unbounded' />
1634         </xs:sequence>
1635         <xs:attribute name='name' type='xs:NCName' use='required' />
1636         <xs:attribute name='type' type='xs:QName' use='required' />
1637       </xs:extension>
1638     </xs:complexContent>
1639   </xs:complexType>
1640     
1641   <xs:complexType name='tBindingOperationMessage' >
1642     <xs:complexContent>
1643       <xs:extension base='wsdl:tExtensibleDocumented' >
1644         <xs:attribute name='name' type='xs:NCName' use='optional' />
1645       </xs:extension>
1646     </xs:complexContent>
1647   </xs:complexType>
1648   
1649   <xs:complexType name='tBindingOperationFault' >
1650     <xs:complexContent>
1651       <xs:extension base='wsdl:tExtensibleDocumented' >
1652         <xs:attribute name='name' type='xs:NCName' use='required' />
1653       </xs:extension>
1654     </xs:complexContent>
1655   </xs:complexType>
1656
1657   <xs:complexType name='tBindingOperation' >
1658     <xs:complexContent>
1659       <xs:extension base='wsdl:tExtensibleDocumented' >
1660         <xs:sequence>
1661           <xs:element name='input' type='wsdl:tBindingOperationMessage' minOccurs='0' />
1662           <xs:element name='output' type='wsdl:tBindingOperationMessage' minOccurs='0' />
1663           <xs:element name='fault' type='wsdl:tBindingOperationFault' minOccurs='0' maxOccurs='unbounded' />
1664         </xs:sequence>
1665         <xs:attribute name='name' type='xs:NCName' use='required' />
1666       </xs:extension>
1667     </xs:complexContent>
1668   </xs:complexType>
1669      
1670   <xs:complexType name='tService' >
1671     <xs:complexContent>
1672       <xs:extension base='wsdl:tExtensibleDocumented' >
1673         <xs:sequence>
1674           <xs:element name='port' type='wsdl:tPort' minOccurs='0' maxOccurs='unbounded' />
1675         </xs:sequence>
1676         <xs:attribute name='name' type='xs:NCName' use='required' />
1677       </xs:extension>
1678     </xs:complexContent>
1679   </xs:complexType>
1680      
1681   <xs:complexType name='tPort' >
1682     <xs:complexContent>
1683       <xs:extension base='wsdl:tExtensibleDocumented' >
1684         <xs:attribute name='name' type='xs:NCName' use='required' />
1685         <xs:attribute name='binding' type='xs:QName' use='required' />
1686       </xs:extension>
1687     </xs:complexContent>
1688   </xs:complexType>
1689
1690   <xs:attribute name='arrayType' type='xs:string' />
1691   <xs:attribute name='required' type='xs:boolean' />
1692   <xs:complexType name='tExtensibilityElement' abstract='true' >
1693     <xs:attribute ref='wsdl:required' use='optional' />
1694   </xs:complexType>
1695
1696 </xs:schema>";
1697
1698         const string soap = @"<?xml version='1.0' encoding='UTF-8' ?> 
1699 <xs:schema xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' targetNamespace='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
1700   <xs:import namespace='http://schemas.xmlsoap.org/wsdl/' />
1701   <xs:simpleType name='encodingStyle'>
1702     <xs:annotation>
1703       <xs:documentation>
1704       'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element.  For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
1705       </xs:documentation>
1706     </xs:annotation>
1707     <xs:list itemType='xs:anyURI' />
1708   </xs:simpleType>
1709   <xs:element name='binding' type='soap:tBinding' />
1710   <xs:complexType name='tBinding'>
1711     <xs:complexContent mixed='false'>
1712       <xs:extension base='wsdl:tExtensibilityElement'>
1713         <xs:attribute name='transport' type='xs:anyURI' use='required' />
1714         <xs:attribute name='style' type='soap:tStyleChoice' use='optional' />
1715       </xs:extension>
1716     </xs:complexContent>
1717   </xs:complexType>
1718   <xs:simpleType name='tStyleChoice'>
1719     <xs:restriction base='xs:string'>
1720       <xs:enumeration value='rpc' />
1721       <xs:enumeration value='document' />
1722     </xs:restriction>
1723   </xs:simpleType>
1724   <xs:element name='operation' type='soap:tOperation' />
1725   <xs:complexType name='tOperation'>
1726     <xs:complexContent mixed='false'>
1727       <xs:extension base='wsdl:tExtensibilityElement'>
1728         <xs:attribute name='soapAction' type='xs:anyURI' use='optional' />
1729         <xs:attribute name='style' type='soap:tStyleChoice' use='optional' />
1730       </xs:extension>
1731     </xs:complexContent>
1732   </xs:complexType>
1733   <xs:element name='body' type='soap:tBody' />
1734   <xs:attributeGroup name='tBodyAttributes'>
1735     <xs:attribute name='encodingStyle' type='soap:encodingStyle' use='optional' />
1736     <xs:attribute name='use' type='soap:useChoice' use='optional' />
1737     <xs:attribute name='namespace' type='xs:anyURI' use='optional' />
1738   </xs:attributeGroup>
1739   <xs:complexType name='tBody'>
1740     <xs:complexContent mixed='false'>
1741       <xs:extension base='wsdl:tExtensibilityElement'>
1742         <xs:attribute name='parts' type='xs:NMTOKENS' use='optional' />
1743         <xs:attributeGroup ref='soap:tBodyAttributes' />
1744       </xs:extension>
1745     </xs:complexContent>
1746   </xs:complexType>
1747   <xs:simpleType name='useChoice'>
1748     <xs:restriction base='xs:string'>
1749       <xs:enumeration value='literal' />
1750       <xs:enumeration value='encoded' />
1751     </xs:restriction>
1752   </xs:simpleType>
1753   <xs:element name='fault' type='soap:tFault' />
1754   <xs:complexType name='tFaultRes' abstract='true'>
1755     <xs:complexContent mixed='false'>
1756       <xs:restriction base='soap:tBody'>
1757         <xs:attribute ref='wsdl:required' use='optional' />
1758         <xs:attribute name='parts' type='xs:NMTOKENS' use='prohibited' />
1759         <xs:attributeGroup ref='soap:tBodyAttributes' />
1760       </xs:restriction>
1761     </xs:complexContent>
1762   </xs:complexType>
1763   <xs:complexType name='tFault'>
1764     <xs:complexContent mixed='false'>
1765       <xs:extension base='soap:tFaultRes'>
1766         <xs:attribute name='name' type='xs:NCName' use='required' />
1767       </xs:extension>
1768     </xs:complexContent>
1769   </xs:complexType>
1770   <xs:element name='header' type='soap:tHeader' />
1771   <xs:attributeGroup name='tHeaderAttributes'>
1772     <xs:attribute name='message' type='xs:QName' use='required' />
1773     <xs:attribute name='part' type='xs:NMTOKEN' use='required' />
1774     <xs:attribute name='use' type='soap:useChoice' use='required' />
1775     <xs:attribute name='encodingStyle' type='soap:encodingStyle' use='optional' />
1776     <xs:attribute name='namespace' type='xs:anyURI' use='optional' />
1777   </xs:attributeGroup>
1778   <xs:complexType name='tHeader'>
1779     <xs:complexContent mixed='false'>
1780       <xs:extension base='wsdl:tExtensibilityElement'>
1781         <xs:sequence>
1782           <xs:element minOccurs='0' maxOccurs='unbounded' ref='soap:headerfault' />
1783         </xs:sequence>
1784         <xs:attributeGroup ref='soap:tHeaderAttributes' />
1785       </xs:extension>
1786     </xs:complexContent>
1787   </xs:complexType>
1788   <xs:element name='headerfault' type='soap:tHeaderFault' />
1789   <xs:complexType name='tHeaderFault'>
1790     <xs:attributeGroup ref='soap:tHeaderAttributes' />
1791   </xs:complexType>
1792   <xs:element name='address' type='soap:tAddress' />
1793   <xs:complexType name='tAddress'>
1794     <xs:complexContent mixed='false'>
1795       <xs:extension base='wsdl:tExtensibilityElement'>
1796         <xs:attribute name='location' type='xs:anyURI' use='required' />
1797       </xs:extension>
1798     </xs:complexContent>
1799   </xs:complexType>
1800 </xs:schema>";
1801         const string soapEncoding = @"<?xml version='1.0' encoding='UTF-8' ?>
1802 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
1803            xmlns:tns='http://schemas.xmlsoap.org/soap/encoding/'
1804            targetNamespace='http://schemas.xmlsoap.org/soap/encoding/' >
1805         
1806  <xs:attribute name='root' >
1807    <xs:simpleType>
1808      <xs:restriction base='xs:boolean'>
1809        <xs:pattern value='0|1' />
1810      </xs:restriction>
1811    </xs:simpleType>
1812  </xs:attribute>
1813
1814   <xs:attributeGroup name='commonAttributes' >
1815     <xs:attribute name='id' type='xs:ID' />
1816     <xs:attribute name='href' type='xs:anyURI' />
1817     <xs:anyAttribute namespace='##other' processContents='lax' />
1818   </xs:attributeGroup>
1819    
1820   <xs:simpleType name='arrayCoordinate' >
1821     <xs:restriction base='xs:string' />
1822   </xs:simpleType>
1823           
1824   <xs:attribute name='arrayType' type='xs:string' />
1825   <xs:attribute name='offset' type='tns:arrayCoordinate' />
1826   
1827   <xs:attributeGroup name='arrayAttributes' >
1828     <xs:attribute ref='tns:arrayType' />
1829     <xs:attribute ref='tns:offset' />
1830   </xs:attributeGroup>    
1831   
1832   <xs:attribute name='position' type='tns:arrayCoordinate' /> 
1833   
1834   <xs:attributeGroup name='arrayMemberAttributes' >
1835     <xs:attribute ref='tns:position' />
1836   </xs:attributeGroup>    
1837
1838   <xs:group name='Array' >
1839     <xs:sequence>
1840       <xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1841     </xs:sequence>
1842   </xs:group>
1843
1844   <xs:element name='Array' type='tns:Array' />
1845   <xs:complexType name='Array' >
1846     <xs:group ref='tns:Array' minOccurs='0' />
1847     <xs:attributeGroup ref='tns:arrayAttributes' />
1848     <xs:attributeGroup ref='tns:commonAttributes' />
1849   </xs:complexType> 
1850   <xs:element name='Struct' type='tns:Struct' />
1851   <xs:group name='Struct' >
1852     <xs:sequence>
1853       <xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1854     </xs:sequence>
1855   </xs:group>
1856
1857   <xs:complexType name='Struct' >
1858     <xs:group ref='tns:Struct' minOccurs='0' />
1859     <xs:attributeGroup ref='tns:commonAttributes'/>
1860   </xs:complexType> 
1861   
1862   <xs:simpleType name='base64' >
1863     <xs:restriction base='xs:base64Binary' />
1864   </xs:simpleType>
1865
1866   <xs:element name='duration' type='tns:duration' />
1867   <xs:complexType name='duration' >
1868     <xs:simpleContent>
1869       <xs:extension base='xs:duration' >
1870         <xs:attributeGroup ref='tns:commonAttributes' />
1871       </xs:extension>
1872     </xs:simpleContent>
1873   </xs:complexType>
1874
1875   <xs:element name='dateTime' type='tns:dateTime' />
1876   <xs:complexType name='dateTime' >
1877     <xs:simpleContent>
1878       <xs:extension base='xs:dateTime' >
1879         <xs:attributeGroup ref='tns:commonAttributes' />
1880       </xs:extension>
1881     </xs:simpleContent>
1882   </xs:complexType>
1883
1884
1885
1886   <xs:element name='NOTATION' type='tns:NOTATION' />
1887   <xs:complexType name='NOTATION' >
1888     <xs:simpleContent>
1889       <xs:extension base='xs:QName' >
1890         <xs:attributeGroup ref='tns:commonAttributes' />
1891       </xs:extension>
1892     </xs:simpleContent>
1893   </xs:complexType>
1894   
1895
1896   <xs:element name='time' type='tns:time' />
1897   <xs:complexType name='time' >
1898     <xs:simpleContent>
1899       <xs:extension base='xs:time' >
1900         <xs:attributeGroup ref='tns:commonAttributes' />
1901       </xs:extension>
1902     </xs:simpleContent>
1903   </xs:complexType>
1904
1905   <xs:element name='date' type='tns:date' />
1906   <xs:complexType name='date' >
1907     <xs:simpleContent>
1908       <xs:extension base='xs:date' >
1909         <xs:attributeGroup ref='tns:commonAttributes' />
1910       </xs:extension>
1911     </xs:simpleContent>
1912   </xs:complexType>
1913
1914   <xs:element name='gYearMonth' type='tns:gYearMonth' />
1915   <xs:complexType name='gYearMonth' >
1916     <xs:simpleContent>
1917       <xs:extension base='xs:gYearMonth' >
1918         <xs:attributeGroup ref='tns:commonAttributes' />
1919       </xs:extension>
1920     </xs:simpleContent>
1921   </xs:complexType>
1922
1923   <xs:element name='gYear' type='tns:gYear' />
1924   <xs:complexType name='gYear' >
1925     <xs:simpleContent>
1926       <xs:extension base='xs:gYear' >
1927         <xs:attributeGroup ref='tns:commonAttributes' />
1928       </xs:extension>
1929     </xs:simpleContent>
1930   </xs:complexType>
1931
1932   <xs:element name='gMonthDay' type='tns:gMonthDay' />
1933   <xs:complexType name='gMonthDay' >
1934     <xs:simpleContent>
1935       <xs:extension base='xs:gMonthDay' >
1936         <xs:attributeGroup ref='tns:commonAttributes' />
1937       </xs:extension>
1938     </xs:simpleContent>
1939   </xs:complexType>
1940
1941   <xs:element name='gDay' type='tns:gDay' />
1942   <xs:complexType name='gDay' >
1943     <xs:simpleContent>
1944       <xs:extension base='xs:gDay' >
1945         <xs:attributeGroup ref='tns:commonAttributes' />
1946       </xs:extension>
1947     </xs:simpleContent>
1948   </xs:complexType>
1949
1950   <xs:element name='gMonth' type='tns:gMonth' />
1951   <xs:complexType name='gMonth' >
1952     <xs:simpleContent>
1953       <xs:extension base='xs:gMonth' >
1954         <xs:attributeGroup ref='tns:commonAttributes' />
1955       </xs:extension>
1956     </xs:simpleContent>
1957   </xs:complexType>
1958   
1959   <xs:element name='boolean' type='tns:boolean' />
1960   <xs:complexType name='boolean' >
1961     <xs:simpleContent>
1962       <xs:extension base='xs:boolean' >
1963         <xs:attributeGroup ref='tns:commonAttributes' />
1964       </xs:extension>
1965     </xs:simpleContent>
1966   </xs:complexType>
1967
1968   <xs:element name='base64Binary' type='tns:base64Binary' />
1969   <xs:complexType name='base64Binary' >
1970     <xs:simpleContent>
1971       <xs:extension base='xs:base64Binary' >
1972         <xs:attributeGroup ref='tns:commonAttributes' />
1973       </xs:extension>
1974     </xs:simpleContent>
1975   </xs:complexType>
1976
1977   <xs:element name='hexBinary' type='tns:hexBinary' />
1978   <xs:complexType name='hexBinary' >
1979     <xs:simpleContent>
1980      <xs:extension base='xs:hexBinary' >
1981        <xs:attributeGroup ref='tns:commonAttributes' />
1982      </xs:extension>
1983     </xs:simpleContent>
1984   </xs:complexType>
1985
1986   <xs:element name='float' type='tns:float' />
1987   <xs:complexType name='float' >
1988     <xs:simpleContent>
1989       <xs:extension base='xs:float' >
1990         <xs:attributeGroup ref='tns:commonAttributes' />
1991       </xs:extension>
1992     </xs:simpleContent>
1993   </xs:complexType>
1994
1995   <xs:element name='double' type='tns:double' />
1996   <xs:complexType name='double' >
1997     <xs:simpleContent>
1998       <xs:extension base='xs:double' >
1999         <xs:attributeGroup ref='tns:commonAttributes' />
2000       </xs:extension>
2001     </xs:simpleContent>
2002   </xs:complexType>
2003
2004   <xs:element name='anyURI' type='tns:anyURI' />
2005   <xs:complexType name='anyURI' >
2006     <xs:simpleContent>
2007       <xs:extension base='xs:anyURI' >
2008         <xs:attributeGroup ref='tns:commonAttributes' />
2009       </xs:extension>
2010     </xs:simpleContent>
2011   </xs:complexType>
2012
2013   <xs:element name='QName' type='tns:QName' />
2014   <xs:complexType name='QName' >
2015     <xs:simpleContent>
2016       <xs:extension base='xs:QName' >
2017         <xs:attributeGroup ref='tns:commonAttributes' />
2018       </xs:extension>
2019     </xs:simpleContent>
2020   </xs:complexType>
2021
2022   
2023   <xs:element name='string' type='tns:string' />
2024   <xs:complexType name='string' >
2025     <xs:simpleContent>
2026       <xs:extension base='xs:string' >
2027         <xs:attributeGroup ref='tns:commonAttributes' />
2028       </xs:extension>
2029     </xs:simpleContent>
2030   </xs:complexType>
2031
2032   <xs:element name='normalizedString' type='tns:normalizedString' />
2033   <xs:complexType name='normalizedString' >
2034     <xs:simpleContent>
2035       <xs:extension base='xs:normalizedString' >
2036         <xs:attributeGroup ref='tns:commonAttributes' />
2037       </xs:extension>
2038     </xs:simpleContent>
2039   </xs:complexType>
2040
2041   <xs:element name='token' type='tns:token' />
2042   <xs:complexType name='token' >
2043     <xs:simpleContent>
2044       <xs:extension base='xs:token' >
2045         <xs:attributeGroup ref='tns:commonAttributes' />
2046       </xs:extension>
2047     </xs:simpleContent>
2048   </xs:complexType>
2049
2050   <xs:element name='language' type='tns:language' />
2051   <xs:complexType name='language' >
2052     <xs:simpleContent>
2053       <xs:extension base='xs:language' >
2054         <xs:attributeGroup ref='tns:commonAttributes' />
2055       </xs:extension>
2056     </xs:simpleContent>
2057   </xs:complexType>
2058
2059   <xs:element name='Name' type='tns:Name' />
2060   <xs:complexType name='Name' >
2061     <xs:simpleContent>
2062       <xs:extension base='xs:Name' >
2063         <xs:attributeGroup ref='tns:commonAttributes' />
2064       </xs:extension>
2065     </xs:simpleContent>
2066   </xs:complexType>
2067
2068   <xs:element name='NMTOKEN' type='tns:NMTOKEN' />
2069   <xs:complexType name='NMTOKEN' >
2070     <xs:simpleContent>
2071       <xs:extension base='xs:NMTOKEN' >
2072         <xs:attributeGroup ref='tns:commonAttributes' />
2073       </xs:extension>
2074     </xs:simpleContent>
2075   </xs:complexType>
2076
2077   <xs:element name='NCName' type='tns:NCName' />
2078   <xs:complexType name='NCName' >
2079     <xs:simpleContent>
2080       <xs:extension base='xs:NCName' >
2081         <xs:attributeGroup ref='tns:commonAttributes' />
2082       </xs:extension>
2083     </xs:simpleContent>
2084   </xs:complexType>
2085
2086   <xs:element name='NMTOKENS' type='tns:NMTOKENS' />
2087   <xs:complexType name='NMTOKENS' >
2088     <xs:simpleContent>
2089       <xs:extension base='xs:NMTOKENS' >
2090         <xs:attributeGroup ref='tns:commonAttributes' />
2091       </xs:extension>
2092     </xs:simpleContent>
2093   </xs:complexType>
2094
2095   <xs:element name='ID' type='tns:ID' />
2096   <xs:complexType name='ID' >
2097     <xs:simpleContent>
2098       <xs:extension base='xs:ID' >
2099         <xs:attributeGroup ref='tns:commonAttributes' />
2100       </xs:extension>
2101     </xs:simpleContent>
2102   </xs:complexType>
2103
2104   <xs:element name='IDREF' type='tns:IDREF' />
2105   <xs:complexType name='IDREF' >
2106     <xs:simpleContent>
2107       <xs:extension base='xs:IDREF' >
2108         <xs:attributeGroup ref='tns:commonAttributes' />
2109       </xs:extension>
2110     </xs:simpleContent>
2111   </xs:complexType>
2112
2113   <xs:element name='ENTITY' type='tns:ENTITY' />
2114   <xs:complexType name='ENTITY' >
2115     <xs:simpleContent>
2116       <xs:extension base='xs:ENTITY' >
2117         <xs:attributeGroup ref='tns:commonAttributes' />
2118       </xs:extension>
2119     </xs:simpleContent>
2120   </xs:complexType>
2121
2122   <xs:element name='IDREFS' type='tns:IDREFS' />
2123   <xs:complexType name='IDREFS' >
2124     <xs:simpleContent>
2125       <xs:extension base='xs:IDREFS' >
2126         <xs:attributeGroup ref='tns:commonAttributes' />
2127       </xs:extension>
2128     </xs:simpleContent>
2129   </xs:complexType>
2130
2131   <xs:element name='ENTITIES' type='tns:ENTITIES' />
2132   <xs:complexType name='ENTITIES' >
2133     <xs:simpleContent>
2134       <xs:extension base='xs:ENTITIES' >
2135         <xs:attributeGroup ref='tns:commonAttributes' />
2136       </xs:extension>
2137     </xs:simpleContent>
2138   </xs:complexType>
2139
2140   <xs:element name='decimal' type='tns:decimal' />
2141   <xs:complexType name='decimal' >
2142     <xs:simpleContent>
2143       <xs:extension base='xs:decimal' >
2144         <xs:attributeGroup ref='tns:commonAttributes' />
2145       </xs:extension>
2146     </xs:simpleContent>
2147   </xs:complexType>
2148
2149   <xs:element name='integer' type='tns:integer' />
2150   <xs:complexType name='integer' >
2151     <xs:simpleContent>
2152       <xs:extension base='xs:integer' >
2153         <xs:attributeGroup ref='tns:commonAttributes' />
2154       </xs:extension>
2155     </xs:simpleContent>
2156   </xs:complexType>
2157
2158   <xs:element name='nonPositiveInteger' type='tns:nonPositiveInteger' />
2159   <xs:complexType name='nonPositiveInteger' >
2160     <xs:simpleContent>
2161       <xs:extension base='xs:nonPositiveInteger' >
2162         <xs:attributeGroup ref='tns:commonAttributes' />
2163       </xs:extension>
2164     </xs:simpleContent>
2165   </xs:complexType>
2166
2167   <xs:element name='negativeInteger' type='tns:negativeInteger' />
2168   <xs:complexType name='negativeInteger' >
2169     <xs:simpleContent>
2170       <xs:extension base='xs:negativeInteger' >
2171         <xs:attributeGroup ref='tns:commonAttributes' />
2172       </xs:extension>
2173     </xs:simpleContent>
2174   </xs:complexType>
2175
2176   <xs:element name='long' type='tns:long' />
2177   <xs:complexType name='long' >
2178     <xs:simpleContent>
2179       <xs:extension base='xs:long' >
2180         <xs:attributeGroup ref='tns:commonAttributes' />
2181       </xs:extension>
2182     </xs:simpleContent>
2183   </xs:complexType>
2184
2185   <xs:element name='int' type='tns:int' />
2186   <xs:complexType name='int' >
2187     <xs:simpleContent>
2188       <xs:extension base='xs:int' >
2189         <xs:attributeGroup ref='tns:commonAttributes' />
2190       </xs:extension>
2191     </xs:simpleContent>
2192   </xs:complexType>
2193
2194   <xs:element name='short' type='tns:short' />
2195   <xs:complexType name='short' >
2196     <xs:simpleContent>
2197       <xs:extension base='xs:short' >
2198         <xs:attributeGroup ref='tns:commonAttributes' />
2199       </xs:extension>
2200     </xs:simpleContent>
2201   </xs:complexType>
2202
2203   <xs:element name='byte' type='tns:byte' />
2204   <xs:complexType name='byte' >
2205     <xs:simpleContent>
2206       <xs:extension base='xs:byte' >
2207         <xs:attributeGroup ref='tns:commonAttributes' />
2208       </xs:extension>
2209     </xs:simpleContent>
2210   </xs:complexType>
2211
2212   <xs:element name='nonNegativeInteger' type='tns:nonNegativeInteger' />
2213   <xs:complexType name='nonNegativeInteger' >
2214     <xs:simpleContent>
2215       <xs:extension base='xs:nonNegativeInteger' >
2216         <xs:attributeGroup ref='tns:commonAttributes' />
2217       </xs:extension>
2218     </xs:simpleContent>
2219   </xs:complexType>
2220
2221   <xs:element name='unsignedLong' type='tns:unsignedLong' />
2222   <xs:complexType name='unsignedLong' >
2223     <xs:simpleContent>
2224       <xs:extension base='xs:unsignedLong' >
2225         <xs:attributeGroup ref='tns:commonAttributes' />
2226       </xs:extension>
2227     </xs:simpleContent>
2228   </xs:complexType>
2229
2230   <xs:element name='unsignedInt' type='tns:unsignedInt' />
2231   <xs:complexType name='unsignedInt' >
2232     <xs:simpleContent>
2233       <xs:extension base='xs:unsignedInt' >
2234         <xs:attributeGroup ref='tns:commonAttributes' />
2235       </xs:extension>
2236     </xs:simpleContent>
2237   </xs:complexType>
2238
2239   <xs:element name='unsignedShort' type='tns:unsignedShort' />
2240   <xs:complexType name='unsignedShort' >
2241     <xs:simpleContent>
2242       <xs:extension base='xs:unsignedShort' >
2243         <xs:attributeGroup ref='tns:commonAttributes' />
2244       </xs:extension>
2245     </xs:simpleContent>
2246   </xs:complexType>
2247
2248   <xs:element name='unsignedByte' type='tns:unsignedByte' />
2249   <xs:complexType name='unsignedByte' >
2250     <xs:simpleContent>
2251       <xs:extension base='xs:unsignedByte' >
2252         <xs:attributeGroup ref='tns:commonAttributes' />
2253       </xs:extension>
2254     </xs:simpleContent>
2255   </xs:complexType>
2256
2257   <xs:element name='positiveInteger' type='tns:positiveInteger' />
2258   <xs:complexType name='positiveInteger' >
2259     <xs:simpleContent>
2260       <xs:extension base='xs:positiveInteger' >
2261         <xs:attributeGroup ref='tns:commonAttributes' />
2262       </xs:extension>
2263     </xs:simpleContent>
2264   </xs:complexType>
2265
2266   <xs:element name='anyType' />
2267 </xs:schema>";
2268
2269         const string fakeXsd = @"<?xml version='1.0' encoding='UTF-8' ?> 
2270 <xsd:schema targetNamespace=""http://www.w3.org/2001/XMLSchema"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
2271     <xsd:element name=""schema"">
2272     <xsd:complexType />
2273     </xsd:element>
2274 </xsd:schema>";
2275
2276         const string fakeXmlSchema = @"<xs:schema targetNamespace='http://www.w3.org/XML/1998/namespace' xmlns:xs='http://www.w3.org/2001/XMLSchema' xml:lang='en'>
2277  <xs:attribute name='lang' type='xs:language'/>
2278  <xs:attribute name='space'>
2279   <xs:simpleType>
2280    <xs:restriction base='xs:NCName'>
2281     <xs:enumeration value='default'/>
2282     <xs:enumeration value='preserve'/>
2283    </xs:restriction>
2284   </xs:simpleType>
2285  </xs:attribute>
2286  <xs:attribute name='base' type='xs:anyURI'/>
2287  <xs:attribute name='id' type='xs:ID' />
2288  <xs:attributeGroup name='specialAttrs'>
2289   <xs:attribute ref='xml:base'/>
2290   <xs:attribute ref='xml:lang'/>
2291   <xs:attribute ref='xml:space'/>
2292  </xs:attributeGroup>
2293 </xs:schema>";
2294
2295
2296         const string fakeSoapEncoding = @"<?xml version='1.0' encoding='UTF-8' ?>
2297 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
2298            xmlns:tns='http://schemas.xmlsoap.org/soap/encoding/'
2299            targetNamespace='http://schemas.xmlsoap.org/soap/encoding/' >
2300         
2301   <xs:attributeGroup name='commonAttributes' >
2302     <xs:attribute name='id' type='xs:ID' />
2303     <xs:attribute name='href' type='xs:anyURI' />
2304     <xs:anyAttribute namespace='##other' processContents='lax' />
2305   </xs:attributeGroup>
2306    
2307   <xs:simpleType name='arrayCoordinate' >
2308     <xs:restriction base='xs:string' />
2309   </xs:simpleType>
2310           
2311   <xs:attribute name='arrayType' type='xs:string' />
2312   <xs:attribute name='offset' type='tns:arrayCoordinate' />
2313   
2314   <xs:attributeGroup name='arrayAttributes' >
2315     <xs:attribute ref='tns:arrayType' />
2316     <xs:attribute ref='tns:offset' />
2317   </xs:attributeGroup>    
2318
2319   <xs:group name='Array' >
2320     <xs:sequence>
2321       <xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
2322     </xs:sequence>
2323   </xs:group>
2324
2325   <xs:element name='Array' type='tns:Array' />
2326   <xs:complexType name='Array' >
2327     <xs:group ref='tns:Array' minOccurs='0' />
2328     <xs:attributeGroup ref='tns:arrayAttributes' />
2329     <xs:attributeGroup ref='tns:commonAttributes' />
2330   </xs:complexType> 
2331 </xs:schema>";
2332
2333
2334     }
2335 }