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 
ExportMessageBinding(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext, Type messageContractExporterType, OperationDescription operation)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 
OnExportMessageContract()34         protected abstract object OnExportMessageContract();
ExportHeaders(int messageIndex, object state)35         protected abstract void ExportHeaders(int messageIndex, object state);
ExportBody(int messageIndex, object state)36         protected abstract void ExportBody(int messageIndex, object state);
37 
ExportKnownTypes()38         protected abstract void ExportKnownTypes();
IsRpcStyle()39         protected abstract bool IsRpcStyle();
IsEncoded()40         protected abstract bool IsEncoded();
GetExtensionData()41         protected abstract object GetExtensionData();
42 
43         protected MessageExportContext ExportedMessages
44         {
45             get { return GetMessageExportContext(exporter); }
46         }
47 
AddElementToSchema(XmlSchemaElement element, string elementNs, XmlSchemaSet schemaSet)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 
GetMessageExportContext(WsdlExporter exporter)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 
MessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)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 
ExportMessageContract()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 
ExportMessage(int messageIndex, object state)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 
ExportFaults(object state)151         protected virtual void ExportFaults(object state)
152         {
153             foreach (FaultDescription fault in operation.Faults)
154             {
155                 ExportFault(fault);
156             }
157         }
158 
IsOperationInherited()159         protected bool IsOperationInherited()
160         {
161             return operation.DeclaringContract != contractContext.Contract;
162         }
163 
ExportAnyMessage(WsdlNS.Message message, MessagePartDescription part)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 
ExportStreamBody(WsdlNS.Message message, string wrapperName, string wrapperNs, string partName, string partNs, bool isRpc, bool skipSchemaExport)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 
ExportFault(FaultDescription fault)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 
ExportFaultElement(FaultDescription fault)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 
ExportType(Type type, string partName, string operationName, out XmlSchemaType xsdType)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 
AddMessagePart(WsdlNS.Message message, string partName, XmlQualifiedName elementName, XmlQualifiedName typeName)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 
EnsureXsdImport(string ns, WsdlNS.ServiceDescription wsdl)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 
GetContainedSchema(WsdlNS.ServiceDescription wsdl, string ns)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 
IsNullOrEmpty(XmlQualifiedName qname)346         static protected bool IsNullOrEmpty(XmlQualifiedName qname)
347         {
348             return qname == null || qname.IsEmpty;
349         }
350 
ExportGlobalElement(string elementName, string elementNs, bool isNillable, XmlQualifiedName typeName, XmlSchemaType xsdType, XmlSchemaSet schemaSet)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 
ExportLocalElement(string wrapperNs, string elementName, string elementNs, XmlQualifiedName typeName, XmlSchemaType xsdType, bool multiple, bool isOptional, bool isNillable, XmlSchemaSequence sequence, XmlSchemaSet schemaSet)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();
ExportWrappedPart(WsdlNS.Message message, string elementName, string elementNs, XmlSchemaSet schemaSet, bool skipSchemaExport)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 
CreateMessage(MessageDescription message, int messageIndex, out WsdlNS.Message wsdlMessage)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 
CreateHeaderMessage(MessageDescription message, out WsdlNS.Message wsdlMessage)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 
GetMessageName(MessageDescription messageDescription)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                 // Microsoft: 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 
GetHeaderMessageName(MessageDescription messageDescription)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 
GetFaultMessageName(string faultName)538         protected string GetFaultMessageName(string faultName)
539         {
540             string portTypeName = contractContext.WsdlPortType.Name;
541             string operationName = contractContext.GetOperation(operation).Name;
542             // Microsoft: 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 
DoesMessageNameExist(string messageName, object wsdlObject)549         static bool DoesMessageNameExist(string messageName, object wsdlObject)
550         {
551             return ((WsdlNS.ServiceDescription)wsdlObject).Messages[messageName] != null;
552         }
GetUniqueMessageName(WsdlNS.ServiceDescription wsdl, string messageNameBase)553         string GetUniqueMessageName(WsdlNS.ServiceDescription wsdl, string messageNameBase)
554         {
555             return NamingHelper.GetUniqueName(messageNameBase, DoesMessageNameExist, wsdl);
556         }
557 
ExportMessagePart(WsdlNS.Message message, MessagePartDescription part, XmlQualifiedName typeName, XmlSchemaType xsdType, bool isOptional, bool isNillable, bool skipSchemaExport, bool generateElement, string wrapperNs, XmlSchemaSequence wrapperSequence, XmlSchemaSet schemaSet)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 
AddParameterOrder(MessageDescription message)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 
GetParameterCount()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 
Compile()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 
MessageBindingExporter(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext)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 
ExportMessageBinding(OperationDescription operation, Type messageContractExporterType)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 
ExportFaultBinding(FaultDescription fault, bool isEncoded, WsdlNS.OperationBinding operationBinding)711             void ExportFaultBinding(FaultDescription fault, bool isEncoded, WsdlNS.OperationBinding operationBinding)
712             {
713                 SoapHelper.CreateSoapFaultBinding(fault.Name, endpointContext, endpointContext.GetFaultBinding(fault), isEncoded);
714             }
715 
ExportMessageBodyBinding(MessageDescription messageDescription, bool isRpc, bool isEncoded, WsdlNS.MessageBinding messageBinding)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 
ExportMessageHeaderBinding(MessageHeaderDescription header, XmlQualifiedName messageName, bool isEncoded, WsdlNS.MessageBinding messageBinding)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 
GetStyleAndUse(OperationDescription operation, Type messageContractExporterType, out bool isRpc, out bool isEncoded)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 
MessageDescriptionDictionaryKey(ContractDescription contract, MessageDescription MessageDescription)799             public MessageDescriptionDictionaryKey(ContractDescription contract, MessageDescription MessageDescription)
800             {
801                 this.Contract = contract;
802                 this.MessageDescription = MessageDescription;
803             }
804 
Equals(object obj)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 
GetHashCode()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 
TypedMessageKey(Type type, string contractNS, object extensionData)825             public TypedMessageKey(Type type, string contractNS, object extensionData)
826             {
827                 this.type = type;
828                 this.contractNS = contractNS;
829                 this.extensionData = extensionData;
830             }
831 
Equals(object obj)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.")]
GetHashCode()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 
OperationMessageKey(OperationDescription operation, int messageIndex)855             public OperationMessageKey(OperationDescription operation, int messageIndex)
856             {
857                 this.methodInfo = operation.OperationMethod;
858                 this.messageIndex = messageIndex;
859                 this.declaringContract = operation.DeclaringContract;
860             }
861 
Equals(object obj)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 
GetHashCode()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;
OperationElement(XmlSchemaElement element, 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     {
DataContractSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)895         internal DataContractSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
896             : base(exporter, context, operation, extension)
897         {
898         }
899 
Compile()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 
IsRpcStyle()918         protected override bool IsRpcStyle()
919         {
920             return ((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute.Style == OperationFormatStyle.Rpc;
921         }
922 
IsEncoded()923         protected override bool IsEncoded()
924         {
925             return false;
926         }
927 
OnExportMessageContract()928         protected override object OnExportMessageContract()
929         {
930             return null;
931         }
932 
ExportHeaders(int messageIndex, object state)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 
IsTypeNullable(Type type)956         static internal bool IsTypeNullable(Type type)
957         {
958             return !type.IsValueType ||
959                     (type.IsGenericType &&
960                     type.GetGenericTypeDefinition() == typeof(Nullable<>));
961         }
962 
ExportBody(int messageIndex, object state)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 
ExportKnownTypes()996         protected override void ExportKnownTypes()
997         {
998             foreach (Type knownType in operation.KnownTypes)
999             {
1000                 DataContractExporter.Export(knownType);
1001             }
1002         }
1003 
GetExtensionData()1004         protected override object GetExtensionData()
1005         {
1006             return new ExtensionData(((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute);
1007         }
1008         class ExtensionData
1009         {
1010             DataContractFormatAttribute dcFormatAttr;
ExtensionData(DataContractFormatAttribute dcFormatAttr)1011             internal ExtensionData(DataContractFormatAttribute dcFormatAttr)
1012             {
1013                 this.dcFormatAttr = dcFormatAttr;
1014             }
1015 
Equals(object obj)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 
GetHashCode()1026             public override int GetHashCode()
1027             {
1028                 return 1; //This is never called
1029             }
1030         }
1031     }
1032 
1033     class XmlSerializerMessageContractExporter : MessageContractExporter
1034     {
XmlSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)1035         internal XmlSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
1036             : base(exporter, context, operation, extension)
1037         {
1038         }
1039 
IsRpcStyle()1040         protected override bool IsRpcStyle()
1041         {
1042             return ((XmlSerializerOperationBehavior)extension).XmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc;
1043         }
1044 
IsEncoded()1045         protected override bool IsEncoded()
1046         {
1047             return ((XmlSerializerOperationBehavior)extension).XmlSerializerFormatAttribute.IsEncoded;
1048         }
1049 
OnExportMessageContract()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 
ExportHeaders(int messageIndex, object state)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 
ExportBody(int messageIndex, object state)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 
ExportFaults(object state)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 
ExportFault(FaultDescription fault, XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector)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 
ExportFaultElement(FaultDescription fault, XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector)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 
ExportKnownTypes()1171         protected override void ExportKnownTypes()
1172         {
1173         }
1174 
GetExtensionData()1175         protected override object GetExtensionData()
1176         {
1177             return new ExtensionData(((XmlSerializerOperationBehavior)this.extension).XmlSerializerFormatAttribute);
1178         }
1179 
1180         class ExtensionData
1181         {
1182             XmlSerializerFormatAttribute xsFormatAttr;
ExtensionData(XmlSerializerFormatAttribute xsFormatAttr)1183             internal ExtensionData(XmlSerializerFormatAttribute xsFormatAttr)
1184             {
1185                 this.xsFormatAttr = xsFormatAttr;
1186             }
1187 
Equals(object obj)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             }
GetHashCode()1198             public override int GetHashCode()
1199             {
1200                 return 1; //This is never called
1201             }
1202         }
ExportMembersMapping(XmlMembersMapping membersMapping, WsdlNS.Message message, bool skipSchemaExport, bool isEncoded, bool isRpc, bool isDocWrapped, bool isHeader)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 
Compile()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 
MoveSchemas()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 
CreateWsdl()1348         internal static XmlSchema CreateWsdl()
1349         {
1350             StringReader reader = new StringReader(wsdl);
1351             return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
1352         }
1353 
CreateSoap()1354         internal static XmlSchema CreateSoap()
1355         {
1356             StringReader reader = new StringReader(soap);
1357             return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
1358         }
1359 
CreateSoapEncoding()1360         internal static XmlSchema CreateSoapEncoding()
1361         {
1362             StringReader reader = new StringReader(soapEncoding);
1363             return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
1364         }
1365 
CreateFakeSoapEncoding()1366         internal static XmlSchema CreateFakeSoapEncoding()
1367         {
1368             StringReader reader = new StringReader(fakeSoapEncoding);
1369             return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
1370         }
1371 
CreateFakeXsdSchema()1372         internal static XmlSchema CreateFakeXsdSchema()
1373         {
1374             StringReader reader = new StringReader(fakeXsd);
1375             return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
1376         }
1377 
CreateFakeXmlSchema()1378         internal static XmlSchema CreateFakeXmlSchema()
1379         {
1380             StringReader reader = new StringReader(fakeXmlSchema);
1381             return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
1382         }
1383 
IsKnownSchema(string ns)1384         internal static bool IsKnownSchema(string ns)
1385         {
1386             return ns == XmlSchema.Namespace || ns == "http://schemas.xmlsoap.org/wsdl/soap/" || ns == "http://schemas.xmlsoap.org/soap/encoding/";
1387         }
1388 
1389         internal const string WsdlNamespace = "http://schemas.xmlsoap.org/wsdl/";
1390         internal const string SoapNamespace = "http://schemas.xmlsoap.org/wsdl/soap/";
1391         internal const string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
1392 
1393         const string wsdl = @"<?xml version='1.0' encoding='UTF-8' ?>
1394 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
1395            xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
1396            targetNamespace='http://schemas.xmlsoap.org/wsdl/'
1397            elementFormDefault='qualified' >
1398 
1399   <xs:complexType mixed='true' name='tDocumentation' >
1400     <xs:sequence>
1401       <xs:any minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1402     </xs:sequence>
1403   </xs:complexType>
1404 
1405   <xs:complexType name='tDocumented' >
1406     <xs:annotation>
1407       <xs:documentation>
1408       This type is extended by  component types to allow them to be documented
1409       </xs:documentation>
1410     </xs:annotation>
1411     <xs:sequence>
1412       <xs:element name='documentation' type='wsdl:tDocumentation' minOccurs='0' />
1413     </xs:sequence>
1414   </xs:complexType>
1415  <!-- allow extensibility via elements and attributes on all elements swa124 -->
1416  <xs:complexType name='tExtensibleAttributesDocumented' abstract='true' >
1417     <xs:complexContent>
1418       <xs:extension base='wsdl:tDocumented' >
1419         <xs:annotation>
1420           <xs:documentation>
1421           This type is extended by component types to allow attributes from other namespaces to be added.
1422           </xs:documentation>
1423         </xs:annotation>
1424         <xs:sequence>
1425           <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1426         </xs:sequence>
1427         <xs:anyAttribute namespace='##other' processContents='lax' />
1428       </xs:extension>
1429     </xs:complexContent>
1430   </xs:complexType>
1431   <xs:complexType name='tExtensibleDocumented' abstract='true' >
1432     <xs:complexContent>
1433       <xs:extension base='wsdl:tDocumented' >
1434         <xs:annotation>
1435           <xs:documentation>
1436           This type is extended by component types to allow elements from other namespaces to be added.
1437           </xs:documentation>
1438         </xs:annotation>
1439         <xs:sequence>
1440           <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1441         </xs:sequence>
1442         <xs:anyAttribute namespace='##other' processContents='lax' />
1443       </xs:extension>
1444     </xs:complexContent>
1445   </xs:complexType>
1446   <!-- original wsdl removed as part of swa124 resolution
1447   <xs:complexType name='tExtensibleAttributesDocumented' abstract='true' >
1448     <xs:complexContent>
1449       <xs:extension base='wsdl:tDocumented' >
1450         <xs:annotation>
1451           <xs:documentation>
1452           This type is extended by component types to allow attributes from other namespaces to be added.
1453           </xs:documentation>
1454         </xs:annotation>
1455         <xs:anyAttribute namespace='##other' processContents='lax' />
1456       </xs:extension>
1457     </xs:complexContent>
1458   </xs:complexType>
1459 
1460   <xs:complexType name='tExtensibleDocumented' abstract='true' >
1461     <xs:complexContent>
1462       <xs:extension base='wsdl:tDocumented' >
1463         <xs:annotation>
1464           <xs:documentation>
1465           This type is extended by component types to allow elements from other namespaces to be added.
1466           </xs:documentation>
1467         </xs:annotation>
1468         <xs:sequence>
1469           <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1470         </xs:sequence>
1471       </xs:extension>
1472     </xs:complexContent>
1473   </xs:complexType>
1474  -->
1475   <xs:element name='definitions' type='wsdl:tDefinitions' >
1476     <xs:key name='message' >
1477       <xs:selector xpath='wsdl:message' />
1478       <xs:field xpath='@name' />
1479     </xs:key>
1480     <xs:key name='portType' >
1481       <xs:selector xpath='wsdl:portType' />
1482       <xs:field xpath='@name' />
1483     </xs:key>
1484     <xs:key name='binding' >
1485       <xs:selector xpath='wsdl:binding' />
1486       <xs:field xpath='@name' />
1487     </xs:key>
1488     <xs:key name='service' >
1489       <xs:selector xpath='wsdl:service' />
1490       <xs:field xpath='@name' />
1491     </xs:key>
1492     <xs:key name='import' >
1493       <xs:selector xpath='wsdl:import' />
1494       <xs:field xpath='@namespace' />
1495     </xs:key>
1496   </xs:element>
1497 
1498   <xs:group name='anyTopLevelOptionalElement' >
1499     <xs:annotation>
1500       <xs:documentation>
1501       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.
1502       </xs:documentation>
1503     </xs:annotation>
1504     <xs:choice>
1505       <xs:element name='import' type='wsdl:tImport' />
1506       <xs:element name='types' type='wsdl:tTypes' />
1507       <xs:element name='message'  type='wsdl:tMessage' >
1508         <xs:unique name='part' >
1509           <xs:selector xpath='wsdl:part' />
1510           <xs:field xpath='@name' />
1511         </xs:unique>
1512       </xs:element>
1513       <xs:element name='portType' type='wsdl:tPortType' />
1514       <xs:element name='binding'  type='wsdl:tBinding' />
1515       <xs:element name='service'  type='wsdl:tService' >
1516         <xs:unique name='port' >
1517           <xs:selector xpath='wsdl:port' />
1518           <xs:field xpath='@name' />
1519         </xs:unique>
1520       </xs:element>
1521     </xs:choice>
1522   </xs:group>
1523 
1524   <xs:complexType name='tDefinitions' >
1525     <xs:complexContent>
1526       <xs:extension base='wsdl:tExtensibleDocumented' >
1527         <xs:sequence>
1528           <xs:group ref='wsdl:anyTopLevelOptionalElement'  minOccurs='0'   maxOccurs='unbounded' />
1529         </xs:sequence>
1530         <xs:attribute name='targetNamespace' type='xs:anyURI' use='optional' />
1531         <xs:attribute name='name' type='xs:NCName' use='optional' />
1532       </xs:extension>
1533     </xs:complexContent>
1534   </xs:complexType>
1535 
1536   <xs:complexType name='tImport' >
1537     <xs:complexContent>
1538       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1539         <xs:attribute name='namespace' type='xs:anyURI' use='required' />
1540         <xs:attribute name='location' type='xs:anyURI' use='required' />
1541       </xs:extension>
1542     </xs:complexContent>
1543   </xs:complexType>
1544 
1545   <xs:complexType name='tTypes' >
1546     <xs:complexContent>
1547       <xs:extension base='wsdl:tExtensibleDocumented' />
1548     </xs:complexContent>
1549   </xs:complexType>
1550 
1551   <xs:complexType name='tMessage' >
1552     <xs:complexContent>
1553       <xs:extension base='wsdl:tExtensibleDocumented' >
1554         <xs:sequence>
1555           <xs:element name='part' type='wsdl:tPart' minOccurs='0' maxOccurs='unbounded' />
1556         </xs:sequence>
1557         <xs:attribute name='name' type='xs:NCName' use='required' />
1558       </xs:extension>
1559     </xs:complexContent>
1560   </xs:complexType>
1561 
1562   <xs:complexType name='tPart' >
1563     <xs:complexContent>
1564       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1565         <xs:attribute name='name' type='xs:NCName' use='required' />
1566         <xs:attribute name='element' type='xs:QName' use='optional' />
1567         <xs:attribute name='type' type='xs:QName' use='optional' />
1568       </xs:extension>
1569     </xs:complexContent>
1570   </xs:complexType>
1571 
1572   <xs:complexType name='tPortType' >
1573     <xs:complexContent>
1574       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1575         <xs:sequence>
1576           <xs:element name='operation' type='wsdl:tOperation' minOccurs='0' maxOccurs='unbounded' />
1577         </xs:sequence>
1578         <xs:attribute name='name' type='xs:NCName' use='required' />
1579       </xs:extension>
1580     </xs:complexContent>
1581   </xs:complexType>
1582 
1583   <xs:complexType name='tOperation' >
1584     <xs:complexContent>
1585       <xs:extension base='wsdl:tExtensibleDocumented' >
1586         <xs:sequence>
1587           <xs:choice>
1588             <xs:group ref='wsdl:request-response-or-one-way-operation' />
1589             <xs:group ref='wsdl:solicit-response-or-notification-operation' />
1590           </xs:choice>
1591         </xs:sequence>
1592         <xs:attribute name='name' type='xs:NCName' use='required' />
1593         <xs:attribute name='parameterOrder' type='xs:NMTOKENS' use='optional' />
1594       </xs:extension>
1595     </xs:complexContent>
1596   </xs:complexType>
1597 
1598   <xs:group name='request-response-or-one-way-operation' >
1599     <xs:sequence>
1600       <xs:element name='input' type='wsdl:tParam' />
1601       <xs:sequence minOccurs='0' >
1602         <xs:element name='output' type='wsdl:tParam' />
1603         <xs:element name='fault' type='wsdl:tFault' minOccurs='0' maxOccurs='unbounded' />
1604       </xs:sequence>
1605     </xs:sequence>
1606   </xs:group>
1607 
1608   <xs:group name='solicit-response-or-notification-operation' >
1609     <xs:sequence>
1610       <xs:element name='output' type='wsdl:tParam' />
1611       <xs:sequence minOccurs='0' >
1612         <xs:element name='input' type='wsdl:tParam' />
1613         <xs:element name='fault' type='wsdl:tFault' minOccurs='0' maxOccurs='unbounded' />
1614       </xs:sequence>
1615     </xs:sequence>
1616   </xs:group>
1617 
1618   <xs:complexType name='tParam' >
1619     <xs:complexContent>
1620       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1621         <xs:attribute name='name' type='xs:NCName' use='optional' />
1622         <xs:attribute name='message' type='xs:QName' use='required' />
1623       </xs:extension>
1624     </xs:complexContent>
1625   </xs:complexType>
1626 
1627   <xs:complexType name='tFault' >
1628     <xs:complexContent>
1629       <xs:extension base='wsdl:tExtensibleAttributesDocumented' >
1630         <xs:attribute name='name' type='xs:NCName'  use='required' />
1631         <xs:attribute name='message' type='xs:QName' use='required' />
1632       </xs:extension>
1633     </xs:complexContent>
1634   </xs:complexType>
1635 
1636   <xs:complexType name='tBinding' >
1637     <xs:complexContent>
1638       <xs:extension base='wsdl:tExtensibleDocumented' >
1639         <xs:sequence>
1640           <xs:element name='operation' type='wsdl:tBindingOperation' minOccurs='0' maxOccurs='unbounded' />
1641         </xs:sequence>
1642         <xs:attribute name='name' type='xs:NCName' use='required' />
1643         <xs:attribute name='type' type='xs:QName' use='required' />
1644       </xs:extension>
1645     </xs:complexContent>
1646   </xs:complexType>
1647 
1648   <xs:complexType name='tBindingOperationMessage' >
1649     <xs:complexContent>
1650       <xs:extension base='wsdl:tExtensibleDocumented' >
1651         <xs:attribute name='name' type='xs:NCName' use='optional' />
1652       </xs:extension>
1653     </xs:complexContent>
1654   </xs:complexType>
1655 
1656   <xs:complexType name='tBindingOperationFault' >
1657     <xs:complexContent>
1658       <xs:extension base='wsdl:tExtensibleDocumented' >
1659         <xs:attribute name='name' type='xs:NCName' use='required' />
1660       </xs:extension>
1661     </xs:complexContent>
1662   </xs:complexType>
1663 
1664   <xs:complexType name='tBindingOperation' >
1665     <xs:complexContent>
1666       <xs:extension base='wsdl:tExtensibleDocumented' >
1667         <xs:sequence>
1668           <xs:element name='input' type='wsdl:tBindingOperationMessage' minOccurs='0' />
1669           <xs:element name='output' type='wsdl:tBindingOperationMessage' minOccurs='0' />
1670           <xs:element name='fault' type='wsdl:tBindingOperationFault' minOccurs='0' maxOccurs='unbounded' />
1671         </xs:sequence>
1672         <xs:attribute name='name' type='xs:NCName' use='required' />
1673       </xs:extension>
1674     </xs:complexContent>
1675   </xs:complexType>
1676 
1677   <xs:complexType name='tService' >
1678     <xs:complexContent>
1679       <xs:extension base='wsdl:tExtensibleDocumented' >
1680         <xs:sequence>
1681           <xs:element name='port' type='wsdl:tPort' minOccurs='0' maxOccurs='unbounded' />
1682         </xs:sequence>
1683         <xs:attribute name='name' type='xs:NCName' use='required' />
1684       </xs:extension>
1685     </xs:complexContent>
1686   </xs:complexType>
1687 
1688   <xs:complexType name='tPort' >
1689     <xs:complexContent>
1690       <xs:extension base='wsdl:tExtensibleDocumented' >
1691         <xs:attribute name='name' type='xs:NCName' use='required' />
1692         <xs:attribute name='binding' type='xs:QName' use='required' />
1693       </xs:extension>
1694     </xs:complexContent>
1695   </xs:complexType>
1696 
1697   <xs:attribute name='arrayType' type='xs:string' />
1698   <xs:attribute name='required' type='xs:boolean' />
1699   <xs:complexType name='tExtensibilityElement' abstract='true' >
1700     <xs:attribute ref='wsdl:required' use='optional' />
1701   </xs:complexType>
1702 
1703 </xs:schema>";
1704 
1705         const string soap = @"<?xml version='1.0' encoding='UTF-8' ?>
1706 <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'>
1707   <xs:import namespace='http://schemas.xmlsoap.org/wsdl/' />
1708   <xs:simpleType name='encodingStyle'>
1709     <xs:annotation>
1710       <xs:documentation>
1711       '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
1712       </xs:documentation>
1713     </xs:annotation>
1714     <xs:list itemType='xs:anyURI' />
1715   </xs:simpleType>
1716   <xs:element name='binding' type='soap:tBinding' />
1717   <xs:complexType name='tBinding'>
1718     <xs:complexContent mixed='false'>
1719       <xs:extension base='wsdl:tExtensibilityElement'>
1720         <xs:attribute name='transport' type='xs:anyURI' use='required' />
1721         <xs:attribute name='style' type='soap:tStyleChoice' use='optional' />
1722       </xs:extension>
1723     </xs:complexContent>
1724   </xs:complexType>
1725   <xs:simpleType name='tStyleChoice'>
1726     <xs:restriction base='xs:string'>
1727       <xs:enumeration value='rpc' />
1728       <xs:enumeration value='document' />
1729     </xs:restriction>
1730   </xs:simpleType>
1731   <xs:element name='operation' type='soap:tOperation' />
1732   <xs:complexType name='tOperation'>
1733     <xs:complexContent mixed='false'>
1734       <xs:extension base='wsdl:tExtensibilityElement'>
1735         <xs:attribute name='soapAction' type='xs:anyURI' use='optional' />
1736         <xs:attribute name='style' type='soap:tStyleChoice' use='optional' />
1737       </xs:extension>
1738     </xs:complexContent>
1739   </xs:complexType>
1740   <xs:element name='body' type='soap:tBody' />
1741   <xs:attributeGroup name='tBodyAttributes'>
1742     <xs:attribute name='encodingStyle' type='soap:encodingStyle' use='optional' />
1743     <xs:attribute name='use' type='soap:useChoice' use='optional' />
1744     <xs:attribute name='namespace' type='xs:anyURI' use='optional' />
1745   </xs:attributeGroup>
1746   <xs:complexType name='tBody'>
1747     <xs:complexContent mixed='false'>
1748       <xs:extension base='wsdl:tExtensibilityElement'>
1749         <xs:attribute name='parts' type='xs:NMTOKENS' use='optional' />
1750         <xs:attributeGroup ref='soap:tBodyAttributes' />
1751       </xs:extension>
1752     </xs:complexContent>
1753   </xs:complexType>
1754   <xs:simpleType name='useChoice'>
1755     <xs:restriction base='xs:string'>
1756       <xs:enumeration value='literal' />
1757       <xs:enumeration value='encoded' />
1758     </xs:restriction>
1759   </xs:simpleType>
1760   <xs:element name='fault' type='soap:tFault' />
1761   <xs:complexType name='tFaultRes' abstract='true'>
1762     <xs:complexContent mixed='false'>
1763       <xs:restriction base='soap:tBody'>
1764         <xs:attribute ref='wsdl:required' use='optional' />
1765         <xs:attribute name='parts' type='xs:NMTOKENS' use='prohibited' />
1766         <xs:attributeGroup ref='soap:tBodyAttributes' />
1767       </xs:restriction>
1768     </xs:complexContent>
1769   </xs:complexType>
1770   <xs:complexType name='tFault'>
1771     <xs:complexContent mixed='false'>
1772       <xs:extension base='soap:tFaultRes'>
1773         <xs:attribute name='name' type='xs:NCName' use='required' />
1774       </xs:extension>
1775     </xs:complexContent>
1776   </xs:complexType>
1777   <xs:element name='header' type='soap:tHeader' />
1778   <xs:attributeGroup name='tHeaderAttributes'>
1779     <xs:attribute name='message' type='xs:QName' use='required' />
1780     <xs:attribute name='part' type='xs:NMTOKEN' use='required' />
1781     <xs:attribute name='use' type='soap:useChoice' use='required' />
1782     <xs:attribute name='encodingStyle' type='soap:encodingStyle' use='optional' />
1783     <xs:attribute name='namespace' type='xs:anyURI' use='optional' />
1784   </xs:attributeGroup>
1785   <xs:complexType name='tHeader'>
1786     <xs:complexContent mixed='false'>
1787       <xs:extension base='wsdl:tExtensibilityElement'>
1788         <xs:sequence>
1789           <xs:element minOccurs='0' maxOccurs='unbounded' ref='soap:headerfault' />
1790         </xs:sequence>
1791         <xs:attributeGroup ref='soap:tHeaderAttributes' />
1792       </xs:extension>
1793     </xs:complexContent>
1794   </xs:complexType>
1795   <xs:element name='headerfault' type='soap:tHeaderFault' />
1796   <xs:complexType name='tHeaderFault'>
1797     <xs:attributeGroup ref='soap:tHeaderAttributes' />
1798   </xs:complexType>
1799   <xs:element name='address' type='soap:tAddress' />
1800   <xs:complexType name='tAddress'>
1801     <xs:complexContent mixed='false'>
1802       <xs:extension base='wsdl:tExtensibilityElement'>
1803         <xs:attribute name='location' type='xs:anyURI' use='required' />
1804       </xs:extension>
1805     </xs:complexContent>
1806   </xs:complexType>
1807 </xs:schema>";
1808         const string soapEncoding = @"<?xml version='1.0' encoding='UTF-8' ?>
1809 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
1810            xmlns:tns='http://schemas.xmlsoap.org/soap/encoding/'
1811            targetNamespace='http://schemas.xmlsoap.org/soap/encoding/' >
1812 
1813  <xs:attribute name='root' >
1814    <xs:simpleType>
1815      <xs:restriction base='xs:boolean'>
1816        <xs:pattern value='0|1' />
1817      </xs:restriction>
1818    </xs:simpleType>
1819  </xs:attribute>
1820 
1821   <xs:attributeGroup name='commonAttributes' >
1822     <xs:attribute name='id' type='xs:ID' />
1823     <xs:attribute name='href' type='xs:anyURI' />
1824     <xs:anyAttribute namespace='##other' processContents='lax' />
1825   </xs:attributeGroup>
1826 
1827   <xs:simpleType name='arrayCoordinate' >
1828     <xs:restriction base='xs:string' />
1829   </xs:simpleType>
1830 
1831   <xs:attribute name='arrayType' type='xs:string' />
1832   <xs:attribute name='offset' type='tns:arrayCoordinate' />
1833 
1834   <xs:attributeGroup name='arrayAttributes' >
1835     <xs:attribute ref='tns:arrayType' />
1836     <xs:attribute ref='tns:offset' />
1837   </xs:attributeGroup>
1838 
1839   <xs:attribute name='position' type='tns:arrayCoordinate' />
1840 
1841   <xs:attributeGroup name='arrayMemberAttributes' >
1842     <xs:attribute ref='tns:position' />
1843   </xs:attributeGroup>
1844 
1845   <xs:group name='Array' >
1846     <xs:sequence>
1847       <xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1848     </xs:sequence>
1849   </xs:group>
1850 
1851   <xs:element name='Array' type='tns:Array' />
1852   <xs:complexType name='Array' >
1853     <xs:group ref='tns:Array' minOccurs='0' />
1854     <xs:attributeGroup ref='tns:arrayAttributes' />
1855     <xs:attributeGroup ref='tns:commonAttributes' />
1856   </xs:complexType>
1857   <xs:element name='Struct' type='tns:Struct' />
1858   <xs:group name='Struct' >
1859     <xs:sequence>
1860       <xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
1861     </xs:sequence>
1862   </xs:group>
1863 
1864   <xs:complexType name='Struct' >
1865     <xs:group ref='tns:Struct' minOccurs='0' />
1866     <xs:attributeGroup ref='tns:commonAttributes'/>
1867   </xs:complexType>
1868 
1869   <xs:simpleType name='base64' >
1870     <xs:restriction base='xs:base64Binary' />
1871   </xs:simpleType>
1872 
1873   <xs:element name='duration' type='tns:duration' />
1874   <xs:complexType name='duration' >
1875     <xs:simpleContent>
1876       <xs:extension base='xs:duration' >
1877         <xs:attributeGroup ref='tns:commonAttributes' />
1878       </xs:extension>
1879     </xs:simpleContent>
1880   </xs:complexType>
1881 
1882   <xs:element name='dateTime' type='tns:dateTime' />
1883   <xs:complexType name='dateTime' >
1884     <xs:simpleContent>
1885       <xs:extension base='xs:dateTime' >
1886         <xs:attributeGroup ref='tns:commonAttributes' />
1887       </xs:extension>
1888     </xs:simpleContent>
1889   </xs:complexType>
1890 
1891 
1892 
1893   <xs:element name='NOTATION' type='tns:NOTATION' />
1894   <xs:complexType name='NOTATION' >
1895     <xs:simpleContent>
1896       <xs:extension base='xs:QName' >
1897         <xs:attributeGroup ref='tns:commonAttributes' />
1898       </xs:extension>
1899     </xs:simpleContent>
1900   </xs:complexType>
1901 
1902 
1903   <xs:element name='time' type='tns:time' />
1904   <xs:complexType name='time' >
1905     <xs:simpleContent>
1906       <xs:extension base='xs:time' >
1907         <xs:attributeGroup ref='tns:commonAttributes' />
1908       </xs:extension>
1909     </xs:simpleContent>
1910   </xs:complexType>
1911 
1912   <xs:element name='date' type='tns:date' />
1913   <xs:complexType name='date' >
1914     <xs:simpleContent>
1915       <xs:extension base='xs:date' >
1916         <xs:attributeGroup ref='tns:commonAttributes' />
1917       </xs:extension>
1918     </xs:simpleContent>
1919   </xs:complexType>
1920 
1921   <xs:element name='gYearMonth' type='tns:gYearMonth' />
1922   <xs:complexType name='gYearMonth' >
1923     <xs:simpleContent>
1924       <xs:extension base='xs:gYearMonth' >
1925         <xs:attributeGroup ref='tns:commonAttributes' />
1926       </xs:extension>
1927     </xs:simpleContent>
1928   </xs:complexType>
1929 
1930   <xs:element name='gYear' type='tns:gYear' />
1931   <xs:complexType name='gYear' >
1932     <xs:simpleContent>
1933       <xs:extension base='xs:gYear' >
1934         <xs:attributeGroup ref='tns:commonAttributes' />
1935       </xs:extension>
1936     </xs:simpleContent>
1937   </xs:complexType>
1938 
1939   <xs:element name='gMonthDay' type='tns:gMonthDay' />
1940   <xs:complexType name='gMonthDay' >
1941     <xs:simpleContent>
1942       <xs:extension base='xs:gMonthDay' >
1943         <xs:attributeGroup ref='tns:commonAttributes' />
1944       </xs:extension>
1945     </xs:simpleContent>
1946   </xs:complexType>
1947 
1948   <xs:element name='gDay' type='tns:gDay' />
1949   <xs:complexType name='gDay' >
1950     <xs:simpleContent>
1951       <xs:extension base='xs:gDay' >
1952         <xs:attributeGroup ref='tns:commonAttributes' />
1953       </xs:extension>
1954     </xs:simpleContent>
1955   </xs:complexType>
1956 
1957   <xs:element name='gMonth' type='tns:gMonth' />
1958   <xs:complexType name='gMonth' >
1959     <xs:simpleContent>
1960       <xs:extension base='xs:gMonth' >
1961         <xs:attributeGroup ref='tns:commonAttributes' />
1962       </xs:extension>
1963     </xs:simpleContent>
1964   </xs:complexType>
1965 
1966   <xs:element name='boolean' type='tns:boolean' />
1967   <xs:complexType name='boolean' >
1968     <xs:simpleContent>
1969       <xs:extension base='xs:boolean' >
1970         <xs:attributeGroup ref='tns:commonAttributes' />
1971       </xs:extension>
1972     </xs:simpleContent>
1973   </xs:complexType>
1974 
1975   <xs:element name='base64Binary' type='tns:base64Binary' />
1976   <xs:complexType name='base64Binary' >
1977     <xs:simpleContent>
1978       <xs:extension base='xs:base64Binary' >
1979         <xs:attributeGroup ref='tns:commonAttributes' />
1980       </xs:extension>
1981     </xs:simpleContent>
1982   </xs:complexType>
1983 
1984   <xs:element name='hexBinary' type='tns:hexBinary' />
1985   <xs:complexType name='hexBinary' >
1986     <xs:simpleContent>
1987      <xs:extension base='xs:hexBinary' >
1988        <xs:attributeGroup ref='tns:commonAttributes' />
1989      </xs:extension>
1990     </xs:simpleContent>
1991   </xs:complexType>
1992 
1993   <xs:element name='float' type='tns:float' />
1994   <xs:complexType name='float' >
1995     <xs:simpleContent>
1996       <xs:extension base='xs:float' >
1997         <xs:attributeGroup ref='tns:commonAttributes' />
1998       </xs:extension>
1999     </xs:simpleContent>
2000   </xs:complexType>
2001 
2002   <xs:element name='double' type='tns:double' />
2003   <xs:complexType name='double' >
2004     <xs:simpleContent>
2005       <xs:extension base='xs:double' >
2006         <xs:attributeGroup ref='tns:commonAttributes' />
2007       </xs:extension>
2008     </xs:simpleContent>
2009   </xs:complexType>
2010 
2011   <xs:element name='anyURI' type='tns:anyURI' />
2012   <xs:complexType name='anyURI' >
2013     <xs:simpleContent>
2014       <xs:extension base='xs:anyURI' >
2015         <xs:attributeGroup ref='tns:commonAttributes' />
2016       </xs:extension>
2017     </xs:simpleContent>
2018   </xs:complexType>
2019 
2020   <xs:element name='QName' type='tns:QName' />
2021   <xs:complexType name='QName' >
2022     <xs:simpleContent>
2023       <xs:extension base='xs:QName' >
2024         <xs:attributeGroup ref='tns:commonAttributes' />
2025       </xs:extension>
2026     </xs:simpleContent>
2027   </xs:complexType>
2028 
2029 
2030   <xs:element name='string' type='tns:string' />
2031   <xs:complexType name='string' >
2032     <xs:simpleContent>
2033       <xs:extension base='xs:string' >
2034         <xs:attributeGroup ref='tns:commonAttributes' />
2035       </xs:extension>
2036     </xs:simpleContent>
2037   </xs:complexType>
2038 
2039   <xs:element name='normalizedString' type='tns:normalizedString' />
2040   <xs:complexType name='normalizedString' >
2041     <xs:simpleContent>
2042       <xs:extension base='xs:normalizedString' >
2043         <xs:attributeGroup ref='tns:commonAttributes' />
2044       </xs:extension>
2045     </xs:simpleContent>
2046   </xs:complexType>
2047 
2048   <xs:element name='token' type='tns:token' />
2049   <xs:complexType name='token' >
2050     <xs:simpleContent>
2051       <xs:extension base='xs:token' >
2052         <xs:attributeGroup ref='tns:commonAttributes' />
2053       </xs:extension>
2054     </xs:simpleContent>
2055   </xs:complexType>
2056 
2057   <xs:element name='language' type='tns:language' />
2058   <xs:complexType name='language' >
2059     <xs:simpleContent>
2060       <xs:extension base='xs:language' >
2061         <xs:attributeGroup ref='tns:commonAttributes' />
2062       </xs:extension>
2063     </xs:simpleContent>
2064   </xs:complexType>
2065 
2066   <xs:element name='Name' type='tns:Name' />
2067   <xs:complexType name='Name' >
2068     <xs:simpleContent>
2069       <xs:extension base='xs:Name' >
2070         <xs:attributeGroup ref='tns:commonAttributes' />
2071       </xs:extension>
2072     </xs:simpleContent>
2073   </xs:complexType>
2074 
2075   <xs:element name='NMTOKEN' type='tns:NMTOKEN' />
2076   <xs:complexType name='NMTOKEN' >
2077     <xs:simpleContent>
2078       <xs:extension base='xs:NMTOKEN' >
2079         <xs:attributeGroup ref='tns:commonAttributes' />
2080       </xs:extension>
2081     </xs:simpleContent>
2082   </xs:complexType>
2083 
2084   <xs:element name='NCName' type='tns:NCName' />
2085   <xs:complexType name='NCName' >
2086     <xs:simpleContent>
2087       <xs:extension base='xs:NCName' >
2088         <xs:attributeGroup ref='tns:commonAttributes' />
2089       </xs:extension>
2090     </xs:simpleContent>
2091   </xs:complexType>
2092 
2093   <xs:element name='NMTOKENS' type='tns:NMTOKENS' />
2094   <xs:complexType name='NMTOKENS' >
2095     <xs:simpleContent>
2096       <xs:extension base='xs:NMTOKENS' >
2097         <xs:attributeGroup ref='tns:commonAttributes' />
2098       </xs:extension>
2099     </xs:simpleContent>
2100   </xs:complexType>
2101 
2102   <xs:element name='ID' type='tns:ID' />
2103   <xs:complexType name='ID' >
2104     <xs:simpleContent>
2105       <xs:extension base='xs:ID' >
2106         <xs:attributeGroup ref='tns:commonAttributes' />
2107       </xs:extension>
2108     </xs:simpleContent>
2109   </xs:complexType>
2110 
2111   <xs:element name='IDREF' type='tns:IDREF' />
2112   <xs:complexType name='IDREF' >
2113     <xs:simpleContent>
2114       <xs:extension base='xs:IDREF' >
2115         <xs:attributeGroup ref='tns:commonAttributes' />
2116       </xs:extension>
2117     </xs:simpleContent>
2118   </xs:complexType>
2119 
2120   <xs:element name='ENTITY' type='tns:ENTITY' />
2121   <xs:complexType name='ENTITY' >
2122     <xs:simpleContent>
2123       <xs:extension base='xs:ENTITY' >
2124         <xs:attributeGroup ref='tns:commonAttributes' />
2125       </xs:extension>
2126     </xs:simpleContent>
2127   </xs:complexType>
2128 
2129   <xs:element name='IDREFS' type='tns:IDREFS' />
2130   <xs:complexType name='IDREFS' >
2131     <xs:simpleContent>
2132       <xs:extension base='xs:IDREFS' >
2133         <xs:attributeGroup ref='tns:commonAttributes' />
2134       </xs:extension>
2135     </xs:simpleContent>
2136   </xs:complexType>
2137 
2138   <xs:element name='ENTITIES' type='tns:ENTITIES' />
2139   <xs:complexType name='ENTITIES' >
2140     <xs:simpleContent>
2141       <xs:extension base='xs:ENTITIES' >
2142         <xs:attributeGroup ref='tns:commonAttributes' />
2143       </xs:extension>
2144     </xs:simpleContent>
2145   </xs:complexType>
2146 
2147   <xs:element name='decimal' type='tns:decimal' />
2148   <xs:complexType name='decimal' >
2149     <xs:simpleContent>
2150       <xs:extension base='xs:decimal' >
2151         <xs:attributeGroup ref='tns:commonAttributes' />
2152       </xs:extension>
2153     </xs:simpleContent>
2154   </xs:complexType>
2155 
2156   <xs:element name='integer' type='tns:integer' />
2157   <xs:complexType name='integer' >
2158     <xs:simpleContent>
2159       <xs:extension base='xs:integer' >
2160         <xs:attributeGroup ref='tns:commonAttributes' />
2161       </xs:extension>
2162     </xs:simpleContent>
2163   </xs:complexType>
2164 
2165   <xs:element name='nonPositiveInteger' type='tns:nonPositiveInteger' />
2166   <xs:complexType name='nonPositiveInteger' >
2167     <xs:simpleContent>
2168       <xs:extension base='xs:nonPositiveInteger' >
2169         <xs:attributeGroup ref='tns:commonAttributes' />
2170       </xs:extension>
2171     </xs:simpleContent>
2172   </xs:complexType>
2173 
2174   <xs:element name='negativeInteger' type='tns:negativeInteger' />
2175   <xs:complexType name='negativeInteger' >
2176     <xs:simpleContent>
2177       <xs:extension base='xs:negativeInteger' >
2178         <xs:attributeGroup ref='tns:commonAttributes' />
2179       </xs:extension>
2180     </xs:simpleContent>
2181   </xs:complexType>
2182 
2183   <xs:element name='long' type='tns:long' />
2184   <xs:complexType name='long' >
2185     <xs:simpleContent>
2186       <xs:extension base='xs:long' >
2187         <xs:attributeGroup ref='tns:commonAttributes' />
2188       </xs:extension>
2189     </xs:simpleContent>
2190   </xs:complexType>
2191 
2192   <xs:element name='int' type='tns:int' />
2193   <xs:complexType name='int' >
2194     <xs:simpleContent>
2195       <xs:extension base='xs:int' >
2196         <xs:attributeGroup ref='tns:commonAttributes' />
2197       </xs:extension>
2198     </xs:simpleContent>
2199   </xs:complexType>
2200 
2201   <xs:element name='short' type='tns:short' />
2202   <xs:complexType name='short' >
2203     <xs:simpleContent>
2204       <xs:extension base='xs:short' >
2205         <xs:attributeGroup ref='tns:commonAttributes' />
2206       </xs:extension>
2207     </xs:simpleContent>
2208   </xs:complexType>
2209 
2210   <xs:element name='byte' type='tns:byte' />
2211   <xs:complexType name='byte' >
2212     <xs:simpleContent>
2213       <xs:extension base='xs:byte' >
2214         <xs:attributeGroup ref='tns:commonAttributes' />
2215       </xs:extension>
2216     </xs:simpleContent>
2217   </xs:complexType>
2218 
2219   <xs:element name='nonNegativeInteger' type='tns:nonNegativeInteger' />
2220   <xs:complexType name='nonNegativeInteger' >
2221     <xs:simpleContent>
2222       <xs:extension base='xs:nonNegativeInteger' >
2223         <xs:attributeGroup ref='tns:commonAttributes' />
2224       </xs:extension>
2225     </xs:simpleContent>
2226   </xs:complexType>
2227 
2228   <xs:element name='unsignedLong' type='tns:unsignedLong' />
2229   <xs:complexType name='unsignedLong' >
2230     <xs:simpleContent>
2231       <xs:extension base='xs:unsignedLong' >
2232         <xs:attributeGroup ref='tns:commonAttributes' />
2233       </xs:extension>
2234     </xs:simpleContent>
2235   </xs:complexType>
2236 
2237   <xs:element name='unsignedInt' type='tns:unsignedInt' />
2238   <xs:complexType name='unsignedInt' >
2239     <xs:simpleContent>
2240       <xs:extension base='xs:unsignedInt' >
2241         <xs:attributeGroup ref='tns:commonAttributes' />
2242       </xs:extension>
2243     </xs:simpleContent>
2244   </xs:complexType>
2245 
2246   <xs:element name='unsignedShort' type='tns:unsignedShort' />
2247   <xs:complexType name='unsignedShort' >
2248     <xs:simpleContent>
2249       <xs:extension base='xs:unsignedShort' >
2250         <xs:attributeGroup ref='tns:commonAttributes' />
2251       </xs:extension>
2252     </xs:simpleContent>
2253   </xs:complexType>
2254 
2255   <xs:element name='unsignedByte' type='tns:unsignedByte' />
2256   <xs:complexType name='unsignedByte' >
2257     <xs:simpleContent>
2258       <xs:extension base='xs:unsignedByte' >
2259         <xs:attributeGroup ref='tns:commonAttributes' />
2260       </xs:extension>
2261     </xs:simpleContent>
2262   </xs:complexType>
2263 
2264   <xs:element name='positiveInteger' type='tns:positiveInteger' />
2265   <xs:complexType name='positiveInteger' >
2266     <xs:simpleContent>
2267       <xs:extension base='xs:positiveInteger' >
2268         <xs:attributeGroup ref='tns:commonAttributes' />
2269       </xs:extension>
2270     </xs:simpleContent>
2271   </xs:complexType>
2272 
2273   <xs:element name='anyType' />
2274 </xs:schema>";
2275 
2276         const string fakeXsd = @"<?xml version='1.0' encoding='UTF-8' ?>
2277 <xsd:schema targetNamespace=""http://www.w3.org/2001/XMLSchema"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
2278     <xsd:element name=""schema"">
2279     <xsd:complexType />
2280     </xsd:element>
2281 </xsd:schema>";
2282 
2283         const string fakeXmlSchema = @"<xs:schema targetNamespace='http://www.w3.org/XML/1998/namespace' xmlns:xs='http://www.w3.org/2001/XMLSchema' xml:lang='en'>
2284  <xs:attribute name='lang' type='xs:language'/>
2285  <xs:attribute name='space'>
2286   <xs:simpleType>
2287    <xs:restriction base='xs:NCName'>
2288     <xs:enumeration value='default'/>
2289     <xs:enumeration value='preserve'/>
2290    </xs:restriction>
2291   </xs:simpleType>
2292  </xs:attribute>
2293  <xs:attribute name='base' type='xs:anyURI'/>
2294  <xs:attribute name='id' type='xs:ID' />
2295  <xs:attributeGroup name='specialAttrs'>
2296   <xs:attribute ref='xml:base'/>
2297   <xs:attribute ref='xml:lang'/>
2298   <xs:attribute ref='xml:space'/>
2299  </xs:attributeGroup>
2300 </xs:schema>";
2301 
2302 
2303         const string fakeSoapEncoding = @"<?xml version='1.0' encoding='UTF-8' ?>
2304 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
2305            xmlns:tns='http://schemas.xmlsoap.org/soap/encoding/'
2306            targetNamespace='http://schemas.xmlsoap.org/soap/encoding/' >
2307 
2308   <xs:attributeGroup name='commonAttributes' >
2309     <xs:attribute name='id' type='xs:ID' />
2310     <xs:attribute name='href' type='xs:anyURI' />
2311     <xs:anyAttribute namespace='##other' processContents='lax' />
2312   </xs:attributeGroup>
2313 
2314   <xs:simpleType name='arrayCoordinate' >
2315     <xs:restriction base='xs:string' />
2316   </xs:simpleType>
2317 
2318   <xs:attribute name='arrayType' type='xs:string' />
2319   <xs:attribute name='offset' type='tns:arrayCoordinate' />
2320 
2321   <xs:attributeGroup name='arrayAttributes' >
2322     <xs:attribute ref='tns:arrayType' />
2323     <xs:attribute ref='tns:offset' />
2324   </xs:attributeGroup>
2325 
2326   <xs:group name='Array' >
2327     <xs:sequence>
2328       <xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
2329     </xs:sequence>
2330   </xs:group>
2331 
2332   <xs:element name='Array' type='tns:Array' />
2333   <xs:complexType name='Array' >
2334     <xs:group ref='tns:Array' minOccurs='0' />
2335     <xs:attributeGroup ref='tns:arrayAttributes' />
2336     <xs:attributeGroup ref='tns:commonAttributes' />
2337   </xs:complexType>
2338 </xs:schema>";
2339 
2340 
2341     }
2342 }
2343