fa4dfa440fd7c5f8234fff58589ec6e2f96fcd97
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / XmlSchemaImporter.cs
1 // \r
2 // System.Xml.Serialization.XmlSchemaImporter\r
3 //\r
4 // Author:\r
5 //   Tim Coleman (tim@timcoleman.com)\r
6 //   Lluis Sanchez Gual (lluis@ximian.com)\r
7 //\r
8 // Copyright (C) Tim Coleman, 2002\r
9 //\r
10 \r
11 using System.Xml;\r
12 using System.Xml.Schema;\r
13 using System.Collections;\r
14 \r
15 namespace System.Xml.Serialization {\r
16         public class XmlSchemaImporter {\r
17 \r
18                 #region Fields\r
19 \r
20                 XmlSchemas schemas;\r
21                 CodeIdentifiers typeIdentifiers;\r
22                 CodeIdentifiers elemIdentifiers = new CodeIdentifiers ();\r
23                 Hashtable mappedTypes = new Hashtable ();\r
24                 Hashtable dataMappedTypes = new Hashtable ();\r
25                 Queue pendingMaps = new Queue ();\r
26                 Hashtable sharedAnonymousTypes = new Hashtable ();\r
27                 bool encodedFormat = false;\r
28                 XmlReflectionImporter auxXmlRefImporter;\r
29                 SoapReflectionImporter auxSoapRefImporter;\r
30                 Hashtable forcedBaseTypes;\r
31 \r
32                 static readonly XmlQualifiedName anyType = new XmlQualifiedName ("anyType",XmlSchema.Namespace);\r
33                 static readonly XmlQualifiedName arrayType = new XmlQualifiedName ("Array",XmlSerializer.EncodingNamespace);\r
34                 static readonly XmlQualifiedName arrayTypeRefName = new XmlQualifiedName ("arrayType",XmlSerializer.EncodingNamespace);\r
35                 \r
36                 const string XmlNamespace = "http://www.w3.org/XML/1998/namespace";\r
37                 \r
38                 XmlSchemaElement anyElement = null;\r
39 \r
40                 class MapFixup\r
41                 {\r
42                         public XmlTypeMapping Map;\r
43                         public XmlSchemaComplexType SchemaType;\r
44                         public XmlQualifiedName TypeName;\r
45                 }\r
46 \r
47                 #endregion\r
48 \r
49                 #region Constructors\r
50 \r
51                 public XmlSchemaImporter (XmlSchemas schemas)\r
52                 {\r
53                         this.schemas = schemas;\r
54                         typeIdentifiers = new CodeIdentifiers ();\r
55                 }\r
56 \r
57                 public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers)\r
58                         : this (schemas)\r
59                 {\r
60                         this.typeIdentifiers = typeIdentifiers;\r
61                 }\r
62                 \r
63                 internal bool UseEncodedFormat\r
64                 {\r
65                         get { return encodedFormat; }\r
66                         set { encodedFormat = value; }\r
67                 }\r
68 \r
69                 #endregion // Constructors\r
70 \r
71                 #region Methods\r
72 \r
73                 public XmlMembersMapping ImportAnyType (XmlQualifiedName typeName, string elementName)\r
74                 {\r
75                         XmlTypeMapMemberAnyElement mapMem = new XmlTypeMapMemberAnyElement ();\r
76                         mapMem.Name = typeName.Name;\r
77                         mapMem.TypeData = TypeTranslator.GetTypeData(typeof(XmlNode));\r
78                         mapMem.ElementInfo.Add (CreateElementInfo (typeName.Namespace, mapMem, typeName.Name, mapMem.TypeData, true));\r
79                         \r
80                         XmlMemberMapping[] mm = new XmlMemberMapping [1];\r
81                         mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);\r
82                         return new XmlMembersMapping (mm);\r
83                 }\r
84 \r
85                 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType)\r
86                 {\r
87                         return ImportDerivedTypeMapping (name, baseType, true);\r
88                 }\r
89                 \r
90                 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)\r
91                 {\r
92                         XmlQualifiedName qname;\r
93                         XmlSchemaType stype;\r
94                         \r
95                         if (encodedFormat)\r
96                         {\r
97                                 qname = name;\r
98                                 stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;\r
99                                 if (stype == null) throw new InvalidOperationException ("Schema type '" + name + "' not found or not valid");\r
100                         }\r
101                         else\r
102                         {\r
103                                 if (!LocateElement (name, out qname, out stype)) return null;\r
104                         }\r
105                         \r
106                         XmlTypeMapping map = GetRegisteredTypeMapping (qname);\r
107                         if (map != null) return map;\r
108                         \r
109                         RegisterForcedBaseType (qname, baseType);\r
110                         \r
111                         map = CreateTypeMapping (qname, SchemaTypes.Class, name);\r
112                         map.Documentation = GetDocumentation (stype);\r
113                         RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);\r
114                         \r
115                         BuildPendingMaps ();\r
116                         return map;\r
117                 }\r
118 \r
119                 [MonoTODO]\r
120                 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, bool baseTypeCanBeIndirect)\r
121                 {\r
122                         throw new NotImplementedException ();\r
123                 }\r
124 \r
125                 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName name)\r
126                 {\r
127                         XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));\r
128                         if (elem == null) throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");\r
129 \r
130                         XmlSchemaComplexType stype;\r
131                         if (elem.SchemaType != null)\r
132                         {\r
133                                 stype = elem.SchemaType as XmlSchemaComplexType;\r
134                         }\r
135                         else\r
136                         {\r
137                                 if (elem.SchemaTypeName.IsEmpty) return null;\r
138                                 if (elem.SchemaTypeName.Namespace == XmlSchema.Namespace) return null;\r
139                                 object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));\r
140                                 if (type == null) throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");\r
141                                 stype = type as XmlSchemaComplexType;\r
142                         }\r
143                         \r
144                         if (stype == null) \r
145                                 throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");\r
146                         \r
147                         XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, name);                       \r
148                         return new XmlMembersMapping (name.Name, name.Namespace, mapping);\r
149                 }\r
150                 \r
151                 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names)\r
152                 {\r
153                         XmlMemberMapping[] mapping = new XmlMemberMapping [names.Length];\r
154                         for (int n=0; n<names.Length; n++)\r
155                         {\r
156                                 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (names[n], typeof (XmlSchemaElement));\r
157                                 if (elem == null) throw new InvalidOperationException ("Schema element '" + names[n] + "' not found");\r
158                                 \r
159                                 XmlQualifiedName typeQName = new XmlQualifiedName ("Message", names[n].Namespace);\r
160                                 TypeData td = GetElementTypeData (typeQName, elem);\r
161                                 \r
162                                 mapping[n] = ImportMemberMapping (elem.Name, typeQName.Namespace, td);\r
163                         }\r
164                         BuildPendingMaps ();\r
165                         return new XmlMembersMapping (mapping);\r
166                 }\r
167                 \r
168                 public XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement)\r
169                 {\r
170                         XmlMemberMapping[] mapping = new XmlMemberMapping [members.Length];\r
171                         for (int n=0; n<members.Length; n++)\r
172                         {\r
173                                 TypeData td = GetTypeData (members[n].MemberType, null);\r
174                                 mapping[n] = ImportMemberMapping (members[n].MemberName, members[n].MemberType.Namespace, td);\r
175                         }\r
176                         BuildPendingMaps ();\r
177                         return new XmlMembersMapping (name, ns, hasWrapperElement, false, mapping);\r
178                 }\r
179                 \r
180                 public XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember member)\r
181                 {\r
182                         XmlSchemaComplexType stype = schemas.Find (member.MemberType, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;\r
183                         if (stype == null) throw new InvalidOperationException ("Schema type '" + member.MemberType + "' not found or not valid");\r
184 \r
185                         XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, member.MemberType);                  \r
186                         return new XmlMembersMapping (name, ns, mapping);\r
187                 }\r
188                 \r
189                 public XmlMemberMapping[] ImportMembersMappingComposite (XmlSchemaComplexType stype, XmlQualifiedName refer)\r
190                 {\r
191                         if (stype.Particle == null) \r
192                                 return new XmlMemberMapping [0];\r
193 \r
194                         ClassMap cmap = new ClassMap ();\r
195                         \r
196                         XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;\r
197                         if (seq == null) throw new InvalidOperationException ("Schema element '" + refer + "' cannot be imported as XmlMembersMapping");\r
198 \r
199                         CodeIdentifiers classIds = new CodeIdentifiers ();\r
200                         ImportParticleComplexContent (refer, cmap, seq, classIds, false);\r
201 \r
202                         BuildPendingMaps ();\r
203 \r
204                         int n = 0;\r
205                         XmlMemberMapping[] mapping = new XmlMemberMapping [cmap.AllMembers.Count];\r
206                         foreach (XmlTypeMapMember mapMem in cmap.AllMembers)\r
207                                 mapping[n++] = new XmlMemberMapping (mapMem.Name, refer.Namespace, mapMem, encodedFormat);\r
208                                 \r
209                         return mapping;\r
210                 }\r
211                 \r
212                 XmlMemberMapping ImportMemberMapping (string name, string ns, TypeData type)\r
213                 {\r
214                         XmlTypeMapMemberElement mapMem = new XmlTypeMapMemberElement ();\r
215                         mapMem.Name = name;\r
216                         mapMem.TypeData = type;\r
217                         mapMem.ElementInfo.Add (CreateElementInfo (ns, mapMem, name, type, true));\r
218                         return new XmlMemberMapping (name, ns, mapMem, encodedFormat);\r
219                 }\r
220                 \r
221                 [MonoTODO]\r
222                 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names, Type baseType, bool baseTypeCanBeIndirect)\r
223                 {\r
224                         throw new NotImplementedException ();\r
225                 }\r
226 \r
227                 public XmlTypeMapping ImportTypeMapping (XmlQualifiedName name)\r
228                 {\r
229                         XmlQualifiedName qname;\r
230                         XmlSchemaType stype;\r
231                         if (!LocateElement (name, out qname, out stype)) return null;\r
232                         \r
233                         XmlTypeMapping map = GetRegisteredTypeMapping (qname);\r
234                         if (map != null) return map;\r
235                         \r
236                         map = CreateTypeMapping (qname, SchemaTypes.Class, name);\r
237                         map.Documentation = GetDocumentation (stype);\r
238                         RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);\r
239                         \r
240                         BuildPendingMaps ();\r
241                         return map;\r
242                 }\r
243 \r
244                 bool LocateElement (XmlQualifiedName name, out XmlQualifiedName qname, out XmlSchemaType stype)\r
245                 {\r
246                         qname = null;\r
247                         stype = null;\r
248                         \r
249                         XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));\r
250                         if (elem == null) return false;\r
251 \r
252                         // The root element must be an element with complex type\r
253 \r
254                         if (elem.SchemaType != null)\r
255                         {\r
256                                 stype = elem.SchemaType;\r
257                                 qname = name;\r
258                         }\r
259                         else\r
260                         {\r
261                                 if (elem.SchemaTypeName.IsEmpty) return false;\r
262                                 if (elem.SchemaTypeName.Namespace == XmlSchema.Namespace) return false;\r
263                                 object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));\r
264                                 if (type == null) type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaSimpleType));\r
265                                 if (type == null) throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");\r
266                                 stype = (XmlSchemaType) type;\r
267                                 qname = stype.QualifiedName;\r
268                         }\r
269 \r
270                         if (stype is XmlSchemaSimpleType) return false;\r
271                         return true;\r
272                 }\r
273 \r
274                 XmlTypeMapping ImportType (XmlQualifiedName name, XmlQualifiedName root)\r
275                 {\r
276                         XmlTypeMapping map = GetRegisteredTypeMapping (name);\r
277                         if (map != null) return map;\r
278 \r
279                         XmlSchemaType type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaComplexType));\r
280                         if (type == null) type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaSimpleType));\r
281                         \r
282                         if (type == null) \r
283                         {\r
284                                 if (name.Namespace == XmlSerializer.EncodingNamespace)\r
285                                         throw new InvalidOperationException ("Referenced type '" + name + "' valid only for encoded SOAP");\r
286                                 else\r
287                                         throw new InvalidOperationException ("Referenced type '" + name + "' not found");\r
288                         }\r
289 \r
290                         return ImportType (name, type, root);\r
291                 }\r
292 \r
293                 XmlTypeMapping ImportType (XmlQualifiedName name, XmlSchemaType stype, XmlQualifiedName root)\r
294                 {\r
295                         XmlTypeMapping map = GetRegisteredTypeMapping (name);\r
296                         if (map != null) return map;\r
297 \r
298                         if (stype is XmlSchemaComplexType)\r
299                                 return ImportClassComplexType (name, (XmlSchemaComplexType) stype, root);\r
300                         else if (stype is XmlSchemaSimpleType)\r
301                                 return ImportClassSimpleType (name, (XmlSchemaSimpleType) stype, root);\r
302 \r
303                         throw new NotSupportedException ("Schema type not supported: " + stype.GetType ());\r
304                 }\r
305 \r
306                 XmlTypeMapping ImportClassComplexType (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)\r
307                 {\r
308                         XmlTypeMapping map;\r
309 \r
310                         // The need for fixups: If the complex type is an array, then to get the type of the\r
311                         // array we need first to get the type of the items of the array.\r
312                         // But if one of the item types or its children has a referece to this type array,\r
313                         // then we enter in an infinite loop. This does not happen with class types because\r
314                         // the class map is registered before parsing the children. We can't do the same\r
315                         // with the array type because to register the array map we need the type of the array.\r
316 \r
317                         if (CanBeArray (typeQName, stype))\r
318                         {\r
319                                 TypeData typeData;\r
320                                 ListMap listMap = BuildArrayMap (typeQName, stype, out typeData);\r
321                                 if (listMap != null)\r
322                                 {\r
323                                         map = CreateArrayTypeMapping (typeQName, typeData);\r
324                                         map.ObjectMap = listMap;\r
325                                         return map;\r
326                                 }\r
327 \r
328                                 // After all, it is not an array. Create a class map then.\r
329                         }\r
330                         else if (CanBeAnyElement (stype))\r
331                         {\r
332                                 return GetTypeMapping (TypeTranslator.GetTypeData(typeof(XmlElement)));\r
333                         }\r
334                         else if (CanBeIXmlSerializable (stype))\r
335                         {\r
336                                 return GetTypeMapping (TypeTranslator.GetTypeData(typeof(object)));\r
337                         }\r
338 \r
339                         // Register the map right now but do not build it,\r
340                         // This will avoid loops.\r
341 \r
342                         map = CreateTypeMapping (typeQName, SchemaTypes.Class, root);\r
343                         map.Documentation = GetDocumentation (stype);\r
344                         RegisterMapFixup (map, typeQName, stype);\r
345                         return map;\r
346                 }\r
347 \r
348                 void RegisterMapFixup (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)\r
349                 {\r
350                         MapFixup fixup = new MapFixup ();\r
351                         fixup.Map = map;\r
352                         fixup.SchemaType = stype;\r
353                         fixup.TypeName = typeQName;\r
354                         pendingMaps.Enqueue (fixup);\r
355                 }\r
356 \r
357                 void BuildPendingMaps ()\r
358                 {\r
359                         while (pendingMaps.Count > 0) {\r
360                                 MapFixup fixup  = (MapFixup) pendingMaps.Dequeue ();\r
361                                 if (fixup.Map.ObjectMap == null) {\r
362                                         BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);\r
363                                         if (fixup.Map.ObjectMap == null) pendingMaps.Enqueue (fixup);\r
364                                 }\r
365                         }\r
366                 }\r
367 \r
368                 void BuildPendingMap (XmlTypeMapping map)\r
369                 {\r
370                         if (map.ObjectMap != null) return;\r
371 \r
372                         foreach (MapFixup fixup in pendingMaps)\r
373                         {\r
374                                 if (fixup.Map == map) {\r
375                                         BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);\r
376                                         return;\r
377                                 }\r
378                         }\r
379                         throw new InvalidOperationException ("Can't complete map of type " + map.XmlType + " : " + map.Namespace);\r
380                 }\r
381 \r
382                 void BuildClassMap (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)\r
383                 {\r
384                         CodeIdentifiers classIds = new CodeIdentifiers();\r
385                         classIds.AddReserved (map.TypeData.TypeName);\r
386 \r
387                         ClassMap cmap = new ClassMap ();\r
388                         map.ObjectMap = cmap;\r
389                         bool isMixed = stype.IsMixed;\r
390 \r
391                         if (stype.Particle != null)\r
392                         {\r
393                                 if  (HasForcedBaseType (typeQName))\r
394                                         ImportForcedDerivedType (map, typeQName, ref isMixed);\r
395                                         \r
396                                 ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, isMixed);\r
397                         }\r
398                         else\r
399                         {\r
400                                 if (stype.ContentModel is XmlSchemaSimpleContent) {\r
401                                         ImportSimpleContent (typeQName, map, (XmlSchemaSimpleContent)stype.ContentModel, classIds, isMixed);\r
402                                 }\r
403                                 else if (stype.ContentModel is XmlSchemaComplexContent) {\r
404                                         ImportComplexContent (typeQName, map, (XmlSchemaComplexContent)stype.ContentModel, classIds, isMixed);\r
405                                 }\r
406                         }\r
407 \r
408                         ImportAttributes (typeQName, cmap, stype.Attributes, stype.AnyAttribute, classIds);\r
409                         ImportExtensionTypes (typeQName);\r
410                 }\r
411                 \r
412                 void ImportAttributes (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat, CodeIdentifiers classIds)\r
413                 {\r
414                         if (anyat != null)\r
415                         {\r
416                         XmlTypeMapMemberAnyAttribute member = new XmlTypeMapMemberAnyAttribute ();\r
417                                 member.Name = classIds.AddUnique ("AnyAttribute", member);\r
418                                 member.TypeData = TypeTranslator.GetTypeData (typeof(XmlAttribute[]));\r
419                                 cmap.AddMember (member);\r
420                         }\r
421                         \r
422                         foreach (XmlSchemaObject at in atts)\r
423                         {\r
424                                 if (at is XmlSchemaAttribute)\r
425                                 {\r
426                                         string ns;\r
427                                         XmlSchemaAttribute attr = (XmlSchemaAttribute)at;\r
428                                         XmlSchemaAttribute refAttr = GetRefAttribute (typeQName, attr, out ns);\r
429                                         XmlTypeMapMemberAttribute member = new XmlTypeMapMemberAttribute ();\r
430                                         member.Name = classIds.AddUnique (CodeIdentifier.MakeValid (refAttr.Name), member);\r
431                                         member.Documentation = GetDocumentation (attr);\r
432                                         member.AttributeName = refAttr.Name;\r
433                                         member.Namespace = ns;\r
434                                         member.Form = refAttr.Form;\r
435                                         member.TypeData = GetAttributeTypeData (typeQName, attr);\r
436                                         \r
437                                         if (refAttr.DefaultValue != null) \r
438                                                 member.DefaultValue = XmlCustomFormatter.FromXmlString (member.TypeData, refAttr.DefaultValue);\r
439                                         else if (member.TypeData.IsValueType)\r
440                                                 member.IsOptionalValueType = true;\r
441                                                 \r
442                                         if (member.TypeData.IsComplexType)\r
443                                                 member.MappedType = GetTypeMapping (member.TypeData);\r
444                                         cmap.AddMember (member);\r
445                                 }\r
446                                 else if (at is XmlSchemaAttributeGroupRef)\r
447                                 {\r
448                                         XmlSchemaAttributeGroupRef gref = (XmlSchemaAttributeGroupRef)at;\r
449                                         XmlSchemaAttributeGroup grp = (XmlSchemaAttributeGroup) schemas.Find (gref.RefName, typeof(XmlSchemaAttributeGroup));\r
450                                         ImportAttributes (typeQName, cmap, grp.Attributes, grp.AnyAttribute, classIds);\r
451                                 }\r
452                         }\r
453                 }\r
454 \r
455                 ListMap BuildArrayMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, out TypeData arrayTypeData)\r
456                 {\r
457                         if (encodedFormat)\r
458                         {\r
459                                 XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;\r
460                                 XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;\r
461                                 XmlSchemaAttribute arrayTypeAt = FindArrayAttribute (rest.Attributes);\r
462                                 \r
463                                 if (arrayTypeAt != null)\r
464                                 {\r
465                                         XmlAttribute[] uatts = arrayTypeAt.UnhandledAttributes;\r
466                                         if (uatts == null || uatts.Length == 0) throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);\r
467                                         \r
468                                         XmlAttribute xat = null;\r
469                                         foreach (XmlAttribute at in uatts)\r
470                                                 if (at.LocalName == "arrayType" && at.NamespaceURI == XmlSerializer.WsdlNamespace)\r
471                                                         { xat = at; break; }\r
472                                         \r
473                                         if (xat == null) \r
474                                                 throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);\r
475         \r
476                                         string name, ns, dims;\r
477                                         TypeTranslator.ParseArrayType (xat.Value, out name, out ns, out dims);\r
478                                         return BuildEncodedArrayMap (name + dims, ns, out arrayTypeData);\r
479                                 }\r
480                                 else\r
481                                 {\r
482                                         XmlSchemaElement elem = null;\r
483                                         XmlSchemaSequence seq = rest.Particle as XmlSchemaSequence;\r
484                                         if (seq != null && seq.Items.Count == 1) \r
485                                                 elem = seq.Items[0] as XmlSchemaElement;\r
486                                         else {\r
487                                                 XmlSchemaAll all = rest.Particle as XmlSchemaAll;\r
488                                                 if (all != null && all.Items.Count == 1)\r
489                                                         elem = all.Items[0] as XmlSchemaElement;\r
490                                         }\r
491                                         if (elem == null)\r
492                                                 throw new InvalidOperationException ("Unknown array format");\r
493                                                 \r
494                                         return BuildEncodedArrayMap (elem.SchemaTypeName.Name + "[]", elem.SchemaTypeName.Namespace, out arrayTypeData);\r
495                                 }\r
496                         }\r
497                         else\r
498                         {\r
499                                 ClassMap cmap = new ClassMap ();\r
500                                 CodeIdentifiers classIds = new CodeIdentifiers();\r
501                                 ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, false);\r
502         \r
503                                 XmlTypeMapMemberFlatList list = (cmap.AllMembers.Count == 1) ? cmap.AllMembers[0] as XmlTypeMapMemberFlatList : null;\r
504                                 if (list != null && list.ChoiceMember == null)\r
505                                 {\r
506                                         arrayTypeData = list.TypeData;\r
507                                         return list.ListMap;\r
508                                 }\r
509                                 else\r
510                                 {\r
511                                         arrayTypeData = null;\r
512                                         return null;\r
513                                 }\r
514                         }\r
515                 }\r
516                 \r
517                 ListMap BuildEncodedArrayMap (string type, string ns, out TypeData arrayTypeData)\r
518                 {\r
519                         ListMap map = new ListMap ();\r
520                         \r
521                         int i = type.LastIndexOf ("[");\r
522                         if (i == -1) throw new InvalidOperationException ("Invalid arrayType value: " + type);\r
523                         if (type.IndexOf (",",i) != -1) throw new InvalidOperationException ("Multidimensional arrays are not supported");\r
524                         \r
525                         string itemType = type.Substring (0,i);\r
526                         \r
527                         TypeData itemTypeData;\r
528                         if (itemType.IndexOf ("[") != -1) \r
529                         {\r
530                                 ListMap innerListMap = BuildEncodedArrayMap (itemType, ns, out itemTypeData);\r
531                                 \r
532                                 int dims = itemType.Split ('[').Length - 1;\r
533                                 string name = TypeTranslator.GetArrayName (type, dims);\r
534                                 XmlQualifiedName qname = new XmlQualifiedName (name, ns);\r
535                                 XmlTypeMapping tmap = CreateArrayTypeMapping (qname, itemTypeData);\r
536                                 tmap.ObjectMap = innerListMap;\r
537                         }\r
538                         else\r
539                         {\r
540                                 itemTypeData = GetTypeData (new XmlQualifiedName (itemType, ns), null);\r
541                         }\r
542                         \r
543                         arrayTypeData = itemTypeData.ListTypeData;\r
544                         \r
545                         map.ItemInfo = new XmlTypeMapElementInfoList();\r
546                         map.ItemInfo.Add (CreateElementInfo ("", null, "Item", itemTypeData, true));\r
547                         return map;\r
548                 }\r
549                 \r
550                 XmlSchemaAttribute FindArrayAttribute (XmlSchemaObjectCollection atts)\r
551                 {\r
552                         foreach (object ob in atts)\r
553                         {\r
554                                 XmlSchemaAttribute att = ob as XmlSchemaAttribute;\r
555                                 if (att != null && att.RefName == arrayTypeRefName) return att;\r
556                                 \r
557                                 XmlSchemaAttributeGroupRef gref = ob as XmlSchemaAttributeGroupRef;\r
558                                 if (gref != null)\r
559                                 {\r
560                                         XmlSchemaAttributeGroup grp = (XmlSchemaAttributeGroup) schemas.Find (gref.RefName, typeof(XmlSchemaAttributeGroup));\r
561                                         att = FindArrayAttribute (grp.Attributes);\r
562                                         if (att != null) return att;\r
563                                 }\r
564                         }\r
565                         return null;\r
566                 }\r
567 \r
568                 void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed)\r
569                 {\r
570                         ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed);\r
571                         if (isMixed)\r
572                         {\r
573                                 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();\r
574                                 member.Name = classIds.AddUnique ("Text", member);\r
575                                 member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));\r
576                                 member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));\r
577                                 member.IsXmlTextCollector = true;\r
578                                 member.ListMap = new ListMap ();\r
579                                 member.ListMap.ItemInfo = member.ElementInfo;\r
580                                 cmap.AddMember (member);\r
581                         }\r
582                 }\r
583                 \r
584                 void ImportParticleContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)\r
585                 {\r
586                         if (particle is XmlSchemaGroupRef)\r
587                                 particle = GetRefGroupParticle ((XmlSchemaGroupRef)particle);\r
588 \r
589                         if (particle.MaxOccurs > 1) multiValue = true;\r
590                         \r
591                         if (particle is XmlSchemaSequence) {\r
592                                 ImportSequenceContent (typeQName, cmap, ((XmlSchemaSequence)particle).Items, classIds, multiValue, ref isMixed);\r
593                         }\r
594                         else if (particle is XmlSchemaChoice) {\r
595                                 if (((XmlSchemaChoice)particle).Items.Count == 1)\r
596                                         ImportSequenceContent (typeQName, cmap, ((XmlSchemaChoice)particle).Items, classIds, multiValue, ref isMixed);\r
597                                 else\r
598                                         ImportChoiceContent (typeQName, cmap, (XmlSchemaChoice)particle, classIds, multiValue);\r
599                         }\r
600                         else if (particle is XmlSchemaAll) {\r
601                                 ImportSequenceContent (typeQName, cmap, ((XmlSchemaAll)particle).Items, classIds, multiValue, ref isMixed);\r
602                         }\r
603                 }\r
604 \r
605                 void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)\r
606                 {\r
607                         foreach (XmlSchemaObject item in items)\r
608                         {\r
609                                 if (item is XmlSchemaElement)\r
610                                 {\r
611                                         string ns;\r
612                                         XmlSchemaElement elem = (XmlSchemaElement) item;\r
613                                         TypeData typeData = GetElementTypeData (typeQName, elem);\r
614                                         XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);\r
615 \r
616                                         if (elem.MaxOccurs == 1 && !multiValue)\r
617                                         {\r
618                                                 XmlTypeMapMemberElement member = null;\r
619                                                 if (typeData.SchemaType != SchemaTypes.Array)\r
620                                                 {\r
621                                                         member = new XmlTypeMapMemberElement ();\r
622                                                         if (refElem.DefaultValue != null) member.DefaultValue = XmlCustomFormatter.FromXmlString (typeData, refElem.DefaultValue);\r
623                                                 }\r
624                                                 else if (GetTypeMapping (typeData).IsSimpleType)\r
625                                                 {\r
626                                                         // It is a simple list (space separated list).\r
627                                                         // Since this is not supported, map as a single item value\r
628                                                         // TODO: improve this\r
629                                                         member = new XmlTypeMapMemberElement ();\r
630                                                         typeData = typeData.ListItemTypeData;\r
631                                                 }\r
632                                                 else\r
633                                                         member = new XmlTypeMapMemberList ();\r
634 \r
635                                                 if (elem.MinOccurs == 0 && typeData.IsValueType)\r
636                                                         member.IsOptionalValueType = true;\r
637 \r
638                                                 member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);\r
639                                                 member.Documentation = GetDocumentation (elem);\r
640                                                 member.TypeData = typeData;\r
641                                                 member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable));\r
642                                                 cmap.AddMember (member);\r
643                                         }\r
644                                         else\r
645                                         {\r
646                                                 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();\r
647                                                 member.ListMap = new ListMap ();\r
648                                                 member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);\r
649                                                 member.Documentation = GetDocumentation (elem);\r
650                                                 member.TypeData = typeData.ListTypeData;\r
651                                                 member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable));\r
652                                                 member.ListMap.ItemInfo = member.ElementInfo;\r
653                                                 cmap.AddMember (member);\r
654                                         }\r
655                                 }\r
656                                 else if (item is XmlSchemaAny)\r
657                                 {\r
658                                         XmlSchemaAny elem = (XmlSchemaAny) item;\r
659                                         XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement ();\r
660                                         member.Name = classIds.AddUnique ("Any", member);\r
661                                         member.Documentation = GetDocumentation (elem);\r
662 \r
663                                         Type ctype;\r
664                                         if (elem.MaxOccurs > 1 || multiValue)\r
665                                                 ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]);\r
666                                         else\r
667                                                 ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement);\r
668 \r
669                                         member.TypeData = TypeTranslator.GetTypeData (ctype);\r
670                                         XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData);\r
671                                         einfo.IsUnnamedAnyElement = true;\r
672                                         member.ElementInfo.Add (einfo);\r
673 \r
674                                         if (isMixed)\r
675                                         {\r
676                                                 einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData);\r
677                                                 member.ElementInfo.Add (einfo);\r
678                                                 member.IsXmlTextCollector = true;\r
679                                                 isMixed = false;        //Allow only one XmlTextAttribute\r
680                                         }\r
681                                         \r
682                                         cmap.AddMember (member);\r
683                                 }\r
684                                 else if (item is XmlSchemaParticle) {\r
685                                         ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed);\r
686                                 }\r
687                         }\r
688                 }\r
689 \r
690 \r
691                 void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue)\r
692                 {\r
693                         XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList ();\r
694                         multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue;\r
695                         if (choices.Count == 0) return;\r
696 \r
697                         if (choice.MaxOccurs > 1) multiValue = true;\r
698 \r
699                         XmlTypeMapMemberElement member;\r
700                         if (multiValue)\r
701                         {\r
702                                 member = new XmlTypeMapMemberFlatList ();\r
703                                 member.Name = classIds.AddUnique ("Items", member);\r
704                                 ListMap listMap = new ListMap ();\r
705                                 listMap.ItemInfo = choices;\r
706                                 ((XmlTypeMapMemberFlatList)member).ListMap = listMap;\r
707                         }\r
708                         else\r
709                         {\r
710                                 member = new XmlTypeMapMemberElement ();\r
711                                 member.Name = classIds.AddUnique ("Item", member);\r
712                         }\r
713                         \r
714                         // If all choices have the same type, use that type for the member.\r
715                         // If not use System.Object.\r
716                         // If there are at least two choices with the same type, use a choice\r
717                         // identifier attribute\r
718 \r
719                         TypeData typeData = null;\r
720                         bool twoEqual = false;\r
721                         bool allEqual = true;\r
722                         Hashtable types = new Hashtable ();\r
723 \r
724                         foreach (XmlTypeMapElementInfo einfo in choices)\r
725                         {\r
726                                 if (types.ContainsKey (einfo.TypeData)) twoEqual = true;\r
727                                 else types.Add (einfo.TypeData, einfo);\r
728 \r
729                                 TypeData choiceType = einfo.TypeData;\r
730                                 if (choiceType.SchemaType == SchemaTypes.Class)\r
731                                 {\r
732                                         // When comparing class types, use the most generic class in the\r
733                                         // inheritance hierarchy\r
734 \r
735 \r
736                                         XmlTypeMapping choiceMap = GetTypeMapping (choiceType);\r
737                                         BuildPendingMap (choiceMap);\r
738                                         while (choiceMap.BaseMap != null) {\r
739                                                 choiceMap = choiceMap.BaseMap;\r
740                                                 BuildPendingMap (choiceMap);\r
741                                                 choiceType = choiceMap.TypeData;\r
742                                         }\r
743                                 }\r
744                                 \r
745                                 if (typeData == null) typeData = choiceType;\r
746                                 else if (typeData != choiceType) allEqual = false;\r
747                         }\r
748 \r
749                         if (!allEqual)\r
750                                 typeData = TypeTranslator.GetTypeData (typeof(object));\r
751 \r
752                         if (twoEqual)\r
753                         {\r
754                                 // Create the choice member\r
755                                 XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();\r
756                                 choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);\r
757                                 member.ChoiceMember = choiceMember.Name;\r
758 \r
759                                 // Create the choice enum\r
760                                 XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);\r
761 \r
762                                 CodeIdentifiers codeIdents = new CodeIdentifiers ();\r
763                                 EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];\r
764                                 for (int n=0; n<choices.Count; n++)\r
765                                 {\r
766                                         XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];\r
767                                         string xmlName = (it.Namespace != null && it.Namespace != "") ? it.Namespace + ":" + it.ElementName : it.ElementName;\r
768                                         string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);\r
769                                         members [n] = new EnumMap.EnumMapMember (xmlName, enumName);\r
770                                 }\r
771                                 enumMap.ObjectMap = new EnumMap (members, false);\r
772 \r
773                                 choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData;\r
774                                 choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false));\r
775                                 cmap.AddMember (choiceMember);\r
776                         }\r
777 \r
778                         if (multiValue)\r
779                                 typeData = typeData.ListTypeData;\r
780 \r
781                         member.ElementInfo = choices;\r
782                         member.Documentation = GetDocumentation (choice);\r
783                         member.TypeData = typeData;\r
784                         cmap.AddMember (member);\r
785                 }\r
786 \r
787                 bool ImportChoices (XmlQualifiedName typeQName, XmlTypeMapMember member, XmlTypeMapElementInfoList choices, XmlSchemaObjectCollection items)\r
788                 {\r
789                         bool multiValue = false;\r
790                         foreach (XmlSchemaObject titem in items)\r
791                         {\r
792                                 XmlSchemaObject item = titem;\r
793                                 if (item is XmlSchemaGroupRef)\r
794                                         item = GetRefGroupParticle ((XmlSchemaGroupRef)item);\r
795 \r
796                                 if (item is XmlSchemaElement)\r
797                                 {\r
798                                         string ns;\r
799                                         XmlSchemaElement elem = (XmlSchemaElement) item;\r
800                                         TypeData typeData = GetElementTypeData (typeQName, elem);\r
801                                         XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);\r
802                                         choices.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable));\r
803                                         if (elem.MaxOccurs > 1) multiValue = true;\r
804                                 }\r
805                                 else if (item is XmlSchemaAny)\r
806                                 {\r
807                                         XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(typeof(XmlElement)));\r
808                                         einfo.IsUnnamedAnyElement = true;\r
809                                         choices.Add (einfo);\r
810                                 }\r
811                                 else if (item is XmlSchemaChoice) {\r
812                                         multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaChoice)item).Items) || multiValue;\r
813                                 }\r
814                                 else if (item is XmlSchemaSequence) {\r
815                                         multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaSequence)item).Items) || multiValue;\r
816                                 }\r
817                         }\r
818                         return multiValue;\r
819                 }\r
820 \r
821                 void ImportSimpleContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaSimpleContent content, CodeIdentifiers classIds, bool isMixed)\r
822                 {\r
823                         ClassMap cmap = (ClassMap)map.ObjectMap;\r
824                         \r
825                         XmlQualifiedName qname = GetContentBaseType (content.Content);\r
826 \r
827                         XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();\r
828                         member.Name = classIds.AddUnique("Value", member);\r
829                         member.TypeData = FindBuiltInType (qname);\r
830                         member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData));\r
831                         member.IsXmlTextCollector = true;\r
832                         cmap.AddMember (member);\r
833 \r
834                         XmlSchemaSimpleContentExtension ext = content.Content as XmlSchemaSimpleContentExtension;\r
835                         if (ext != null)\r
836                                 ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);\r
837                 }\r
838 \r
839                 TypeData FindBuiltInType (XmlQualifiedName qname)\r
840                 {\r
841                         if (qname.Namespace == XmlSchema.Namespace)\r
842                                 return TypeTranslator.GetPrimitiveTypeData (qname.Name);\r
843 \r
844                         XmlSchemaComplexType ct = (XmlSchemaComplexType) schemas.Find (qname, typeof(XmlSchemaComplexType));\r
845                         if (ct != null)\r
846                         {\r
847                                 XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;\r
848                                 if (sc == null) throw new InvalidOperationException ("Invalid schema");\r
849                                 return FindBuiltInType (GetContentBaseType (sc.Content));\r
850                         }\r
851                         \r
852                         XmlSchemaSimpleType st = (XmlSchemaSimpleType) schemas.Find (qname, typeof(XmlSchemaSimpleType));\r
853                         if (st != null)\r
854                                 return FindBuiltInType (qname, st);\r
855 \r
856                         throw new InvalidOperationException ("Definition of type " + qname + " not found");\r
857                 }\r
858 \r
859                 TypeData FindBuiltInType (XmlQualifiedName qname, XmlSchemaSimpleType st)\r
860                 {\r
861                         if (CanBeEnum (st))\r
862                                 return ImportType (qname, null).TypeData;\r
863 \r
864                         if (st.Content is XmlSchemaSimpleTypeRestriction) {\r
865                                 return FindBuiltInType (GetContentBaseType (st.Content));\r
866                         }\r
867                         else if (st.Content is XmlSchemaSimpleTypeList) {\r
868                                 return FindBuiltInType (GetContentBaseType (st.Content)).ListTypeData;\r
869                         }\r
870                         else if (st.Content is XmlSchemaSimpleTypeUnion)\r
871                         {\r
872                                 // Check if all types of the union are equal. If not, then will use anyType.\r
873                                 XmlSchemaSimpleTypeUnion uni = (XmlSchemaSimpleTypeUnion) st.Content;\r
874                                 TypeData utype = null;\r
875 \r
876                                 // Anonymous types are unique\r
877                                 if (uni.BaseTypes.Count != 0 && uni.MemberTypes.Length != 0)\r
878                                         return FindBuiltInType (anyType);\r
879 \r
880                                 foreach (XmlQualifiedName mt in uni.MemberTypes)\r
881                                 {\r
882                                         TypeData qn = FindBuiltInType (mt);\r
883                                         if (utype != null && qn != utype) return FindBuiltInType (anyType);\r
884                                         else utype = qn;\r
885                                 }\r
886                                 return utype;\r
887                         }\r
888                         else\r
889                                 return null;\r
890                 }\r
891 \r
892                 XmlQualifiedName GetContentBaseType (XmlSchemaObject ob)\r
893                 {\r
894                         if (ob is XmlSchemaSimpleContentExtension)\r
895                                 return ((XmlSchemaSimpleContentExtension)ob).BaseTypeName;\r
896                         else if (ob is XmlSchemaSimpleContentRestriction)\r
897                                 return ((XmlSchemaSimpleContentRestriction)ob).BaseTypeName;\r
898                         else if (ob is XmlSchemaSimpleTypeRestriction)\r
899                                 return ((XmlSchemaSimpleTypeRestriction)ob).BaseTypeName;\r
900                         else if (ob is XmlSchemaSimpleTypeList)\r
901                                 return ((XmlSchemaSimpleTypeList)ob).ItemTypeName;\r
902                         else\r
903                                 return null;\r
904                 }\r
905 \r
906                 void ImportComplexContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaComplexContent content, CodeIdentifiers classIds, bool isMixed)\r
907                 {\r
908                         ClassMap cmap = (ClassMap)map.ObjectMap;\r
909                         XmlQualifiedName qname;\r
910 \r
911                         XmlSchemaComplexContentExtension ext = content.Content as XmlSchemaComplexContentExtension;\r
912                         if (ext != null) qname = ext.BaseTypeName;\r
913                         else qname = ((XmlSchemaComplexContentRestriction)content.Content).BaseTypeName;\r
914                         \r
915                         if (HasForcedBaseType (typeQName))\r
916                                 RegisterForcedBaseType (qname, GetForcedBaseType (typeQName));\r
917                                 \r
918                         // Add base map members to this map\r
919 \r
920                         XmlTypeMapping baseMap = ImportType (qname, null);\r
921                         BuildPendingMap (baseMap);\r
922                         ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;\r
923 \r
924                         foreach (XmlTypeMapMember member in baseClassMap.AllMembers)\r
925                                 cmap.AddMember (member);\r
926 \r
927                         if (baseClassMap.XmlTextCollector != null) isMixed = false;\r
928                         else if (content.IsMixed) isMixed = true;\r
929 \r
930                         map.BaseMap = baseMap;\r
931                         baseMap.DerivedTypes.Add (map);\r
932 \r
933                         if (ext != null) {\r
934                                 // Add the members of this map\r
935                                 if (ext.Particle != null)\r
936                                         ImportParticleComplexContent (typeQName, cmap, ext.Particle, classIds, isMixed);\r
937 \r
938                                 ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);\r
939                         }\r
940                         else {\r
941                                 if (isMixed) ImportParticleComplexContent (typeQName, cmap, null, classIds, true);\r
942                         }\r
943                 }\r
944                 \r
945                 public void ImportForcedDerivedType (XmlTypeMapping map, XmlQualifiedName qname, ref bool isMixed)\r
946                 {\r
947                         ClassMap cmap = (ClassMap)map.ObjectMap;\r
948 \r
949                         XmlTypeMapping baseMap;\r
950                         Type baseType = GetForcedBaseType (qname);\r
951                         if (encodedFormat)\r
952                         {\r
953                                 if (auxXmlRefImporter == null) auxXmlRefImporter = new XmlReflectionImporter ();\r
954                                 baseMap = auxXmlRefImporter.ImportTypeMapping (baseType);\r
955                         }\r
956                         else\r
957                         {\r
958                                 if (auxSoapRefImporter == null) auxSoapRefImporter = new SoapReflectionImporter ();\r
959                                 baseMap = auxSoapRefImporter.ImportTypeMapping (baseType);\r
960                         }\r
961 \r
962                         ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;\r
963 \r
964                         foreach (XmlTypeMapMember member in baseClassMap.AllMembers)\r
965                                 cmap.AddMember (member);\r
966 \r
967                         if (baseClassMap.XmlTextCollector != null) isMixed = false;\r
968 \r
969                         map.BaseMap = baseMap;\r
970                         baseMap.DerivedTypes.Add (map);\r
971                 }\r
972                 \r
973                 void ImportExtensionTypes (XmlQualifiedName qname)\r
974                 {\r
975                         foreach (XmlSchema schema in schemas) {\r
976                                 foreach (XmlSchemaObject sob in schema.Items) \r
977                                 {\r
978                                         XmlSchemaComplexType sct = sob as XmlSchemaComplexType;\r
979                                         if (sct != null && sct.ContentModel is XmlSchemaComplexContent) {\r
980                                                 XmlQualifiedName exqname;\r
981                                                 XmlSchemaComplexContentExtension ext = sct.ContentModel.Content as XmlSchemaComplexContentExtension;\r
982                                                 if (ext != null) exqname = ext.BaseTypeName;\r
983                                                 else exqname = ((XmlSchemaComplexContentRestriction)sct.ContentModel.Content).BaseTypeName;\r
984                                                 if (exqname == qname)\r
985                                                         ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);\r
986                                         }\r
987                                 }\r
988                         }                                       \r
989                 }\r
990 \r
991                 XmlTypeMapping ImportClassSimpleType (XmlQualifiedName typeQName, XmlSchemaSimpleType stype, XmlQualifiedName root)\r
992                 {\r
993                         if (CanBeEnum (stype))\r
994                         {\r
995                                 // Create an enum map\r
996 \r
997                                 CodeIdentifiers codeIdents = new CodeIdentifiers ();\r
998                                 XmlTypeMapping enumMap = CreateTypeMapping (typeQName, SchemaTypes.Enum, null);\r
999                                 enumMap.Documentation = GetDocumentation (stype);\r
1000                                 \r
1001                                 bool isFlags = false;\r
1002                                 if (stype.Content is XmlSchemaSimpleTypeList) {\r
1003                                         stype = ((XmlSchemaSimpleTypeList)stype.Content).ItemType;\r
1004                                         isFlags = true;\r
1005                                 }\r
1006                                 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;\r
1007 \r
1008                                 codeIdents.AddReserved (enumMap.TypeData.TypeName);\r
1009 \r
1010                                 EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [rest.Facets.Count];\r
1011                                 for (int n=0; n<rest.Facets.Count; n++)\r
1012                                 {\r
1013                                         XmlSchemaEnumerationFacet enu = (XmlSchemaEnumerationFacet) rest.Facets[n];\r
1014                                         string enumName = codeIdents.AddUnique(CodeIdentifier.MakeValid (enu.Value), enu);\r
1015                                         members [n] = new EnumMap.EnumMapMember (enu.Value, enumName);\r
1016                                         members [n].Documentation = GetDocumentation (enu);\r
1017                                 }\r
1018                                 enumMap.ObjectMap = new EnumMap (members, isFlags);\r
1019                                 enumMap.IsSimpleType = true;\r
1020                                 return enumMap;\r
1021                         }\r
1022 \r
1023                         if (stype.Content is XmlSchemaSimpleTypeList)\r
1024                         {\r
1025                                 XmlSchemaSimpleTypeList slist = (XmlSchemaSimpleTypeList)stype.Content;\r
1026                                 TypeData arrayTypeData = FindBuiltInType (slist.ItemTypeName, stype);\r
1027 \r
1028                                 ListMap listMap = new ListMap ();\r
1029 \r
1030                                 listMap.ItemInfo = new XmlTypeMapElementInfoList ();\r
1031                                 listMap.ItemInfo.Add (CreateElementInfo (typeQName.Namespace, null, "Item", arrayTypeData.ListItemTypeData, false));\r
1032 \r
1033                                 XmlTypeMapping map = CreateArrayTypeMapping (typeQName, arrayTypeData);\r
1034                                 map.ObjectMap = listMap;\r
1035                                 map.IsSimpleType = true;\r
1036                                 return map;\r
1037                         }\r
1038 \r
1039                         // It is an extension of a primitive or known type\r
1040                         \r
1041                         TypeData typeData = FindBuiltInType (typeQName, stype);\r
1042                         return GetTypeMapping (typeData);\r
1043                 }\r
1044 \r
1045                 bool CanBeEnum (XmlSchemaSimpleType stype)\r
1046                 {\r
1047                         if (stype.Content is XmlSchemaSimpleTypeRestriction)\r
1048                         {\r
1049                                 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;\r
1050                                 foreach (object ob in rest.Facets)\r
1051                                         if (!(ob is XmlSchemaEnumerationFacet)) return false;\r
1052                                 return true;\r
1053                         }\r
1054                         else if (stype.Content is XmlSchemaSimpleTypeList)\r
1055                         {\r
1056                                 XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList) stype.Content;\r
1057                                 return (list.ItemType != null && CanBeEnum (list.ItemType));\r
1058                         }\r
1059                         return false;\r
1060                 }\r
1061 \r
1062                 bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaComplexType stype)\r
1063                 {\r
1064                         if (encodedFormat)\r
1065                         {\r
1066                                 XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;\r
1067                                 if (content == null) return false;\r
1068                                 XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;\r
1069                                 if (rest == null) return false;\r
1070                                 return rest.BaseTypeName == arrayType;\r
1071                         }\r
1072                         else\r
1073                         {\r
1074                                 if (stype.Attributes.Count > 0 || stype.AnyAttribute != null) return false;\r
1075                                 else return !stype.IsMixed && CanBeArray (typeQName, stype.Particle, false);\r
1076                         }\r
1077                 }\r
1078 \r
1079                 bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaParticle particle, bool multiValue)\r
1080                 {\r
1081                         // To be an array, there can't be a direct child of type typeQName\r
1082 \r
1083                         if (particle == null) return false;\r
1084 \r
1085                         multiValue = multiValue || particle.MaxOccurs > 1;\r
1086 \r
1087                         if (particle is XmlSchemaGroupRef)\r
1088                                 return CanBeArray (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), multiValue);\r
1089 \r
1090                         if (particle is XmlSchemaElement)\r
1091                         {\r
1092                                 XmlSchemaElement elem = (XmlSchemaElement)particle;\r
1093                                 if (!elem.RefName.IsEmpty)\r
1094                                         return CanBeArray (typeQName, FindRefElement (elem), multiValue);\r
1095                                 else\r
1096                                         return multiValue && !typeQName.Equals (((XmlSchemaElement)particle).SchemaTypeName);\r
1097                         }\r
1098 \r
1099                         if (particle is XmlSchemaAny)\r
1100                                 return multiValue;\r
1101 \r
1102                         if (particle is XmlSchemaSequence)\r
1103                         {\r
1104                                 XmlSchemaSequence seq = particle as XmlSchemaSequence;\r
1105                                 if (seq.Items.Count != 1) return false;\r
1106                                 return CanBeArray (typeQName, (XmlSchemaParticle)seq.Items[0], multiValue);\r
1107                         }\r
1108 \r
1109                         if (particle is XmlSchemaChoice)\r
1110                         {\r
1111                                 // Can be array if all choices have different types\r
1112                                 ArrayList types = new ArrayList ();\r
1113                                 if(!CheckChoiceType (typeQName, particle, types, ref multiValue)) return false;\r
1114                                 return multiValue;\r
1115                         }\r
1116 \r
1117                         return false;\r
1118                 }\r
1119 \r
1120                 bool CheckChoiceType (XmlQualifiedName typeQName, XmlSchemaParticle particle, ArrayList types, ref bool multiValue)\r
1121                 {\r
1122                         XmlQualifiedName type = null;\r
1123 \r
1124                         multiValue = multiValue || particle.MaxOccurs > 1;\r
1125 \r
1126                         if (particle is XmlSchemaGroupRef)\r
1127                                 return CheckChoiceType (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), types, ref multiValue);\r
1128 \r
1129                         if (particle is XmlSchemaElement) {\r
1130                                 string ns;\r
1131                                 XmlSchemaElement elem = (XmlSchemaElement)particle;\r
1132                                 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);\r
1133                                 if (refElem.SchemaType != null) return true;\r
1134                                 type = refElem.SchemaTypeName;\r
1135                         }\r
1136                         else if (particle is XmlSchemaAny) {\r
1137                                 type = anyType;\r
1138                         }\r
1139                         else if (particle is XmlSchemaSequence)\r
1140                         {\r
1141                                 XmlSchemaSequence seq = particle as XmlSchemaSequence;\r
1142                                 foreach (XmlSchemaParticle par in seq.Items)\r
1143                                         if (!CheckChoiceType (typeQName, par, types, ref multiValue)) return false;\r
1144                                 return true;\r
1145                         }\r
1146                         else if (particle is XmlSchemaChoice)\r
1147                         {\r
1148                                 foreach (XmlSchemaParticle choice in ((XmlSchemaChoice)particle).Items)\r
1149                                         if (!CheckChoiceType (typeQName, choice, types, ref multiValue)) return false;\r
1150                                 return true;\r
1151                         }\r
1152 \r
1153                         if (typeQName.Equals (type)) return false;\r
1154 \r
1155                         // For primitive types, compare using CLR types, since several\r
1156                         // xml types can be mapped to a single CLR type\r
1157 \r
1158                         string t;\r
1159                         if (type.Namespace == XmlSchema.Namespace)\r
1160                                 t = TypeTranslator.GetPrimitiveTypeData (type.Name).FullTypeName + ":" + type.Namespace;\r
1161 \r
1162                         else\r
1163                                 t = type.Name + ":" + type.Namespace;\r
1164 \r
1165                         if (types.Contains (t)) return false;\r
1166                         types.Add (t);\r
1167                         return true;\r
1168                 }\r
1169                 \r
1170                 bool CanBeAnyElement (XmlSchemaComplexType stype)\r
1171                 {\r
1172                         XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;\r
1173                         return (seq != null) && (seq.Items.Count == 1) && (seq.Items[0] is XmlSchemaAny);\r
1174                 }\r
1175 \r
1176                 bool CanBeIXmlSerializable (XmlSchemaComplexType stype)\r
1177                 {\r
1178                         XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;\r
1179                         if (seq == null) return false;\r
1180                         if (seq.Items.Count != 2) return false;\r
1181                         XmlSchemaElement elem = seq.Items[0] as XmlSchemaElement;\r
1182                         if (elem == null) return false;\r
1183                         if (elem.RefName != new XmlQualifiedName ("schema",XmlSchema.Namespace)) return false;\r
1184                         return (seq.Items[1] is XmlSchemaAny);\r
1185                 }\r
1186                 \r
1187                 void RegisterForcedBaseType (XmlQualifiedName tname, Type type)\r
1188                 {\r
1189                         if (forcedBaseTypes == null) forcedBaseTypes = new Hashtable ();\r
1190                         forcedBaseTypes [tname] = type;\r
1191                 }\r
1192                 \r
1193                 bool HasForcedBaseType (XmlQualifiedName tname)\r
1194                 {\r
1195                         if (forcedBaseTypes == null) return false;\r
1196                         return forcedBaseTypes.ContainsKey (tname);\r
1197                 }\r
1198 \r
1199                 Type GetForcedBaseType (XmlQualifiedName tname)\r
1200                 {\r
1201                         if (forcedBaseTypes == null) return null;\r
1202                         return (Type) forcedBaseTypes [tname];\r
1203                 }\r
1204 \r
1205                 XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable)\r
1206                 {\r
1207                         XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);\r
1208                         einfo.ElementName = name;\r
1209                         einfo.Namespace = ns;\r
1210                         einfo.IsNullable = isNillable;\r
1211                         if (einfo.TypeData.IsComplexType)\r
1212                                 einfo.MappedType = GetTypeMapping (typeData);\r
1213                         return einfo;\r
1214                 }\r
1215 \r
1216                 XmlTypeMapElementInfo CreateTextElementInfo (string ns, XmlTypeMapMember member, TypeData typeData)\r
1217                 {\r
1218                         XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);\r
1219                         einfo.IsTextElement = true;\r
1220                         einfo.WrappedElement = false;\r
1221                         if (typeData.IsComplexType)\r
1222                                 einfo.MappedType = GetTypeMapping (typeData);\r
1223                         return einfo;\r
1224                 }\r
1225 \r
1226                 XmlTypeMapping CreateTypeMapping (XmlQualifiedName typeQName, SchemaTypes schemaType, XmlQualifiedName root)\r
1227                 {\r
1228                         string typeName = CodeIdentifier.MakeValid (typeQName.Name);\r
1229                         typeName = typeIdentifiers.AddUnique (typeName, null);\r
1230 \r
1231                         TypeData typeData = new TypeData (typeName, typeName, typeName, schemaType, null);\r
1232 \r
1233                         string rootElem;\r
1234                         string rootNs;\r
1235                         if (root != null) {\r
1236                                 rootElem = root.Name;\r
1237                                 rootNs = root.Namespace;\r
1238                         }\r
1239                         else {\r
1240                                 rootElem = typeQName.Name;\r
1241                                 rootNs = "";\r
1242                         }\r
1243                         \r
1244                         XmlTypeMapping map = new XmlTypeMapping (rootElem, rootNs, typeData, typeQName.Name, typeQName.Namespace);\r
1245                         map.IncludeInSchema = true;\r
1246                         mappedTypes [typeQName] = map;\r
1247                         dataMappedTypes [typeData] = map;\r
1248 \r
1249                         return map;\r
1250                 }\r
1251 \r
1252                 XmlTypeMapping CreateArrayTypeMapping (XmlQualifiedName typeQName, TypeData arrayTypeData)\r
1253                 {\r
1254                         XmlTypeMapping map;\r
1255                         if (encodedFormat) map = new XmlTypeMapping ("Array", XmlSerializer.EncodingNamespace, arrayTypeData, "Array", XmlSerializer.EncodingNamespace);\r
1256                         else map = new XmlTypeMapping (arrayTypeData.XmlType, typeQName.Namespace, arrayTypeData, arrayTypeData.XmlType, typeQName.Namespace);\r
1257                         \r
1258                         map.IncludeInSchema = true;\r
1259                         mappedTypes [typeQName] = map;\r
1260                         dataMappedTypes [arrayTypeData] = map;\r
1261 \r
1262                         return map;\r
1263                 }\r
1264 \r
1265                 XmlSchemaElement GetRefElement (XmlQualifiedName typeQName, XmlSchemaElement elem, out string ns)\r
1266                 {\r
1267 \r
1268                         if (!elem.RefName.IsEmpty)\r
1269                         {\r
1270                                 ns = elem.RefName.Namespace;\r
1271                                 return FindRefElement (elem);\r
1272                         }\r
1273                         else\r
1274                         {\r
1275                                 ns = typeQName.Namespace;\r
1276                                 return elem;\r
1277                         }\r
1278                 }\r
1279 \r
1280                 XmlSchemaAttribute GetRefAttribute (XmlQualifiedName typeQName, XmlSchemaAttribute attr, out string ns)\r
1281                 {\r
1282                         if (!attr.RefName.IsEmpty)\r
1283                         {\r
1284                                 ns = attr.RefName.Namespace;\r
1285                                 return FindRefAttribute (attr.RefName);\r
1286                         }\r
1287                         else\r
1288                         {\r
1289                                 ns = typeQName.Namespace;\r
1290                                 return attr;\r
1291                         }\r
1292                 }\r
1293 \r
1294                 TypeData GetElementTypeData (XmlQualifiedName typeQName, XmlSchemaElement elem)\r
1295                 {\r
1296                         bool sharedAnnType = false;\r
1297                         XmlQualifiedName root = null;\r
1298                         \r
1299                         if (!elem.RefName.IsEmpty) {\r
1300                                 XmlSchemaElement refElem = FindRefElement (elem);\r
1301                                 if (refElem == null) throw new InvalidOperationException ("Global element not found: " + elem.RefName);\r
1302                                 root = elem.RefName;\r
1303                                 elem = refElem;\r
1304                                 sharedAnnType = true;\r
1305                         }\r
1306 \r
1307                         if (!elem.SchemaTypeName.IsEmpty) return GetTypeData (elem.SchemaTypeName, root);\r
1308                         else if (elem.SchemaType == null) return TypeTranslator.GetTypeData (typeof(object));\r
1309                         else return GetTypeData (elem.SchemaType, typeQName, elem.Name, sharedAnnType, root);\r
1310                 }\r
1311 \r
1312                 TypeData GetAttributeTypeData (XmlQualifiedName typeQName, XmlSchemaAttribute attr)\r
1313                 {\r
1314                         bool sharedAnnType = false;\r
1315 \r
1316                         if (!attr.RefName.IsEmpty) {\r
1317                                 XmlSchemaAttribute refAtt = FindRefAttribute (attr.RefName);\r
1318                                 if (refAtt == null) throw new InvalidOperationException ("Global attribute not found: " + attr.RefName);\r
1319                                 attr = refAtt;\r
1320                                 sharedAnnType = true;\r
1321                         }\r
1322                         \r
1323                         if (!attr.SchemaTypeName.IsEmpty) return GetTypeData (attr.SchemaTypeName, null);\r
1324                         else return GetTypeData (attr.SchemaType, typeQName, attr.Name, sharedAnnType, null);\r
1325                 }\r
1326 \r
1327                 TypeData GetTypeData (XmlQualifiedName typeQName, XmlQualifiedName root)\r
1328                 {\r
1329                         if (typeQName.Namespace == XmlSchema.Namespace || (encodedFormat && typeQName.Namespace == ""))\r
1330                                 return TypeTranslator.GetPrimitiveTypeData (typeQName.Name);\r
1331 \r
1332                         return ImportType (typeQName, root).TypeData;\r
1333                 }\r
1334 \r
1335                 TypeData GetTypeData (XmlSchemaType stype, XmlQualifiedName typeQNname, string propertyName, bool sharedAnnType, XmlQualifiedName root)\r
1336                 {\r
1337                         string baseName;\r
1338 \r
1339                         if (sharedAnnType)\r
1340                         {\r
1341                                 // Anonymous types defined in root elements or attributes can be shared among all elements that\r
1342                                 // reference this root element or attribute\r
1343                                 TypeData std = sharedAnonymousTypes [stype] as TypeData;\r
1344                                 if (std != null) return std;\r
1345                                 baseName = propertyName;\r
1346                         }\r
1347                         else\r
1348                                 baseName = typeQNname.Name + typeIdentifiers.MakeRightCase (propertyName);\r
1349 \r
1350                         baseName = elemIdentifiers.AddUnique (baseName, stype);\r
1351                         \r
1352                         XmlQualifiedName newName;\r
1353                         newName = new XmlQualifiedName (baseName, typeQNname.Namespace);\r
1354 \r
1355                         XmlTypeMapping map = ImportType (newName, stype, root);\r
1356                         if (sharedAnnType) sharedAnonymousTypes [stype] = map.TypeData;\r
1357 \r
1358                         return map.TypeData;\r
1359                 }\r
1360 \r
1361                 XmlTypeMapping GetTypeMapping (TypeData typeData)\r
1362                 {\r
1363                         XmlTypeMapping map = (XmlTypeMapping) dataMappedTypes [typeData];\r
1364                         if (map != null) return map;\r
1365                         \r
1366                         if (map == null && typeData.IsListType)\r
1367                         {\r
1368                                 // Create an array map for the type\r
1369 \r
1370                                 XmlTypeMapping itemMap = GetTypeMapping (typeData.ListItemTypeData);\r
1371                                 \r
1372                                 map = new XmlTypeMapping (typeData.XmlType, itemMap.Namespace, typeData, typeData.XmlType, itemMap.Namespace);\r
1373                                 map.IncludeInSchema = true;\r
1374 \r
1375                                 ListMap listMap = new ListMap ();\r
1376                                 listMap.ItemInfo = new XmlTypeMapElementInfoList();\r
1377                                 listMap.ItemInfo.Add (CreateElementInfo (itemMap.Namespace, null, typeData.ListItemTypeData.XmlType, typeData.ListItemTypeData, false));\r
1378                                 map.ObjectMap = listMap;\r
1379                                 \r
1380                                 mappedTypes [new XmlQualifiedName(map.ElementName, map.Namespace)] = map;\r
1381                                 dataMappedTypes [typeData] = map;\r
1382                                 return map;\r
1383                         }\r
1384                         else if (typeData.SchemaType == SchemaTypes.Primitive || typeData.Type == typeof(object) || typeof(XmlNode).IsAssignableFrom(typeData.Type))\r
1385                         {\r
1386                                 map = new XmlTypeMapping (typeData.XmlType, XmlSchema.Namespace, typeData, typeData.XmlType, XmlSchema.Namespace);\r
1387                                 map.IncludeInSchema = false;\r
1388                                 dataMappedTypes [typeData] = map;\r
1389                                 return map;\r
1390                         }\r
1391                         \r
1392                         throw new InvalidOperationException ("Map for type " + typeData.TypeName + " not found");\r
1393                 }\r
1394 \r
1395                 XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName)\r
1396                 {\r
1397                         return (XmlTypeMapping) mappedTypes [typeQName];\r
1398                 }\r
1399 \r
1400                 XmlSchemaParticle GetRefGroupParticle (XmlSchemaGroupRef refGroup)\r
1401                 {\r
1402                         XmlSchemaGroup grp = (XmlSchemaGroup) schemas.Find (refGroup.RefName, typeof (XmlSchemaGroup));\r
1403                         return grp.Particle;\r
1404                 }\r
1405 \r
1406                 XmlSchemaElement FindRefElement (XmlSchemaElement elem)\r
1407                 {\r
1408                         if (elem.RefName.Namespace == XmlSchema.Namespace)\r
1409                         {\r
1410                                 if (anyElement != null) return anyElement;\r
1411                                 anyElement = new XmlSchemaElement ();\r
1412                                 anyElement.Name = "any";\r
1413                                 anyElement.SchemaTypeName = anyType;\r
1414                                 return anyElement;\r
1415                         }\r
1416                         return (XmlSchemaElement) schemas.Find (elem.RefName, typeof(XmlSchemaElement));\r
1417                 }\r
1418                 \r
1419                 XmlSchemaAttribute FindRefAttribute (XmlQualifiedName refName)\r
1420                 {\r
1421                         if (refName.Namespace == XmlNamespace)\r
1422                         {\r
1423                                 XmlSchemaAttribute at = new XmlSchemaAttribute ();\r
1424                                 at.Name = refName.Name;\r
1425                                 at.SchemaTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);\r
1426                                 return at;\r
1427                         }\r
1428                         return (XmlSchemaAttribute) schemas.Find (refName, typeof(XmlSchemaAttribute));\r
1429                 }\r
1430 \r
1431                 string GetDocumentation (XmlSchemaAnnotated elem)\r
1432                 {\r
1433                         string res = "";\r
1434                         XmlSchemaAnnotation anot = elem.Annotation;\r
1435                         if (anot == null || anot.Items == null) return null;\r
1436                         \r
1437                         foreach (object ob in anot.Items)\r
1438                         {\r
1439                                 XmlSchemaDocumentation doc = ob as XmlSchemaDocumentation;\r
1440                                 if (doc != null && doc.Markup != null && doc.Markup.Length > 0) {\r
1441                                         if (res != string.Empty) res += "\n";\r
1442                                         foreach (XmlNode node in doc.Markup)\r
1443                                                 res += node.Value;\r
1444                                 }\r
1445                         }\r
1446                         return res;\r
1447                 }\r
1448 \r
1449                 #endregion // Methods\r
1450         }\r
1451 }