Fix XMM scanning on Mac x86.
[mono.git] / mcs / class / referencesource / System.Data / System / Data / XMLSchema.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XMLSchema.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 // <owner current="true" primary="true">[....]</owner>
6 // <owner current="true" primary="false">[....]</owner>
7 //------------------------------------------------------------------------------
8
9 namespace System.Data {
10     using System;
11     using System.Data.Common;
12     using System.Xml;
13     using System.Xml.Schema;
14     using System.Diagnostics;
15     using System.Collections;
16     using System.Collections.Generic;
17     using System.Globalization;
18     using System.ComponentModel;
19     using System.Security;
20     using System.Security.Permissions;
21
22     internal class XMLSchema {
23
24         internal static TypeConverter GetConverter(Type type) { 
25 #if FEATURE_MONO_CAS
26             HostProtectionAttribute protAttrib = new HostProtectionAttribute();
27             protAttrib.SharedState = true;
28             CodeAccessPermission permission = (CodeAccessPermission)protAttrib.CreatePermission();
29             permission.Assert(); 
30 #endif
31             try {
32                 return TypeDescriptor.GetConverter(type);
33             }
34             finally {
35 #if FEATURE_MONO_CAS
36                 CodeAccessPermission.RevertAssert(); 
37 #endif
38             }
39         }
40
41         internal static void SetProperties(Object instance, XmlAttributeCollection attrs) {
42             // This is called from both XSD and XDR schemas. 
43             // Do we realy need it in XSD ???
44             for (int i = 0; i < attrs.Count; i++) {
45                 if (attrs[i].NamespaceURI == Keywords.MSDNS) {
46                     string name  = attrs[i].LocalName;
47                     string value = attrs[i].Value;
48
49                     if (name == "DefaultValue" || name == "RemotingFormat")
50                         continue;
51 // Webdata 97925, skipp expressions, we will handle them after SetProperties (in xdrschema)
52                     if (name == "Expression" &&  instance is DataColumn)
53                         continue;
54
55                     PropertyDescriptor pd = TypeDescriptor.GetProperties(instance)[name];
56                     if (pd != null) {
57                         // Standard property
58                         Type type = pd.PropertyType;
59
60                         TypeConverter converter = XMLSchema.GetConverter(type);
61                         object propValue;
62                         if (converter.CanConvertFrom(typeof(string))) {
63                             propValue = converter.ConvertFromString(value);
64                         }else if (type == typeof(Type)) {
65                             propValue = DataStorage.GetType(value);
66                         }else if (type == typeof(CultureInfo)) {
67                             propValue = new CultureInfo(value);
68                         }else {
69                             throw ExceptionBuilder.CannotConvert(value,type.FullName);
70                         }
71                         pd.SetValue(instance, propValue);
72                     }
73                 }
74             }
75         }// SetProperties
76
77         internal static bool FEqualIdentity(XmlNode node, String name, String ns) {
78             if (node != null && node.LocalName == name && node.NamespaceURI == ns)
79                 return true;
80
81             return false;
82         }
83
84         internal static bool GetBooleanAttribute(XmlElement element, String attrName, String attrNS, bool defVal) {
85             string value = element.GetAttribute(attrName, attrNS);
86             if (value == null || value.Length == 0) {
87                 return defVal;
88             }
89             if ((value == Keywords.TRUE) || (value == Keywords.ONE_DIGIT)){
90                 return true;
91             }
92             if ((value == Keywords.FALSE) || (value == Keywords.ZERO_DIGIT)){
93                 return false;
94             }
95             // Error processing:
96             throw ExceptionBuilder.InvalidAttributeValue(attrName, value);
97         }
98
99         internal static string GenUniqueColumnName(string proposedName, DataTable table) {
100
101             if (table.Columns.IndexOf(proposedName) >= 0) {
102                 for (int i=0; i <= table.Columns.Count; i++) {
103                     string tempName = proposedName + "_" + (i).ToString(CultureInfo.InvariantCulture);
104                     if (table.Columns.IndexOf(tempName) >= 0) {
105                         continue;
106                     }
107                     else {
108                         return tempName;
109                     }
110                 }
111             }
112             return proposedName;
113         }
114      }
115
116     internal sealed class ConstraintTable {
117         public DataTable table;
118         public XmlSchemaIdentityConstraint constraint;
119         public ConstraintTable(DataTable t, XmlSchemaIdentityConstraint c) {
120             table = t;
121             constraint = c;
122         }
123     }
124
125     internal sealed class XSDSchema :  XMLSchema 
126     {
127         XmlSchemaSet _schemaSet = null;    
128         XmlSchemaElement dsElement = null;
129         DataSet _ds = null;
130         String _schemaName = null;
131         private ArrayList ColumnExpressions;
132         private Hashtable ConstraintNodes;
133         private ArrayList RefTables;
134         private ArrayList complexTypes;
135         XmlSchemaObjectCollection annotations;
136         XmlSchemaObjectCollection elements;
137         Hashtable attributes;
138         Hashtable elementsTable;
139         Hashtable attributeGroups;
140         Hashtable schemaTypes;
141         Hashtable expressions;
142         Dictionary <DataTable, List<DataTable>> tableDictionary;
143
144         Hashtable udSimpleTypes;
145
146         Hashtable existingSimpleTypeMap;
147         
148         private bool fromInference = false;
149         
150         internal bool FromInference {
151             get {
152                 return fromInference;
153             }
154             set {
155                 fromInference = value;
156             }
157         }        
158
159         private void CollectElementsAnnotations(XmlSchema schema){
160             ArrayList schemaList = new ArrayList();
161             CollectElementsAnnotations(schema, schemaList);
162             schemaList.Clear();
163         }
164         
165         private void CollectElementsAnnotations(XmlSchema schema, ArrayList schemaList){
166             if (schemaList.Contains(schema)) {
167                 return;
168             }
169             schemaList.Add(schema);
170
171             foreach(object item in schema.Items) {
172                 if (item is XmlSchemaAnnotation) {
173                     annotations.Add((XmlSchemaAnnotation)item);
174                 }
175                 if (item is XmlSchemaElement) {
176                     XmlSchemaElement elem = (XmlSchemaElement)item;
177                     elements.Add(elem);
178                     elementsTable[elem.QualifiedName] = elem;
179                 }
180                 if (item is XmlSchemaAttribute) {
181                     XmlSchemaAttribute attr = (XmlSchemaAttribute)item;
182                     attributes[attr.QualifiedName] = attr;
183                 }
184                 if (item is XmlSchemaAttributeGroup) {
185                     XmlSchemaAttributeGroup attr = (XmlSchemaAttributeGroup)item;
186                     attributeGroups[attr.QualifiedName] = attr;
187                 }
188                 if (item is XmlSchemaType) {
189                     string MSDATATargetNamespace = null;
190                     if (item is XmlSchemaSimpleType) {
191                         MSDATATargetNamespace = XSDSchema.GetMsdataAttribute((XmlSchemaType)item, Keywords.TARGETNAMESPACE);
192                     }
193                     
194                     XmlSchemaType type = (XmlSchemaType)item;
195                     schemaTypes[type.QualifiedName] = type;
196
197 // Webdata 92054 if we have a User Defined simple type, cache it so later we may need for mapping
198 // meanwhile more convinient solution would be to directly use schemaTypes, but it would be more complex to handle
199                     XmlSchemaSimpleType xmlSimpleType = (item as XmlSchemaSimpleType );
200                     if (xmlSimpleType != null) { 
201                         if (udSimpleTypes == null) {
202                             udSimpleTypes = new Hashtable();
203                         }
204
205                         udSimpleTypes[type.QualifiedName.ToString()] = xmlSimpleType;
206                         DataColumn dc = (DataColumn)existingSimpleTypeMap[type.QualifiedName.ToString()];
207                         // Assumption is that our simple type qualified name ihas the same output as XmlSchemaSimpleType type.QualifiedName.ToString()
208                         SimpleType tmpSimpleType = (dc != null)? dc.SimpleType: null;
209 // 
210                         if (tmpSimpleType != null) {
211                             SimpleType tmpDataSimpleType = new SimpleType(xmlSimpleType);
212                             string errorStr = tmpSimpleType.HasConflictingDefinition(tmpDataSimpleType);
213                             if (errorStr.Length != 0) {
214                                 throw ExceptionBuilder.InvalidDuplicateNamedSimpleTypeDelaration(tmpDataSimpleType.SimpleTypeQualifiedName, errorStr);
215                             }
216                         }
217                         
218                     }                    
219                 }
220             }
221             foreach(XmlSchemaExternal include in schema.Includes) {
222                 if (include is XmlSchemaImport)
223                     continue;
224                 if (include.Schema != null) {
225                     CollectElementsAnnotations(include.Schema, schemaList);
226                 }
227             }
228         }
229
230         internal static string QualifiedName(string name) {
231             int iStart = name.IndexOf(':');
232             if (iStart == -1)
233                 return Keywords.XSD_PREFIXCOLON + name;
234             else
235                 return name;
236         }
237
238         internal static void SetProperties(Object instance, XmlAttribute[] attrs) {
239             // This is called from both XSD and XDR schemas. 
240             // Do we realy need it in XSD ???
241             if (attrs == null)
242                 return;
243             for (int i = 0; i < attrs.Length; i++) {
244                 if (attrs[i].NamespaceURI == Keywords.MSDNS) {
245                     string name  = attrs[i].LocalName;
246                     string value = attrs[i].Value;
247
248                     if (name == "DefaultValue" || name == "Ordinal" || name == "Locale" || name == "RemotingFormat")
249                         continue;
250
251                     if (name == "Expression" &&  instance is DataColumn) // Webdata 97925: we will handle columnexpressions at HandleColumnExpression
252                         continue;
253
254                     if (name == "DataType") {
255                         DataColumn col = instance as DataColumn;
256                         if (col != null) {
257                             col.DataType = DataStorage.GetType(value);
258                         }
259
260                         continue;
261                     }
262
263                     PropertyDescriptor pd = TypeDescriptor.GetProperties(instance)[name];
264                     if (pd != null) {
265                         // Standard property
266                         Type type = pd.PropertyType;
267
268                         TypeConverter converter = XMLSchema.GetConverter(type);
269                         object propValue;
270                         if (converter.CanConvertFrom(typeof(string))) {
271                             propValue = converter.ConvertFromString(value);
272                         }else if (type == typeof(Type)) {
273                             propValue = Type.GetType(value);
274                         }else if (type == typeof(CultureInfo)) {
275                             propValue = new CultureInfo(value);
276                         }else {
277                             throw ExceptionBuilder.CannotConvert(value,type.FullName);
278                         }
279                         pd.SetValue(instance, propValue);
280                     }
281                 }
282             }
283         }// SetProperties
284
285         private static void SetExtProperties(Object instance, XmlAttribute[] attrs) {
286             PropertyCollection props = null;
287             if (attrs == null)
288                 return;
289             for (int i = 0; i < attrs.Length; i++) {
290                 if (attrs[i].NamespaceURI == Keywords.MSPROPNS) {
291                     if(props == null) {
292                         object val = TypeDescriptor.GetProperties(instance)["ExtendedProperties"].GetValue(instance);
293                         Debug.Assert(val is PropertyCollection, "We can set values only for classes that have ExtendedProperties");
294                         props = (PropertyCollection) val;
295                     }
296                     string propName = XmlConvert.DecodeName(attrs[i].LocalName);
297
298                     if (instance is ForeignKeyConstraint) {
299                         if (propName.StartsWith(Keywords.MSD_FK_PREFIX, StringComparison.Ordinal)) 
300                             propName = propName.Substring(3);
301                         else 
302                             continue; 
303                     }
304                     if ((instance is DataRelation) && (propName.StartsWith(Keywords.MSD_REL_PREFIX, StringComparison.Ordinal))) {
305                             propName = propName.Substring(4);
306                     }
307                     else if ((instance is DataRelation) && (propName.StartsWith(Keywords.MSD_FK_PREFIX, StringComparison.Ordinal))) {
308                         continue;
309                     }
310
311                     props.Add(propName, attrs[i].Value);
312                 }
313             }
314         }// SetExtProperties
315
316         private void HandleColumnExpression(Object instance, XmlAttribute[] attrs) {
317             if (attrs == null)
318                 return;
319             DataColumn dc = instance as DataColumn;
320             Debug.Assert(dc != null, "HandleColumnExpression is supposed to be called for DataColumn");
321             if (dc != null ) {
322                 for (int i = 0; i < attrs.Length; i++) {
323                     if (attrs[i].NamespaceURI == Keywords.MSDNS) {
324                         if (attrs[i].LocalName == "Expression"){
325                             if (this.expressions == null)
326                                 this.expressions = new Hashtable();
327                             this.expressions[dc] = attrs[i].Value;
328                             ColumnExpressions.Add(dc);
329                             break;
330                         }
331                     }
332                 }
333             }
334         }
335         
336         internal static String GetMsdataAttribute(XmlSchemaAnnotated node, String ln) {
337             XmlAttribute[]   nodeAttributes = node.UnhandledAttributes;
338             if (nodeAttributes!=null)
339                 for(int i=0; i<nodeAttributes.Length;i++)
340                     if (nodeAttributes[i].LocalName == ln && nodeAttributes[i].NamespaceURI == Keywords.MSDNS)
341                         return nodeAttributes[i].Value;
342             return null;
343         }
344                 
345         private static void SetExtProperties(Object instance, XmlAttributeCollection attrs) {
346             PropertyCollection props = null;
347             for (int i = 0; i < attrs.Count; i++) {
348                 if (attrs[i].NamespaceURI == Keywords.MSPROPNS) {
349                     if(props == null) {
350                         object val = TypeDescriptor.GetProperties(instance)["ExtendedProperties"].GetValue(instance);
351                         Debug.Assert(val is PropertyCollection, "We can set values only for classes that have ExtendedProperties");
352                         props = (PropertyCollection) val;
353                     }
354                     string propName = XmlConvert.DecodeName(attrs[i].LocalName);
355                     props.Add(propName, attrs[i].Value);
356                 }
357             }
358         }// SetExtProperties
359
360         internal void HandleRefTableProperties(ArrayList RefTables, XmlSchemaElement element) {
361             string typeName = GetInstanceName(element);
362             DataTable table = _ds.Tables.GetTable(XmlConvert.DecodeName(typeName), element.QualifiedName.Namespace);
363             Debug.Assert(table != null, "ref table should have been already created");
364
365             SetProperties(table, element.UnhandledAttributes);
366             SetExtProperties(table, element.UnhandledAttributes);
367         }
368         
369         internal void HandleRelation(XmlElement node, bool fNested) {
370             string          strName;
371             string          parentName;
372             string          childName;
373             string []       parentNames;
374             string []       childNames;
375             string          value;
376             bool            fCreateConstraints = false; //if we have a relation,
377                                                         //we do not have constraints
378             DataRelationCollection rels = _ds.Relations;
379             DataRelation    relation;
380             DataColumn []   parentKey;
381             DataColumn []   childKey;
382             DataTable       parent;
383             DataTable       child;
384             int             keyLength;
385
386             strName = XmlConvert.DecodeName(node.GetAttribute(Keywords.NAME));
387             for (int i = 0; i < rels.Count; ++i) {
388                 if (0 == String.Compare(rels[i].RelationName, strName, StringComparison.Ordinal)) 
389                     return;
390             }
391
392             parentName = node.GetAttribute(Keywords.MSD_PARENT, Keywords.MSDNS);
393             if (parentName == null || parentName.Length==0)
394                 throw ExceptionBuilder.RelationParentNameMissing(strName);
395             parentName = XmlConvert.DecodeName(parentName);
396             
397             childName = node.GetAttribute(Keywords.MSD_CHILD, Keywords.MSDNS);
398             if (childName == null || childName.Length==0)
399                 throw ExceptionBuilder.RelationChildNameMissing(strName);
400             childName = XmlConvert.DecodeName(childName);
401
402             value = node.GetAttribute(Keywords.MSD_PARENTKEY, Keywords.MSDNS);
403             if (value == null || value.Length==0)
404                 throw ExceptionBuilder.RelationTableKeyMissing(strName);
405
406             parentNames = value.TrimEnd(null).Split(new char[] {Keywords.MSD_KEYFIELDSEP, Keywords.MSD_KEYFIELDOLDSEP});
407             value = node.GetAttribute(Keywords.MSD_CHILDKEY, Keywords.MSDNS);
408             if (value == null || value.Length==0)
409                 throw ExceptionBuilder.RelationChildKeyMissing(strName);
410
411             childNames = value.TrimEnd(null).Split(new char[] {Keywords.MSD_KEYFIELDSEP, Keywords.MSD_KEYFIELDOLDSEP});
412
413             keyLength = parentNames.Length;
414             if (keyLength != childNames.Length)
415                 throw ExceptionBuilder.MismatchKeyLength();
416
417             parentKey = new DataColumn[keyLength];
418             childKey = new DataColumn[keyLength];
419
420             string parentNs = node.GetAttribute(Keywords.MSD_PARENTTABLENS, Keywords.MSDNS);
421             string childNs = node.GetAttribute(Keywords.MSD_CHILDTABLENS, Keywords.MSDNS);
422             
423             parent = _ds.Tables.GetTableSmart(parentName,parentNs);
424
425             if (parent == null)
426                 throw ExceptionBuilder.ElementTypeNotFound(parentName);
427
428             child =  _ds.Tables.GetTableSmart(childName,childNs);
429
430             if (child == null)
431                 throw ExceptionBuilder.ElementTypeNotFound(childName);
432
433             for (int i = 0; i < keyLength; i++) {
434                 parentKey[i] = parent.Columns[XmlConvert.DecodeName(parentNames[i])];
435                 if (parentKey[i] == null)
436                     throw ExceptionBuilder.ElementTypeNotFound(parentNames[i]);
437                 childKey[i] = child.Columns[XmlConvert.DecodeName(childNames[i])];
438                 if (childKey[i] == null)
439                     throw ExceptionBuilder.ElementTypeNotFound(childNames[i]);
440             }
441             relation = new DataRelation(strName, parentKey, childKey, fCreateConstraints);
442             relation.Nested = fNested;
443             SetExtProperties(relation, node.Attributes);
444             _ds.Relations.Add(relation);
445             if (FromInference && relation.Nested) {
446                 tableDictionary[relation.ParentTable].Add(relation.ChildTable);
447             }
448         }
449
450         private bool HasAttributes(XmlSchemaObjectCollection attributes){
451             foreach (XmlSchemaObject so in attributes) {
452                 if (so is XmlSchemaAttribute) {
453                    return true;
454                 }
455                 if (so is XmlSchemaAttributeGroup) {
456                    return true;
457                 }
458                 if (so is XmlSchemaAttributeGroupRef) {
459                    return true;
460                 }
461             }
462             return false;
463         }
464
465         private bool IsDatasetParticle(XmlSchemaParticle pt){
466             XmlSchemaObjectCollection items = GetParticleItems(pt);
467     
468             if (items == null)
469                 return false; // empty element, threat it as table
470             
471             bool isChoice = this.FromInference && (pt is XmlSchemaChoice);// currently we add this support for choice, just for inference
472
473
474             foreach (XmlSchemaAnnotated el in items){
475                 if (el is XmlSchemaElement) {
476
477                     // pushing max occur of choice element to its imidiate children of type xs:elements
478                     if (isChoice && pt.MaxOccurs > Decimal.One && (((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)) // we know frominference condition
479                         ((XmlSchemaElement)el).MaxOccurs = pt.MaxOccurs;
480
481             if (((XmlSchemaElement)el).RefName.Name.Length != 0) {
482                 if (!FromInference || (((XmlSchemaElement)el).MaxOccurs != Decimal.One &&  !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)))
483                     continue;
484             }
485
486
487                     if (!IsTable ((XmlSchemaElement)el))
488                         return false;
489
490                     continue;
491                 }
492             
493                 if (el is XmlSchemaParticle) {
494                     if (!IsDatasetParticle((XmlSchemaParticle)el))
495                         return false;
496                 }
497             } 
498
499             return true;
500         }
501         
502         private int DatasetElementCount(XmlSchemaObjectCollection elements) {
503             int nCount = 0;
504             foreach(XmlSchemaElement XmlElement in elements) {
505                 if (GetBooleanAttribute(XmlElement, Keywords.MSD_ISDATASET,  /*default:*/ false)) {
506                     nCount++;
507                 }
508             }
509             return nCount;
510         }
511
512         private XmlSchemaElement FindDatasetElement(XmlSchemaObjectCollection elements) {
513             foreach(XmlSchemaElement XmlElement in elements) {
514                 if (GetBooleanAttribute(XmlElement, Keywords.MSD_ISDATASET,  /*default:*/ false)) 
515                     return XmlElement;
516             }
517             if ((elements.Count == 1) || (this.FromInference && elements.Count > 0)) { //let's see if this element looks like a DataSet
518
519                 XmlSchemaElement node = (XmlSchemaElement)elements[0];
520                 if (!GetBooleanAttribute(node, Keywords.MSD_ISDATASET,  /*default:*/ true)) 
521                     return null;
522
523                 XmlSchemaComplexType ct = node.SchemaType as XmlSchemaComplexType;
524                 if (ct == null)
525                     return null;
526
527                 while (ct != null) {
528                     if (HasAttributes(ct.Attributes))
529                         return null;
530
531                      if (ct.ContentModel is XmlSchemaSimpleContent){
532                          XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent) (ct.ContentModel)).Content;
533                          if (cContent is XmlSchemaSimpleContentExtension) {
534                               XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension) cContent );
535                              if (HasAttributes(ccExtension.Attributes))
536                                 return null;
537                           } else {
538                               XmlSchemaSimpleContentRestriction ccRestriction = ((XmlSchemaSimpleContentRestriction) cContent );
539                              if (HasAttributes(ccRestriction.Attributes))
540                                 return null;
541                           }
542                      }
543                      
544                     
545                     XmlSchemaParticle particle = GetParticle(ct);
546                     if (particle != null) {
547                         if (!IsDatasetParticle(particle))
548                             return null; // it's a table
549                         } 
550
551                     if (ct.BaseXmlSchemaType is XmlSchemaComplexType) 
552                         ct = (XmlSchemaComplexType)ct.BaseXmlSchemaType;
553                     else
554                         break;
555                 }
556
557
558                 //if we are here there all elements are tables
559                 return node;
560             }
561             return null;
562         }
563
564         public void LoadSchema(XmlSchemaSet schemaSet , DataTable dt) {
565             if (dt.DataSet != null)
566                 LoadSchema(schemaSet, dt.DataSet);
567         }
568         public void LoadSchema(XmlSchemaSet schemaSet , DataSet ds) { //Element schemaRoot, DataSet ds) {
569             ConstraintNodes = new Hashtable();
570             RefTables = new ArrayList();
571             ColumnExpressions = new ArrayList();
572             complexTypes = new ArrayList();
573             bool setRootNStoDataSet = false;
574             bool newDataSet = (ds.Tables.Count == 0);
575
576             if (schemaSet == null) // 
577                 return;
578             _schemaSet = schemaSet;
579             _ds = ds;
580             ds.fIsSchemaLoading = true;
581
582             foreach (XmlSchema schemaRoot in schemaSet.Schemas()) {
583                 _schemaName = schemaRoot.Id;
584
585                 if (_schemaName == null ||_schemaName.Length == 0) {
586                     _schemaName = "NewDataSet";
587                 }
588                 ds.DataSetName = XmlConvert.DecodeName(_schemaName);
589                 string ns = schemaRoot.TargetNamespace;
590                 if (ds.namespaceURI == null || ds.namespaceURI.Length == 0) {// set just one time, for backward compatibility
591                     ds.namespaceURI = (ns== null)? string.Empty : ns;           // see fx\Data\XDO\ReadXml\SchemaM2.xml for more info
592                 }
593                 break; // we just need to take Name and NS from first schema [V1.0 & v1.1 semantics]
594             }
595             
596             annotations = new XmlSchemaObjectCollection();
597             elements = new XmlSchemaObjectCollection();
598             elementsTable = new Hashtable();
599             attributes = new Hashtable();
600             attributeGroups = new Hashtable();
601             schemaTypes = new Hashtable();
602             tableDictionary = new Dictionary <DataTable, List<DataTable>>() ;
603
604             existingSimpleTypeMap = new Hashtable();
605             foreach(DataTable dt in ds.Tables){
606                 foreach(DataColumn dc in dt.Columns) {
607                     if (dc.SimpleType!= null && dc.SimpleType.Name != null && dc.SimpleType.Name.Length != 0) {
608                         existingSimpleTypeMap[dc.SimpleType.SimpleTypeQualifiedName] = dc;
609 //                        existingSimpleTypeMap[dc.SimpleType.SimpleTypeQualifiedName] = dc.SimpleType;
610                     }
611                 }
612             }
613
614
615
616             foreach (XmlSchema schemaRoot in schemaSet.Schemas())
617                 CollectElementsAnnotations(schemaRoot);
618
619
620
621             dsElement = FindDatasetElement(elements);
622             if (dsElement != null) {
623                 string mainName = GetStringAttribute (dsElement, Keywords.MSD_MAINDATATABLE, "");
624                 if (null != mainName) {
625                     ds.MainTableName = XmlConvert.DecodeName (mainName);
626                 }
627             }
628             else {
629                 if (this.FromInference) {
630                     ds.fTopLevelTable = true; // Backward compatability: for inference, if we do not read DataSet element
631                 }
632                 // we should not write it also
633                 setRootNStoDataSet = true;
634                 //incase of Root is not mapped to DataSet and is mapped to DataTable instead; to be backward compatable
635                 // we need to set the Namespace of Root to DataSet's namespace also(it would be NS of First DataTable in collection)
636             }
637
638             List<XmlQualifiedName> qnames = new List<XmlQualifiedName>();
639                 
640             if (ds != null && ds.UseDataSetSchemaOnly) {
641                 int dataSetElementCount = DatasetElementCount(elements);
642                 if (dataSetElementCount == 0) {
643                     throw ExceptionBuilder.IsDataSetAttributeMissingInSchema();
644                 }
645                 else if (dataSetElementCount > 1) {
646                     throw ExceptionBuilder.TooManyIsDataSetAtributeInSchema();
647                 }              
648
649                 XmlSchemaComplexType ct = (XmlSchemaComplexType) FindTypeNode(dsElement);
650                 if (ct.Particle != null) {
651                     XmlSchemaObjectCollection items = GetParticleItems(ct.Particle);
652                     if (items != null) {
653                         foreach (XmlSchemaAnnotated el in items){
654                             XmlSchemaElement sel = el as XmlSchemaElement;
655                             if (null != sel) {
656                                 if(sel.RefName.Name.Length != 0 ) {
657                                     qnames.Add(sel.QualifiedName);
658                                 }
659                             }
660                         }
661                     }
662                 }
663                 
664             }
665
666             // Walk all the top level Element tags.  
667             foreach (XmlSchemaElement element in elements) {
668                 if (element == dsElement)
669                     continue;
670                 if (ds != null && ds.UseDataSetSchemaOnly && dsElement != null) {
671                     if (dsElement.Parent != element.Parent) {
672                         if (!qnames.Contains(element.QualifiedName)) {
673                             continue;
674                         }
675                     }
676                 }
677
678                 String typeName = GetInstanceName(element);
679                 if (RefTables.Contains(element.QualifiedName.Namespace +":"+ typeName)) {
680                     HandleRefTableProperties(RefTables, element);
681                     continue;
682                 }
683
684                 DataTable table = HandleTable(element);
685             } 
686             
687             if (dsElement!=null)
688                 HandleDataSet(dsElement, newDataSet);
689
690             foreach (XmlSchemaAnnotation annotation in annotations) {
691                 HandleRelations(annotation, false);
692             }
693
694 //just add Expressions, at this point and if ColumnExpressions.Count > 0, this.expressions should not be null 
695             for(int i=0; i<ColumnExpressions.Count; i++) {
696                 DataColumn dc = ((DataColumn)(ColumnExpressions[i]));
697                 dc.Expression = (string) this.expressions[dc];
698             }             
699
700             foreach (DataTable dt in ds.Tables) {
701                 if (dt.NestedParentRelations.Length == 0 && dt.Namespace == ds.Namespace) {
702                     DataRelationCollection childRelations = dt.ChildRelations;// WebData 113251 if we nulling NS of parent table,
703                     for (int j = 0; j < childRelations.Count; j++) {   //  we need to do the same thing for nested child tables as they
704                         if (childRelations[j].Nested && dt.Namespace == childRelations[j].ChildTable.Namespace) { // take NS from Parent table
705                             childRelations[j].ChildTable.tableNamespace = null;
706                         }
707                     }
708                     dt.tableNamespace = null;
709                 }
710             }
711
712            DataTable tmpTable = ds.Tables[ds.DataSetName, ds.Namespace];
713            if ( tmpTable  != null) // this fix is done to support round-trip problem in case if there is one table with same name and NS
714                tmpTable.fNestedInDataset = true;
715
716
717             // this fix is for backward compatability with old inference engine
718             if (this.FromInference && ds.Tables.Count == 0 && String.Compare(ds.DataSetName, "NewDataSet", StringComparison.Ordinal) == 0)
719                 ds.DataSetName = XmlConvert.DecodeName(((XmlSchemaElement)elements[0]).Name);
720
721             
722             ds.fIsSchemaLoading = false; //reactivate column computations
723
724
725             //for backward compatability; we need to set NS of Root Element to DataSet, if root already does not mapped to dataSet
726             if (setRootNStoDataSet) { 
727                 if (ds.Tables.Count > 0) { // if there is table, take first one's NS
728                     ds.Namespace = ds.Tables[0].Namespace;
729                     ds.Prefix = ds.Tables[0].Prefix;
730                 }
731                 else {// otherwise, take TargetNS from first schema
732                     Debug.Assert(schemaSet.Count == 1, "there should be one schema");
733                     foreach (XmlSchema schemaRoot in schemaSet.Schemas()) { // we should have 1 schema
734                         ds.Namespace = schemaRoot.TargetNamespace;
735                     }
736                 }
737             }
738         }
739
740         private void HandleRelations(XmlSchemaAnnotation ann, bool fNested) {
741             foreach (object __items in ann.Items)
742             if (__items is XmlSchemaAppInfo) {
743                 XmlNode[] relations = ((XmlSchemaAppInfo) __items).Markup;
744                 for (int i = 0; i<relations.Length; i++)
745                 if (FEqualIdentity(relations[i], Keywords.MSD_RELATION, Keywords.MSDNS))
746                     HandleRelation((XmlElement)relations[i], fNested);
747             }
748         }
749         
750         internal XmlSchemaObjectCollection GetParticleItems(XmlSchemaParticle pt){
751             if (pt is XmlSchemaSequence)
752                 return ((XmlSchemaSequence)pt).Items;
753             if (pt is XmlSchemaAll)
754                 return ((XmlSchemaAll)pt).Items;
755             if (pt is XmlSchemaChoice)
756                 return ((XmlSchemaChoice)pt).Items;
757             if (pt is XmlSchemaAny)
758                 return null;
759             // the code below is a little hack for the SOM behavior        
760             if (pt is XmlSchemaElement) {
761                 XmlSchemaObjectCollection Items = new XmlSchemaObjectCollection();
762                 Items.Add(pt);
763                 return Items;
764             }
765             if (pt is XmlSchemaGroupRef)
766                 return GetParticleItems( ((XmlSchemaGroupRef)pt).Particle );
767             // should never get here.
768             return null;
769
770         }
771
772         internal void HandleParticle(XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, bool isBase){
773             XmlSchemaObjectCollection items = GetParticleItems(pt);
774             
775             if (items == null)
776                 return;
777
778             foreach (XmlSchemaAnnotated item in items){
779                 XmlSchemaElement el = item as XmlSchemaElement;
780                 if (el != null) {
781                     if (this.FromInference && pt is XmlSchemaChoice && pt.MaxOccurs > Decimal.One && (el.SchemaType is XmlSchemaComplexType))
782                         ((XmlSchemaElement)el).MaxOccurs = pt.MaxOccurs;
783                    
784
785                     DataTable child = null;
786                     // to decide if element is our table, we need to match both name and ns 
787                     // 286043 - SQL BU Defect Tracking
788                     if (((el.Name == null) && (el.RefName.Name == table.EncodedTableName && el.RefName.Namespace == table.Namespace)) ||
789                         (IsTable(el) && el.Name == table.TableName)) {
790                         if (this.FromInference) {
791                             child = HandleTable ((XmlSchemaElement)el);
792                             Debug.Assert(child == table, "table not the same");
793                         }
794                         else {
795                             child = table;
796                         }
797                     }
798                     else {
799                         child = HandleTable ((XmlSchemaElement)el);
800                         if (child == null && this.FromInference && el.Name == table.TableName) {
801                             child = table;
802                         }
803                     }
804                     
805                     if (child==null) {
806                         if (!this.FromInference || el.Name != table.TableName) {// check is required to support 1.1 inference behavior
807                             HandleElementColumn((XmlSchemaElement)el, table, isBase); 
808                         }
809                     }
810                     else {
811                         DataRelation relation = null;
812                         if (el.Annotation != null)
813                             HandleRelations(el.Annotation, true);
814
815                         DataRelationCollection childRelations = table.ChildRelations;
816                         for (int j = 0; j < childRelations.Count; j++) {
817                             if (!childRelations[j].Nested)
818                                 continue;
819
820                             if (child == childRelations[j].ChildTable)
821                                 relation = childRelations[j];
822                         }
823
824                         if (relation == null) {
825                             tableChildren.Add(child);// how about prefix for this?
826                             if(this.FromInference && table.UKColumnPositionForInference == -1) { // this is done for Inference
827                                 int ukColumnPosition = -1;
828                                 foreach(DataColumn dc in table.Columns) {
829                                     if (dc.ColumnMapping == MappingType.Element)
830                                         ukColumnPosition++;
831                                 }
832                                 table.UKColumnPositionForInference = ukColumnPosition + 1; // since it starts from 
833                             }
834                         }
835                     }
836                 } 
837                 else {
838                     HandleParticle((XmlSchemaParticle)item, table, tableChildren, isBase);
839                 }
840
841             }
842             return ;
843         }
844
845         internal void HandleAttributes(XmlSchemaObjectCollection attributes, DataTable table, bool isBase) {
846         foreach (XmlSchemaObject so in attributes) {
847                 if (so is XmlSchemaAttribute) {
848                     HandleAttributeColumn((XmlSchemaAttribute) so, table, isBase);
849                 }
850                 else {  // XmlSchemaAttributeGroupRef
851                     XmlSchemaAttributeGroupRef groupRef =  so as XmlSchemaAttributeGroupRef;
852                     XmlSchemaAttributeGroup schemaGroup = attributeGroups[groupRef.RefName] as XmlSchemaAttributeGroup;
853                     if (schemaGroup!=null) {
854                         HandleAttributeGroup(schemaGroup, table, isBase);
855                     }
856                 }
857             }
858         }
859
860        private void HandleAttributeGroup(XmlSchemaAttributeGroup attributeGroup, DataTable table, bool isBase) {
861            foreach (XmlSchemaObject obj in attributeGroup.Attributes) {
862                if (obj is XmlSchemaAttribute) {
863                    HandleAttributeColumn((XmlSchemaAttribute) obj, table, isBase);
864                }
865                else { // XmlSchemaAttributeGroupRef
866                    XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
867                    XmlSchemaAttributeGroup attributeGroupResolved;
868                    if (attributeGroup.RedefinedAttributeGroup != null && attributeGroupRef.RefName == new XmlQualifiedName(attributeGroup.Name, attributeGroupRef.RefName.Namespace)) {
869                        attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroup.RedefinedAttributeGroup;
870                    }
871                    else {
872                        attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroups[attributeGroupRef.RefName];
873                    }
874                    if (attributeGroupResolved != null) {
875                        HandleAttributeGroup(attributeGroupResolved, table, isBase);
876                    }
877                }
878            }
879        }
880         internal void HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren,  bool isNillable){
881             if (complexTypes.Contains(ct))
882                 throw ExceptionBuilder.CircularComplexType(ct.Name);
883             bool isBase = false;
884             complexTypes.Add(ct);
885
886
887             if (ct.ContentModel != null) {
888                 /*
889                 HandleParticle(ct.CompiledParticle, table, tableChildren, isBase);
890                 foreach (XmlSchemaAttribute s in ct.Attributes){
891                     HandleAttributeColumn(s, table, isBase);
892                 }
893                 */
894
895                 
896                 if (ct.ContentModel is XmlSchemaComplexContent) {
897                     XmlSchemaAnnotated cContent = ((XmlSchemaComplexContent) (ct.ContentModel)).Content;
898                     if (cContent is XmlSchemaComplexContentExtension) {
899                         XmlSchemaComplexContentExtension ccExtension = ((XmlSchemaComplexContentExtension) cContent );
900                         if (!(ct.BaseXmlSchemaType is XmlSchemaComplexType && this.FromInference))
901                             HandleAttributes(ccExtension.Attributes, table, isBase);
902
903                         if (ct.BaseXmlSchemaType is XmlSchemaComplexType) {
904                             HandleComplexType((XmlSchemaComplexType)ct.BaseXmlSchemaType, table, tableChildren, isNillable);
905                         }
906                         else {
907                             Debug.Assert(ct.BaseXmlSchemaType is XmlSchemaSimpleType,  "Expected SimpleType or ComplexType");
908                             if (ccExtension.BaseTypeName.Namespace != Keywords.XSDNS){ 
909                                 // this is UDSimpleType, pass Qualified name of type
910                                 HandleSimpleContentColumn(ccExtension.BaseTypeName.ToString(), table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
911                             }
912                             else { // it is built in type
913                                 HandleSimpleContentColumn(ccExtension.BaseTypeName.Name, table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
914                             }
915                         }
916                         if (ccExtension.Particle != null)
917                             HandleParticle(ccExtension.Particle, table, tableChildren, isBase);
918                         if (ct.BaseXmlSchemaType is XmlSchemaComplexType && this.FromInference)
919                             HandleAttributes(ccExtension.Attributes, table, isBase);
920                     } else {
921                         Debug.Assert(cContent is XmlSchemaComplexContentRestriction, "Expected complexContent extension or restriction");
922                         XmlSchemaComplexContentRestriction ccRestriction = ((XmlSchemaComplexContentRestriction) cContent );
923                             if (!this.FromInference)
924                         HandleAttributes(ccRestriction.Attributes, table, isBase);
925                         if (ccRestriction.Particle != null)
926                             HandleParticle(ccRestriction.Particle, table, tableChildren, isBase);
927                         if (this.FromInference)
928                             HandleAttributes(ccRestriction.Attributes, table, isBase);
929                     }
930                 } else {
931                     Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent");
932                     XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent) (ct.ContentModel)).Content;
933                     if (cContent is XmlSchemaSimpleContentExtension) {
934                         XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension) cContent );
935                             HandleAttributes(ccExtension.Attributes, table, isBase);
936                         if (ct.BaseXmlSchemaType is XmlSchemaComplexType) {
937                             HandleComplexType((XmlSchemaComplexType)ct.BaseXmlSchemaType, table, tableChildren, isNillable);
938                         } 
939                         else {
940                             Debug.Assert(ct.BaseXmlSchemaType is XmlSchemaSimpleType,  "Expected SimpleType or ComplexType");
941                             HandleSimpleTypeSimpleContentColumn((XmlSchemaSimpleType)ct.BaseXmlSchemaType, ccExtension.BaseTypeName.Name, table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
942                         }
943                     } else {
944                         Debug.Assert(cContent is XmlSchemaSimpleContentRestriction, "Expected SimpleContent extension or restriction");
945                         XmlSchemaSimpleContentRestriction ccRestriction = ((XmlSchemaSimpleContentRestriction) cContent );
946                         HandleAttributes(ccRestriction.Attributes, table, isBase);
947                     }
948
949                 }
950
951             }
952             else {
953                 isBase = true;
954                 if (!this.FromInference)
955                     HandleAttributes(ct.Attributes, table, isBase);
956                 if (ct.Particle != null)
957                     HandleParticle(ct.Particle, table, tableChildren, isBase);
958                 if (this.FromInference) {
959                     HandleAttributes(ct.Attributes, table, isBase);
960                     if (isNillable) // this is for backward compatability to support xsi:Nill=true
961                         HandleSimpleContentColumn("string", table, isBase, null, isNillable);
962                 }
963             }
964
965             complexTypes.Remove(ct);
966         }       
967
968         internal XmlSchemaParticle GetParticle(XmlSchemaComplexType ct){
969             if (ct.ContentModel != null) {
970                 if (ct.ContentModel is XmlSchemaComplexContent) {
971                     XmlSchemaAnnotated cContent = ((XmlSchemaComplexContent) (ct.ContentModel)).Content;
972                     if (cContent is XmlSchemaComplexContentExtension) {
973                         return ((XmlSchemaComplexContentExtension) cContent ).Particle;
974                     } else {
975                         Debug.Assert(cContent is XmlSchemaComplexContentRestriction, "Expected complexContent extension or restriction");
976                         return ((XmlSchemaComplexContentRestriction) cContent ).Particle;
977                     }
978                 } else {
979                     Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent");
980                     return null;
981
982                 }
983  
984             }
985             else {
986                 return ct.Particle;
987             }
988
989         }
990
991         internal DataColumn FindField(DataTable table, string field) {
992             bool attribute = false;
993             String colName = field;
994  
995             if (field.StartsWith("@", StringComparison.Ordinal)) {
996                 attribute = true;
997                 colName = field.Substring(1);
998             }
999
1000             String [] split = colName.Split(':');
1001             colName = split [split.Length - 1];
1002
1003             colName = XmlConvert.DecodeName(colName);
1004             DataColumn col = table.Columns[colName];
1005             if (col == null )
1006                 throw ExceptionBuilder.InvalidField(field);
1007
1008             bool _attribute = (col.ColumnMapping == MappingType.Attribute) || (col.ColumnMapping == MappingType.Hidden);
1009     
1010             if  (_attribute != attribute)
1011                 throw ExceptionBuilder.InvalidField(field);
1012                 
1013             return col;
1014         }
1015
1016         internal DataColumn[] BuildKey(XmlSchemaIdentityConstraint keyNode, DataTable table){
1017             ArrayList keyColumns = new ArrayList();
1018          
1019             foreach (XmlSchemaXPath node in keyNode.Fields) {
1020                 keyColumns.Add(FindField(table, node.XPath));
1021             }
1022          
1023             DataColumn [] key = new DataColumn[keyColumns.Count];
1024             keyColumns.CopyTo(key, 0);
1025           
1026             return key;
1027         } 
1028           
1029         internal bool GetBooleanAttribute(XmlSchemaAnnotated element, String attrName, bool defVal) {
1030             string value = GetMsdataAttribute(element, attrName);
1031             if (value == null || value.Length == 0) {
1032                 return defVal;
1033             }
1034             if ((value == Keywords.TRUE) || (value == Keywords.ONE_DIGIT)){
1035                 return true;
1036             }
1037             if ((value == Keywords.FALSE) || (value == Keywords.ZERO_DIGIT)){
1038                 return false;
1039             }            
1040             // Error processing:
1041             throw ExceptionBuilder.InvalidAttributeValue(attrName, value);
1042         }
1043
1044         internal String GetStringAttribute(XmlSchemaAnnotated element, String attrName, String defVal) {
1045             string value = GetMsdataAttribute(element, attrName);
1046             if (value == null || value.Length == 0) {
1047                 return defVal;
1048             }
1049             return value;
1050         }
1051                     
1052         /*
1053         <key name="fk">
1054             <selector>../Customers</selector>
1055             <field>ID</field>
1056         </key>
1057         <keyref refer="fk">
1058             <selector>.</selector>
1059             <field>CustID</field>
1060         </keyref>
1061         */
1062
1063         internal static AcceptRejectRule TranslateAcceptRejectRule( string strRule ) {
1064             if (strRule == "Cascade")
1065                 return AcceptRejectRule.Cascade;
1066             else if (strRule == "None")
1067                 return AcceptRejectRule.None;
1068             else
1069                 return ForeignKeyConstraint.AcceptRejectRule_Default;
1070         }
1071
1072         internal static Rule TranslateRule( string strRule ) {
1073             if (strRule == "Cascade")
1074                 return Rule.Cascade;
1075             else if (strRule == "None")
1076                 return Rule.None;
1077             else if (strRule == "SetDefault")
1078                 return Rule.SetDefault;
1079             else if (strRule == "SetNull")
1080                 return Rule.SetNull;
1081             else
1082                 return ForeignKeyConstraint.Rule_Default;
1083         }
1084
1085         internal void HandleKeyref(XmlSchemaKeyref keyref) {
1086             string refer = XmlConvert.DecodeName(keyref.Refer.Name); // check here!!!
1087             string name = XmlConvert.DecodeName(keyref.Name);
1088             name = GetStringAttribute( keyref, "ConstraintName", /*default:*/ name);
1089             
1090             // we do not process key defined outside the current node
1091             
1092             String tableName = GetTableName(keyref);
1093
1094             string tableNs = GetMsdataAttribute(keyref,Keywords.MSD_TABLENS);
1095             
1096             DataTable table =  _ds.Tables.GetTableSmart(tableName,tableNs);
1097             
1098             if (table == null)
1099                 return;
1100
1101             if (refer == null || refer.Length == 0)
1102                 throw ExceptionBuilder.MissingRefer(name);
1103             
1104             ConstraintTable key = (ConstraintTable) ConstraintNodes[refer];
1105
1106             if (key == null) {
1107                 throw ExceptionBuilder.InvalidKey(name);
1108             }
1109
1110             DataColumn[] pKey = BuildKey(key.constraint, key.table);
1111             DataColumn[] fKey = BuildKey(keyref, table);
1112
1113             ForeignKeyConstraint fkc = null;
1114
1115             if (GetBooleanAttribute(keyref, Keywords.MSD_CONSTRAINTONLY,  /*default:*/ false)) {
1116                 int iExisting = fKey[0].Table.Constraints.InternalIndexOf(name);
1117                 if (iExisting > -1) {
1118                     if (fKey[0].Table.Constraints[iExisting].ConstraintName != name)
1119                         iExisting = -1;
1120                 }
1121        
1122                 if (iExisting < 0) {
1123                     fkc = new ForeignKeyConstraint( name, pKey, fKey );
1124                     fKey[0].Table.Constraints.Add(fkc);
1125                 }
1126             }
1127             else {
1128                 string relName = XmlConvert.DecodeName(GetStringAttribute( keyref, Keywords.MSD_RELATIONNAME, keyref.Name));
1129
1130                 if (relName == null || relName.Length == 0)
1131                     relName = name;
1132
1133                 int iExisting = fKey[0].Table.DataSet.Relations.InternalIndexOf(relName);
1134                 if (iExisting > -1) {
1135                     if (fKey[0].Table.DataSet.Relations[iExisting].RelationName != relName)
1136                         iExisting = -1;
1137                 }
1138                 DataRelation relation = null;
1139                 if (iExisting < 0) {
1140                     relation = new DataRelation(relName, pKey, fKey);
1141                     SetExtProperties(relation, keyref.UnhandledAttributes);
1142                     pKey[0].Table.DataSet.Relations.Add(relation);
1143
1144                     if (FromInference && relation.Nested) {
1145                         if (tableDictionary.ContainsKey(relation.ParentTable)) {
1146                             tableDictionary[relation.ParentTable].Add(relation.ChildTable);
1147                         }
1148                     }
1149                     
1150                     fkc = relation.ChildKeyConstraint;
1151                     fkc.ConstraintName = name;
1152                 } 
1153                 else {
1154                     relation = fKey[0].Table.DataSet.Relations[iExisting];
1155                 }
1156                 if (GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED,  /*default:*/ false)) {
1157                     relation.Nested = true;
1158                 }
1159
1160             }
1161
1162             string acceptRejectRule = GetMsdataAttribute(keyref, Keywords.MSD_ACCEPTREJECTRULE);
1163             string updateRule       = GetMsdataAttribute(keyref, Keywords.MSD_UPDATERULE);
1164             string deleteRule       = GetMsdataAttribute(keyref, Keywords.MSD_DELETERULE);
1165
1166             if (fkc != null) {
1167                 if (acceptRejectRule != null)
1168                     fkc.AcceptRejectRule = TranslateAcceptRejectRule(acceptRejectRule);
1169
1170                 if (updateRule != null)
1171                     fkc.UpdateRule = TranslateRule(updateRule);
1172
1173                 if (deleteRule != null)
1174                     fkc.DeleteRule = TranslateRule(deleteRule);
1175
1176                 SetExtProperties(fkc, keyref.UnhandledAttributes);
1177             }
1178         }
1179
1180
1181         internal void HandleConstraint(XmlSchemaIdentityConstraint keyNode){
1182             String name = null;
1183             
1184             name = XmlConvert.DecodeName(keyNode.Name);
1185             if (name==null || name.Length==0)
1186                 throw ExceptionBuilder.MissingAttribute(Keywords.NAME);
1187
1188             if (ConstraintNodes.ContainsKey(name))
1189                 throw ExceptionBuilder.DuplicateConstraintRead(name);
1190
1191             // we do not process key defined outside the current node
1192             String tableName = GetTableName(keyNode);
1193             string tableNs = GetMsdataAttribute(keyNode,Keywords.MSD_TABLENS);
1194             
1195             DataTable table =  _ds.Tables.GetTableSmart(tableName,tableNs);
1196
1197             if (table == null)
1198                 return;
1199
1200             ConstraintNodes.Add(name, new ConstraintTable(table, keyNode));
1201
1202             bool   fPrimaryKey = GetBooleanAttribute(keyNode, Keywords.MSD_PRIMARYKEY,  /*default:*/ false);
1203             name        = GetStringAttribute(keyNode, "ConstraintName", /*default:*/ name);
1204
1205
1206
1207             DataColumn[] key = BuildKey(keyNode, table);
1208
1209             if (0 < key.Length) {
1210                 UniqueConstraint found = (UniqueConstraint) key[0].Table.Constraints.FindConstraint(new UniqueConstraint(name, key));
1211
1212                 if (found == null) {
1213                     key[0].Table.Constraints.Add(name, key, fPrimaryKey);
1214                     SetExtProperties(key[0].Table.Constraints[name], keyNode.UnhandledAttributes);
1215                 }
1216                 else {
1217                         key = found.ColumnsReference;
1218                         SetExtProperties(found, keyNode.UnhandledAttributes);
1219                         if (fPrimaryKey)
1220                             key[0].Table.PrimaryKey = key;
1221                     }
1222                 if (keyNode is XmlSchemaKey) {
1223                     for (int i=0; i<key.Length; i++)
1224                         key[i].AllowDBNull = false;
1225                 }
1226             }
1227         }
1228
1229         internal DataTable InstantiateSimpleTable(XmlSchemaElement node) {
1230             DataTable table;
1231             String typeName = XmlConvert.DecodeName(GetInstanceName(node));
1232             String _TableUri;
1233             
1234             _TableUri = node.QualifiedName.Namespace;
1235             table = _ds.Tables.GetTable(typeName, _TableUri);
1236
1237 // 
1238
1239
1240
1241 /*            if (table!=null) {
1242                 throw ExceptionBuilder.DuplicateDeclaration(typeName);
1243             }
1244 */
1245             if (!FromInference && table!=null) {
1246                 throw ExceptionBuilder.DuplicateDeclaration(typeName);
1247             }
1248
1249
1250             if (table == null) {
1251                 table = new DataTable( typeName);
1252                 table.Namespace = _TableUri;
1253                 // If msdata:targetNamespace node on element, then use it to override table.Namespace.
1254                 table.Namespace = GetStringAttribute(node, "targetNamespace", _TableUri);
1255                 
1256                 if (!this.FromInference) {
1257                     table.MinOccurs = node.MinOccurs;
1258                     table.MaxOccurs = node.MaxOccurs;
1259                 }
1260                 else {
1261                     string prefix = GetPrefix(_TableUri);
1262                     if (prefix != null)
1263                         table.Prefix = prefix;
1264                 }
1265
1266                 SetProperties(table, node.UnhandledAttributes);
1267                 SetExtProperties(table, node.UnhandledAttributes);
1268             }
1269
1270
1271              XmlSchemaComplexType ct = node.SchemaType as XmlSchemaComplexType;
1272              // We assume node.ElementSchemaType.BaseSchemaType to be null for 
1273              //  <xs:element name="foo"/> and not null for <xs:element name="foo" type="xs:string"/>
1274              bool isSimpleContent = ((node.ElementSchemaType.BaseXmlSchemaType != null) ||(ct != null && ct.ContentModel is XmlSchemaSimpleContent)); 
1275
1276              if (!FromInference ||(isSimpleContent && table.Columns.Count == 0 )) {// for inference backward compatability
1277                  HandleElementColumn(node, table, false);
1278                  string colName;
1279                  
1280                  if (this.FromInference) {
1281                      int i = 0;
1282                      colName = typeName + "_Text";
1283                      while (table.Columns[colName] != null)
1284                          colName = colName + i++;
1285                  }
1286                  else {
1287                      colName = typeName + "_Column";
1288                  }
1289
1290                  table.Columns[0].ColumnName = colName;
1291                  table.Columns[0].ColumnMapping = MappingType.SimpleContent;
1292              }
1293              
1294              if (!this.FromInference ||_ds.Tables.GetTable(typeName, _TableUri) == null) { // for inference; special case: add table if doesnot exists in collection
1295                 _ds.Tables.Add(table);
1296                 if (this.FromInference) {
1297                     tableDictionary.Add(table, new List<DataTable>());
1298                 }
1299              }
1300
1301             // handle all the unique and key constraints related to this table
1302
1303             if ((dsElement != null) && (dsElement.Constraints!=null)) {
1304                 foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
1305                     if (key is XmlSchemaKeyref) 
1306                         continue;
1307                     if (GetTableName(key) == table.TableName)
1308                         HandleConstraint(key);
1309                 }
1310             }
1311             table.fNestedInDataset = false;
1312
1313             return (table);
1314         }
1315
1316
1317         internal string GetInstanceName(XmlSchemaAnnotated node) {
1318             string  instanceName = null;
1319
1320             Debug.Assert( (node is XmlSchemaElement) || (node is XmlSchemaAttribute), "GetInstanceName should only be called on attribute or elements");
1321
1322             if (node is XmlSchemaElement) {
1323                 XmlSchemaElement el = (XmlSchemaElement) node;
1324                 instanceName = el.Name != null ? el.Name : el.RefName.Name;
1325             }
1326             else if (node is XmlSchemaAttribute) {
1327                 XmlSchemaAttribute el = (XmlSchemaAttribute) node;
1328                 instanceName = el.Name != null ? el.Name : el.RefName.Name;
1329             }
1330
1331             Debug.Assert((instanceName != null) && (instanceName.Length != 0), "instanceName cannot be null or empty. There's an error in the XSD compiler");
1332
1333             return instanceName;
1334         }
1335
1336         // Sequences of handling Elements, Attributes and Text-only column should be the same as in InferXmlSchema
1337         internal DataTable InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, bool isRef) {
1338             DataTable table;
1339             String typeName = GetInstanceName(node);
1340             ArrayList tableChildren = new ArrayList();
1341             
1342             String _TableUri;
1343             
1344             _TableUri = node.QualifiedName.Namespace;
1345
1346             table = _ds.Tables.GetTable(XmlConvert.DecodeName(typeName), _TableUri);
1347 // TOD: Do not do this fix
1348 //            if (table == null && node.RefName.IsEmpty && !IsTopLevelElement(node) && _TableUri != null && _TableUri.Length > 0) { 
1349 //                _TableUri = null;    // it means form="qualified", so child element inherits namespace. [....]
1350 //            }
1351             
1352             if (!FromInference || (FromInference && table == null)) 
1353             {
1354                 if (table!=null) 
1355                 {
1356                     if (isRef)
1357                         return table;
1358                     else
1359                         throw ExceptionBuilder.DuplicateDeclaration(typeName);
1360                 }
1361                 
1362                 if (isRef)
1363                     RefTables.Add(_TableUri+":"+typeName);
1364
1365                 table = new DataTable(XmlConvert.DecodeName(typeName) );
1366                 table.TypeName = node.SchemaTypeName;
1367
1368                 table.Namespace = _TableUri;
1369                 table.Namespace = GetStringAttribute(node, "targetNamespace", _TableUri);
1370
1371                 //table.Prefix = node.Prefix;
1372                 String value= GetStringAttribute(typeNode, Keywords.MSD_CASESENSITIVE,  "") ;
1373                 if (value.Length ==0)
1374                 {
1375                     value= GetStringAttribute(node, Keywords.MSD_CASESENSITIVE,  "") ;
1376                 }
1377                 if (0 < value.Length) {
1378                     if ((value == Keywords.TRUE) || (value == "True"))
1379                         table.CaseSensitive = true;                
1380                     if ((value == Keywords.FALSE) || (value == "False"))
1381                         table.CaseSensitive = false;                
1382                 }
1383
1384                 value = GetMsdataAttribute(node, Keywords.MSD_LOCALE);
1385                 if (null != value) { // set by user
1386                     if (0 < value.Length) {
1387                         // <... msdata:Locale="en-US"/>
1388                         table.Locale = new CultureInfo(value);
1389                     }
1390                     else {
1391                         // everett bug behavior before <... msdata:Locale=""/> inherit from DataSet
1392                         table.Locale = CultureInfo.InvariantCulture;
1393                     }
1394                 }
1395                 
1396                 // else inherit from DataSet, not set by user
1397                 
1398                 if (!this.FromInference) 
1399                 {
1400                     table.MinOccurs = node.MinOccurs;
1401                     table.MaxOccurs = node.MaxOccurs;
1402                 } 
1403                 else 
1404                 {
1405                     string prefix = GetPrefix(_TableUri);
1406                     if (prefix != null)
1407                         table.Prefix = prefix;
1408                 }
1409
1410                 _ds.Tables.Add(table);
1411                 if (FromInference) {
1412                     tableDictionary.Add(table, new List<DataTable>());
1413                 }
1414             }
1415          
1416             HandleComplexType(typeNode, table, tableChildren, node.IsNillable);
1417
1418             for (int i=0; i < table.Columns.Count ; i++)
1419                 table.Columns[i].SetOrdinalInternal(i);
1420
1421 /*
1422             if (xmlContent == XmlContent.Mixed) {
1423                 string textColumn = GenUniqueColumnName(table.TableName+ "_Text", table);
1424                 table.XmlText = new DataColumn(textColumn, typeof(string), null, MappingType.Text);
1425             } */
1426
1427             SetProperties(table, node.UnhandledAttributes);
1428             SetExtProperties(table, node.UnhandledAttributes);
1429
1430             // handle all the unique and key constraints related to this table
1431             if ((dsElement != null) && (dsElement.Constraints!=null)) {
1432                 foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
1433                     if (key is XmlSchemaKeyref) 
1434                         continue;
1435                     if (GetTableName(key) == table.TableName) {
1436                         // respect the NS if it is specified for key, otherwise just go with table name check
1437                         if( GetTableNamespace(key) == table.Namespace || GetTableNamespace(key) == null)
1438                             HandleConstraint(key);
1439 /*                     if (GetTableNamespace(key) != null) {
1440                             if (GetTableNamespace(key) == table.Namespace)
1441                                 HandleConstraint(key);
1442                         }
1443                         else {
1444                             HandleConstraint(key);
1445                         }
1446 */
1447                     }
1448                 }
1449             }
1450
1451             foreach(DataTable _tableChild in tableChildren) {
1452                 if (_tableChild != table && table.Namespace == _tableChild.Namespace)
1453                     _tableChild.tableNamespace = null;
1454
1455                 if ((dsElement != null) && (dsElement.Constraints!=null)) {
1456                     foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
1457                         XmlSchemaKeyref keyref = key as XmlSchemaKeyref;
1458                         if (keyref == null)
1459                             continue;
1460
1461                         bool isNested = GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED,  /*default:*/ false);                                
1462                         if (!isNested)
1463                             continue;
1464                         if (GetTableName(keyref) == _tableChild.TableName) {
1465                             if (_tableChild.DataSet.Tables.InternalIndexOf(_tableChild.TableName) < -1) { // if we have multiple tables with the same name
1466                                 if (GetTableNamespace(keyref) == _tableChild.Namespace) {
1467                                     HandleKeyref(keyref);
1468                                 }
1469                             }
1470                             else {
1471                                 HandleKeyref(keyref);
1472                             }
1473                         }
1474                     }
1475                 } 
1476
1477                 DataRelation relation = null;
1478
1479                 DataRelationCollection childRelations = table.ChildRelations;
1480                 for (int j = 0; j < childRelations.Count; j++) {
1481                     if (!childRelations[j].Nested)
1482                         continue;
1483
1484                     if (_tableChild == childRelations[j].ChildTable)
1485                         relation = childRelations[j];
1486                 }
1487
1488                 if (relation!=null)
1489                     continue;
1490
1491                 DataColumn parentKey;
1492                 if (this.FromInference) {
1493                     int position = table.UKColumnPositionForInference;// we keep posiotion of unique key column here, for inference
1494                     if (position == -1)
1495                         foreach (DataColumn dc in table.Columns) {
1496                         if (dc.ColumnMapping == MappingType.Attribute) {
1497                             position = dc.Ordinal;
1498                             break;
1499                         }
1500                     }
1501                     parentKey = table.AddUniqueKey(position);
1502
1503                 }
1504                 else {
1505                     parentKey = table.AddUniqueKey();
1506                 }
1507
1508                 // foreign key in the child table
1509                 DataColumn childKey = _tableChild.AddForeignKey(parentKey);
1510
1511                 // when we add  unique key, we do set prefix; but for Fk we do not do . So for backward compatability
1512                 if (this.FromInference)
1513                     childKey.Prefix = _tableChild.Prefix;
1514 //                    childKey.Prefix = GetPrefix(childKey.Namespace);
1515
1516                 // create relationship
1517                 // setup relationship between parent and this table
1518                 relation = new DataRelation(table.TableName + "_" + _tableChild.TableName, parentKey, childKey, true);
1519                 relation.Nested = true;
1520                 _tableChild.DataSet.Relations.Add(relation);
1521                 if (FromInference && relation.Nested) {
1522                     if (tableDictionary.ContainsKey(relation.ParentTable)) {
1523                         tableDictionary[relation.ParentTable].Add(relation.ChildTable);
1524                     }                   
1525                 }
1526             }
1527
1528             return (table);
1529         }
1530
1531         private sealed class NameType : IComparable {
1532             public readonly String   name;
1533             public readonly Type     type;
1534             public NameType(String n, Type t) { 
1535                 name = n;
1536                 type = t;
1537             }
1538             public int CompareTo(object obj) { return String.Compare(name, (string)obj, StringComparison.Ordinal); }
1539         };
1540
1541         public static Type XsdtoClr(string xsdTypeName) {
1542 #if DEBUG
1543             for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
1544                 Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
1545             }
1546 #endif
1547             int index = Array.BinarySearch(mapNameTypeXsd, xsdTypeName);
1548             if (index < 0) {
1549                 throw ExceptionBuilder.UndefinedDatatype(xsdTypeName);
1550             }
1551             return mapNameTypeXsd[index].type;
1552         }
1553         
1554         // XSD spec: http://www.w3.org/TR/xmlschema-2/
1555         //    April: http://www.w3.org/TR/2000/WD-xmlschema-2-20000407/datatypes.html
1556         //    Fabr:  http://www.w3.org/TR/2000/WD-xmlschema-2-20000225/
1557         private static readonly NameType[] mapNameTypeXsd = {
1558             new NameType("ENTITIES"            , typeof(string)  ), /* XSD Apr */
1559             new NameType("ENTITY"              , typeof(string)  ), /* XSD Apr */
1560             new NameType("ID"                  , typeof(string)  ), /* XSD Apr */
1561             new NameType("IDREF"               , typeof(string)  ), /* XSD Apr */
1562             new NameType("IDREFS"              , typeof(string)  ), /* XSD Apr */
1563             new NameType("NCName"              , typeof(string)  ), /* XSD Apr */
1564             new NameType("NMTOKEN"             , typeof(string)  ), /* XSD Apr */
1565             new NameType("NMTOKENS"            , typeof(string)  ), /* XSD Apr */
1566             new NameType("NOTATION"            , typeof(string)  ), /* XSD Apr */
1567             new NameType("Name"                , typeof(string)  ), /* XSD Apr */
1568             new NameType("QName"               , typeof(string)  ), /* XSD Apr */
1569
1570             new NameType("anyType"             , typeof(System.Object)  ), /* XSD Apr */
1571             new NameType("anyURI"              , typeof(System.Uri)  ), /* XSD Apr */
1572             new NameType("base64Binary"        , typeof(Byte[])  ), /* XSD Apr : abstruct */
1573             new NameType("boolean"             , typeof(bool)    ), /* XSD Apr */
1574             new NameType("byte"                , typeof(SByte)   ), /* XSD Apr */
1575             new NameType("date"                , typeof(DateTime)), /* XSD Apr */
1576             new NameType("dateTime"            , typeof(DateTime)), /* XSD Apr */
1577             new NameType("decimal"              , typeof(decimal) ), /* XSD 2001 [....] */
1578             new NameType("double"              , typeof(double)  ), /* XSD Apr */
1579             new NameType("duration"            , typeof(TimeSpan)), /* XSD Apr */
1580             new NameType("float"               , typeof(Single)  ), /* XSD Apr */
1581             new NameType("gDay"                , typeof(DateTime)), /* XSD Apr */
1582             new NameType("gMonth"              , typeof(DateTime)), /* XSD Apr */
1583             new NameType("gMonthDay"           , typeof(DateTime)), /* XSD Apr */
1584             new NameType("gYear"               , typeof(DateTime)), /* XSD Apr */
1585             new NameType("gYearMonth"          , typeof(DateTime)), /* XSD Apr */
1586             new NameType("hexBinary"           , typeof(Byte[])  ), /* XSD Apr : abstruct */
1587             new NameType("int"                 , typeof(Int32)   ), /* XSD Apr */
1588             new NameType("integer"             , typeof(Int64)   ), /* XSD Apr */ // <xs:element name="" msdata:DataType="System.Numerics.BigInteger" type="xs:integer" minOccurs="0" />
1589             new NameType("language"            , typeof(string)  ), /* XSD Apr */
1590             new NameType("long"                , typeof(Int64)   ), /* XSD Apr */
1591             new NameType("negativeInteger"     , typeof(Int64)   ), /* XSD Apr */
1592             new NameType("nonNegativeInteger"  , typeof(UInt64)  ), /* XSD Apr */
1593             new NameType("nonPositiveInteger"  , typeof(Int64)   ), /* XSD Apr */
1594             new NameType("normalizedString"    , typeof(string)  ), /* XSD Apr */
1595             new NameType("positiveInteger"     , typeof(UInt64)  ), /* XSD Apr */
1596             new NameType("short"               , typeof(Int16)   ), /* XSD Apr */
1597             new NameType("string"              , typeof(string)  ), /* XSD Apr */
1598             new NameType("time"                , typeof(DateTime)), /* XSD Apr */
1599             new NameType("unsignedByte"        , typeof(Byte)    ), /* XSD Apr */
1600             new NameType("unsignedInt"         , typeof(UInt32)  ), /* XSD Apr */
1601             new NameType("unsignedLong"        , typeof(UInt64)  ), /* XSD Apr */
1602             new NameType("unsignedShort"       , typeof(UInt16)  ), /* XSD Apr */
1603         };
1604
1605         private static NameType FindNameType(string name) {
1606 #if DEBUG
1607             for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
1608                 Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
1609             }
1610 #endif
1611             int index = Array.BinarySearch(mapNameTypeXsd, name);
1612             if (index < 0) {
1613                 throw ExceptionBuilder.UndefinedDatatype(name);
1614             }
1615             return mapNameTypeXsd[index];
1616         }
1617
1618         // input param dt is a "qName" for UDSimpleType else it assumes it's a XSD builtin simpleType
1619         private Type ParseDataType(string dt) {
1620             if (!IsXsdType(dt)) {
1621                 if (udSimpleTypes != null) {
1622                     XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType) udSimpleTypes[dt];
1623                     if (simpleType == null) { // it is not named simple type, it is not  XSD type, it should be unsupported type like xs:token
1624                         throw ExceptionBuilder.UndefinedDatatype(dt);
1625                     }
1626                     SimpleType rootType = new SimpleType(simpleType);
1627                     while (rootType.BaseSimpleType != null) {
1628                         rootType = rootType.BaseSimpleType;
1629                     }
1630
1631                     return ParseDataType(rootType.BaseType);
1632                 }
1633             }
1634             NameType nt = FindNameType(dt);
1635             return nt.type;
1636         }
1637 /*  later we may need such a function
1638         private Boolean IsUDSimpleType(string qname) {
1639             if (udSimpleTypes == null)
1640                 return false;
1641             return (udSimpleTypes.Contains(qname));
1642         }
1643 */
1644         internal static Boolean IsXsdType(string name) {
1645 #if DEBUG
1646             for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
1647                 Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
1648             }
1649 #endif
1650             int index = Array.BinarySearch(mapNameTypeXsd, name);
1651             if (index < 0) {
1652 #if DEBUG
1653                 // Let's check that we realy don't have this name:
1654                 foreach (NameType nt in mapNameTypeXsd) {
1655                     Debug.Assert(nt.name != name, "FindNameType('" + name + "') -- failed. Existed name not found");
1656                 }
1657 #endif
1658                 return false;
1659             }
1660             Debug.Assert(mapNameTypeXsd[index].name == name, "FindNameType('" + name + "') -- failed. Wrong name found");
1661             return true;
1662         }
1663
1664
1665         internal XmlSchemaAnnotated FindTypeNode(XmlSchemaAnnotated node) {
1666             // this function is returning null
1667             // if the typeNode for node is in the XSD namespace.
1668             
1669             XmlSchemaAttribute attr = node as XmlSchemaAttribute;
1670             XmlSchemaElement el = node as XmlSchemaElement;
1671             bool isAttr = false;
1672             if (attr != null) {
1673                 isAttr = true;
1674             }
1675
1676             String _type = isAttr ? attr.SchemaTypeName.Name :  el.SchemaTypeName.Name;
1677             String _typeNs = isAttr ? attr.SchemaTypeName.Namespace :  el.SchemaTypeName.Namespace;
1678             if (_typeNs == Keywords.XSDNS)
1679                 return null;
1680             XmlSchemaAnnotated typeNode;
1681             if (_type == null || _type.Length == 0) {
1682                 _type = isAttr ? attr.RefName.Name :  el.RefName.Name;
1683                 if (_type == null || _type.Length == 0) 
1684                     typeNode = (XmlSchemaAnnotated) (isAttr ? attr.SchemaType :  el.SchemaType);
1685                 else 
1686                     typeNode = isAttr ? FindTypeNode((XmlSchemaAnnotated)attributes[attr.RefName]) :FindTypeNode((XmlSchemaAnnotated)elementsTable[el.RefName]);
1687             }
1688             else
1689                 typeNode = (XmlSchemaAnnotated)schemaTypes[isAttr ? ((XmlSchemaAttribute)node).SchemaTypeName :  ((XmlSchemaElement)node).SchemaTypeName];
1690             return typeNode;
1691         }
1692
1693
1694     internal void HandleSimpleTypeSimpleContentColumn(XmlSchemaSimpleType typeNode, string strType, DataTable table, bool isBase, XmlAttribute[] attrs, bool isNillable){
1695             // disallow multiple simple content columns for the table
1696             if(FromInference && table.XmlText != null) { // backward compatability for inference
1697                 return;
1698             }
1699
1700             Type type = null;        
1701             SimpleType xsdType = null;
1702             
1703 //            if (typeNode.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
1704             if (typeNode.QualifiedName.Name != null && typeNode.QualifiedName.Name.Length != 0 && typeNode.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
1705                 xsdType = new SimpleType(typeNode);
1706                 strType = typeNode.QualifiedName.ToString(); // use qualifed name
1707                 type = ParseDataType(typeNode.QualifiedName.ToString());
1708             }
1709             else {// previous code V 1.1
1710                 XmlSchemaSimpleType ancestor = typeNode.BaseXmlSchemaType as XmlSchemaSimpleType;
1711                 if ((ancestor != null) && (ancestor.QualifiedName.Namespace != Keywords.XSDNS)) { 
1712                     xsdType = new SimpleType(typeNode);
1713                     SimpleType rootType = xsdType;
1714
1715                     while (rootType.BaseSimpleType != null) {
1716                         rootType = rootType.BaseSimpleType;
1717                     }
1718                     type = ParseDataType(rootType.BaseType);
1719                     strType = xsdType.Name;
1720                 }
1721                 else {
1722                     type = ParseDataType(strType);
1723                 }
1724             }
1725
1726             
1727             DataColumn column;
1728
1729             string colName;
1730             if (this.FromInference) {
1731                 int i = 0;
1732                 colName = table.TableName + "_Text";
1733                 while (table.Columns[colName] != null) {
1734                     colName = colName + i++;
1735                 }
1736             }
1737             else
1738                 colName = table.TableName + "_text";
1739
1740             string columnName = colName;
1741             bool isToAdd = true;
1742             if ((!isBase) && (table.Columns.Contains(columnName, true))){
1743                 column = table.Columns[columnName];
1744                 isToAdd = false;
1745             }
1746             else {
1747                 column = new DataColumn(columnName, type, null, MappingType.SimpleContent);
1748             }
1749
1750             SetProperties(column, attrs);
1751             HandleColumnExpression(column, attrs);
1752             SetExtProperties(column, attrs);
1753
1754             String tmp = (-1).ToString(CultureInfo.CurrentCulture);
1755             string defValue = null;
1756             //try to see if attributes contain allownull
1757             column.AllowDBNull = isNillable;
1758
1759             if(attrs!=null)
1760                 for(int i=0; i< attrs.Length;i++) {
1761                     if ( attrs[i].LocalName == Keywords.MSD_ALLOWDBNULL &&  attrs[i].NamespaceURI == Keywords.MSDNS)
1762                         if ( attrs[i].Value == Keywords.FALSE) 
1763                             column.AllowDBNull = false;
1764                     if ( attrs[i].LocalName == Keywords.MSD_ORDINAL &&  attrs[i].NamespaceURI == Keywords.MSDNS)
1765                         tmp = attrs[i].Value;
1766                     if ( attrs[i].LocalName == Keywords.MSD_DEFAULTVALUE &&  attrs[i].NamespaceURI == Keywords.MSDNS)
1767                         defValue = attrs[i].Value;
1768                 }
1769             int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
1770
1771             
1772             //SetExtProperties(column, attr.UnhandledAttributes);
1773
1774             if ((column.Expression!=null)&&(column.Expression.Length!=0)) {
1775                 ColumnExpressions.Add(column);
1776             } 
1777
1778 // Update XSD type to point to simple types actual namespace instead of normalized default namespace in case of remoting
1779             if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0) {
1780                 if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE)!= null) {
1781                   column.XmlDataType = xsdType.SimpleTypeQualifiedName;
1782                 }
1783             }
1784             else {
1785                 column.XmlDataType = strType;
1786             }
1787             column.SimpleType = xsdType;
1788
1789             //column.Namespace = typeNode.SourceUri;
1790             if (isToAdd) {
1791                 if (this.FromInference) {
1792                     column.Prefix = GetPrefix(table.Namespace);
1793                     column.AllowDBNull = true;
1794                 }
1795                 if(ordinal>-1 && ordinal<table.Columns.Count)
1796                     table.Columns.AddAt(ordinal, column);
1797                 else
1798                     table.Columns.Add(column);
1799             }
1800
1801             if (defValue != null)
1802                 try {
1803                     column.DefaultValue = column.ConvertXmlToObject(defValue);
1804                 }
1805                 catch (System.FormatException) {
1806                     throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
1807                 }    
1808
1809
1810     }
1811
1812     internal void HandleSimpleContentColumn(String strType, DataTable table, bool isBase, XmlAttribute[] attrs, bool isNillable){
1813 // for Named Simple type support : We should not recieved anything here other than string.
1814 // there can not be typed simple content
1815             // disallow multiple simple content columns for the table
1816             if(this.FromInference && table.XmlText != null) // backward compatability for inference
1817              return;
1818             
1819             Type type = null;            
1820             if (strType == null) {
1821                 return;
1822             }
1823             type = ParseDataType(strType); // we pass it correctly when we call the method, no need to special check. 
1824             DataColumn column;
1825
1826
1827             string colName;
1828             if (this.FromInference) {
1829                 int i = 0;
1830                 colName = table.TableName + "_Text";
1831                 while (table.Columns[colName] != null) {
1832                     colName = colName + i++;
1833                 }
1834             }
1835             else
1836                 colName = table.TableName + "_text";
1837
1838             string columnName = colName;
1839             bool isToAdd = true;
1840
1841             if ((!isBase) && (table.Columns.Contains(columnName, true))){
1842                 column = table.Columns[columnName];
1843                 isToAdd = false;
1844             }
1845             else {
1846                 column = new DataColumn(columnName, type, null, MappingType.SimpleContent);
1847             }
1848             
1849             SetProperties(column, attrs);
1850             HandleColumnExpression(column, attrs);
1851             SetExtProperties(column, attrs);
1852
1853             String tmp = (-1).ToString(CultureInfo.CurrentCulture);
1854             string defValue = null;
1855             //try to see if attributes contain allownull
1856             column.AllowDBNull = isNillable;
1857
1858             if(attrs!=null)
1859                 for(int i=0; i< attrs.Length;i++) {
1860                     if ( attrs[i].LocalName == Keywords.MSD_ALLOWDBNULL &&  attrs[i].NamespaceURI == Keywords.MSDNS)
1861                         if ( attrs[i].Value == Keywords.FALSE) 
1862                             column.AllowDBNull = false;
1863                     if ( attrs[i].LocalName == Keywords.MSD_ORDINAL &&  attrs[i].NamespaceURI == Keywords.MSDNS)
1864                         tmp = attrs[i].Value;
1865                     if ( attrs[i].LocalName == Keywords.MSD_DEFAULTVALUE &&  attrs[i].NamespaceURI == Keywords.MSDNS)
1866                         defValue = attrs[i].Value;
1867                 }
1868             int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
1869
1870             
1871             //SetExtProperties(column, attr.UnhandledAttributes);
1872
1873             if ((column.Expression!=null)&&(column.Expression.Length!=0)) {
1874                 ColumnExpressions.Add(column);
1875             } 
1876
1877             column.XmlDataType = strType;
1878             column.SimpleType = null;
1879
1880             //column.Namespace = typeNode.SourceUri;
1881          if(this.FromInference)
1882              column.Prefix = GetPrefix(column.Namespace);
1883             if (isToAdd) {
1884                 if (this.FromInference) // move this setting to SetProperties
1885                     column.AllowDBNull = true;
1886                 if(ordinal>-1 && ordinal<table.Columns.Count)
1887                     table.Columns.AddAt(ordinal, column);
1888                 else
1889                     table.Columns.Add(column);
1890             }
1891
1892             if (defValue != null)
1893                 try {
1894                     column.DefaultValue = column.ConvertXmlToObject(defValue);
1895                 }
1896                 catch (System.FormatException) {
1897                     throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
1898                 }    
1899
1900
1901         }
1902
1903         internal void HandleAttributeColumn(XmlSchemaAttribute attrib, DataTable table, bool isBase){
1904             Type type = null;
1905             XmlSchemaAttribute attr = attrib.Name != null ? attrib : (XmlSchemaAttribute) attributes[attrib.RefName];
1906
1907
1908             XmlSchemaAnnotated typeNode = FindTypeNode(attr);
1909             String strType = null;
1910             SimpleType xsdType = null;
1911
1912             if (typeNode == null) {
1913                 strType = attr.SchemaTypeName.Name;
1914                 if (Common.ADP.IsEmpty(strType)) {
1915                     strType = "";
1916                     type = typeof(string);
1917                 }
1918                 else {
1919                     if (attr.SchemaTypeName.Namespace != Keywords.XSDNS) // it is UD Simple Type, can it be?
1920 //
1921                         type = ParseDataType(attr.SchemaTypeName.ToString());
1922                     else
1923                         type = ParseDataType(attr.SchemaTypeName.Name);
1924                 }
1925             }
1926             else if (typeNode is XmlSchemaSimpleType) {
1927                 // 
1928                 XmlSchemaSimpleType node = typeNode as XmlSchemaSimpleType;
1929                 xsdType = new SimpleType(node);
1930                 if (node.QualifiedName.Name != null && node.QualifiedName.Name.Length != 0 && node.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
1931                     strType = node.QualifiedName.ToString(); // use qualifed name
1932                     type = ParseDataType(node.QualifiedName.ToString());// search with QName
1933                 }
1934                 else {
1935                     type = ParseDataType(xsdType.BaseType);
1936                     strType = xsdType.Name;
1937                     if(xsdType.Length == 1 && type == typeof(string)) {
1938                         type = typeof(Char);
1939                     }
1940                 }
1941             }
1942             else if (typeNode is XmlSchemaElement) {
1943                 strType = ((XmlSchemaElement)typeNode).SchemaTypeName.Name;
1944                 type = ParseDataType(strType);
1945             }
1946             else {
1947                 if (typeNode.Id == null)
1948                     throw ExceptionBuilder.DatatypeNotDefined();
1949                 else
1950                     throw ExceptionBuilder.UndefinedDatatype(typeNode.Id);
1951             }
1952
1953             DataColumn column;
1954             string columnName = XmlConvert.DecodeName(GetInstanceName(attr));
1955             bool isToAdd = true;
1956
1957             if ((!isBase || FromInference) && (table.Columns.Contains(columnName, true))) {
1958                 column = table.Columns[columnName];
1959                 isToAdd = false;
1960
1961                 if (FromInference) { // for backward compatability with old inference
1962             // throw eception if same column is being aded with different mapping
1963                     if (column.ColumnMapping != MappingType.Attribute)
1964                         throw ExceptionBuilder.ColumnTypeConflict(column.ColumnName);
1965                     // in previous inference , if we have incoming column with different NS, we think as different column and 
1966                     //while adding , since there is no NS concept for datacolumn, we used to throw exception
1967                     // simulate the same behavior.
1968                     if ((Common.ADP.IsEmpty(attrib.QualifiedName.Namespace) && Common.ADP.IsEmpty(column._columnUri)) || // backward compatability :SQL BU DT 310912
1969                         (string.Compare(attrib.QualifiedName.Namespace, column.Namespace, StringComparison.Ordinal) == 0))
1970                     {
1971                         return; // backward compatability
1972                     }
1973                     column = new DataColumn(columnName, type, null, MappingType.Attribute); // this is to fix issue with Exception we used to throw for old inference engine if column
1974                     //exists with different namespace; while adding it to columncollection
1975                     isToAdd = true;
1976                 }
1977
1978             }
1979             else {
1980                 column = new DataColumn(columnName, type, null, MappingType.Attribute);
1981             }
1982
1983             SetProperties(column, attr.UnhandledAttributes);
1984             HandleColumnExpression(column, attr.UnhandledAttributes);
1985             SetExtProperties(column, attr.UnhandledAttributes);
1986
1987             if ((column.Expression!=null)&&(column.Expression.Length!=0)) {
1988                 ColumnExpressions.Add(column);
1989             }
1990
1991             if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0) {
1992                 if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE)!= null) {
1993                   column.XmlDataType = xsdType.SimpleTypeQualifiedName;
1994                 }
1995             }
1996             else {
1997                 column.XmlDataType = strType;
1998             }
1999
2000             column.SimpleType = xsdType;
2001
2002             column.AllowDBNull = !(attrib.Use == XmlSchemaUse.Required);
2003             column.Namespace = attrib.QualifiedName.Namespace;
2004             column.Namespace = GetStringAttribute(attrib, "targetNamespace", column.Namespace);
2005
2006             if (isToAdd) {
2007                 if (this.FromInference) { // move this setting to SetProperties
2008                     column.AllowDBNull = true;
2009                     column.Prefix = GetPrefix(column.Namespace);
2010                 }
2011               table.Columns.Add(column);
2012             }
2013
2014             if (attrib.Use == XmlSchemaUse.Prohibited) {
2015                 column.ColumnMapping = MappingType.Hidden;
2016                 
2017                 column.AllowDBNull = GetBooleanAttribute(attr, Keywords.MSD_ALLOWDBNULL, true)  ;
2018                 String defValue = GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE);
2019                 if (defValue != null)
2020                     try {
2021                         column.DefaultValue = column.ConvertXmlToObject(defValue);
2022                     }
2023                     catch (System.FormatException) {
2024                         throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
2025                     }    
2026             }
2027
2028
2029             // XDR [....] change
2030             string strDefault = (attrib.Use == XmlSchemaUse.Required) ? GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE) : attr.DefaultValue;
2031             if ((attr.Use == XmlSchemaUse.Optional) && (strDefault == null ))
2032                 strDefault = attr.FixedValue;
2033             
2034             if (strDefault != null)
2035                 try {
2036                     column.DefaultValue = column.ConvertXmlToObject(strDefault);
2037                 }
2038                 catch (System.FormatException) {
2039                     throw ExceptionBuilder.CannotConvert(strDefault, type.FullName);
2040                 }    
2041         }
2042
2043         internal void HandleElementColumn(XmlSchemaElement elem, DataTable table, bool isBase){
2044             Type type = null;
2045             XmlSchemaElement el = elem.Name != null ? elem : (XmlSchemaElement) elementsTable[elem.RefName];
2046
2047             if (el == null) // it's possible due to some XSD compiler optimizations
2048                 return; // do nothing
2049             
2050             XmlSchemaAnnotated typeNode = FindTypeNode(el);
2051             String strType = null;
2052             SimpleType xsdType = null;
2053
2054             if (typeNode == null) {
2055                 strType = el.SchemaTypeName.Name;
2056                 if (Common.ADP.IsEmpty(strType)) {
2057                     strType = "";
2058                     type = typeof(string);
2059                 }
2060                 else {
2061                     type = ParseDataType(el.SchemaTypeName.Name);
2062                 }
2063             }
2064             else if (typeNode is XmlSchemaSimpleType) {
2065                 // 
2066                 XmlSchemaSimpleType simpleTypeNode = typeNode as XmlSchemaSimpleType;
2067                 xsdType = new SimpleType(simpleTypeNode);
2068              // ((XmlSchemaSimpleType)typeNode).Name != null && ((XmlSchemaSimpleType)typeNode).Name.Length != 0 check is for annonymos simple type, 
2069              // it should be  user defined  Named  simple type
2070                 if (((XmlSchemaSimpleType)typeNode).Name != null && ((XmlSchemaSimpleType)typeNode).Name.Length != 0 && ((XmlSchemaSimpleType)typeNode).QualifiedName.Namespace != Keywords.XSDNS) {
2071
2072                     string targetNamespace = XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE);
2073                     strType = ((XmlSchemaSimpleType)typeNode).QualifiedName.ToString(); // use qualifed name
2074                     type = ParseDataType(strType);
2075                 }
2076                 else {
2077                     simpleTypeNode = (xsdType.XmlBaseType!= null && xsdType.XmlBaseType.Namespace != Keywords.XSDNS)  ?
2078                                                 schemaTypes[xsdType.XmlBaseType] as XmlSchemaSimpleType :
2079                                                 null;
2080                     while (simpleTypeNode != null) {
2081                         xsdType.LoadTypeValues(simpleTypeNode);
2082                         simpleTypeNode = (xsdType.XmlBaseType!= null && xsdType.XmlBaseType.Namespace != Keywords.XSDNS)  ?
2083                                                     schemaTypes[xsdType.XmlBaseType] as XmlSchemaSimpleType :
2084                                                     null;
2085                    }
2086
2087                     type = ParseDataType(xsdType.BaseType);
2088                     strType = xsdType.Name;
2089
2090                     if(xsdType.Length == 1 && type == typeof(string)) {
2091                         type = typeof(Char);
2092                     }
2093                 }
2094             }
2095             else if (typeNode is XmlSchemaElement) { // theoratically no named simpletype should come here
2096                 strType = ((XmlSchemaElement)typeNode).SchemaTypeName.Name;
2097                 type = ParseDataType(strType);
2098             }
2099             else if (typeNode is XmlSchemaComplexType) {
2100                 if (ADP.IsEmpty(XSDSchema.GetMsdataAttribute(elem, Keywords.MSD_DATATYPE))) {
2101                     throw ExceptionBuilder.DatatypeNotDefined();
2102                 }
2103                 else {
2104                     type = typeof(object);
2105                 }
2106             }
2107             else {
2108                 if (typeNode.Id == null)
2109                     throw ExceptionBuilder.DatatypeNotDefined();
2110                 else
2111                     throw ExceptionBuilder.UndefinedDatatype(typeNode.Id);
2112             }
2113
2114             DataColumn column;
2115             string columnName = XmlConvert.DecodeName(GetInstanceName(el));
2116             bool isToAdd = true;
2117
2118             if (((!isBase) || FromInference) && (table.Columns.Contains(columnName, true))) {
2119                 column = table.Columns[columnName];
2120                 isToAdd = false;
2121                 
2122                 if (FromInference) { // for backward compatability with old inference
2123                     if (column.ColumnMapping != MappingType.Element)
2124                         throw ExceptionBuilder.ColumnTypeConflict(column.ColumnName);
2125                     // in previous inference , if we have incoming column with different NS, we think as different column and 
2126                     //while adding , since there is no NS concept for datacolumn, we used to throw exception
2127                     // simulate the same behavior.
2128                     if ((Common.ADP.IsEmpty(elem.QualifiedName.Namespace) && Common.ADP.IsEmpty(column._columnUri)) || // backward compatability :SQL BU DT 310912
2129                         (string.Compare(elem.QualifiedName.Namespace, column.Namespace, StringComparison.Ordinal) == 0))
2130                     {
2131                         return; // backward compatability
2132                     }
2133                     column =   new DataColumn(columnName, type, null, MappingType.Element);// this is to fix issue with Exception we used to throw for old inference engine if column
2134                     //exists with different namespace; while adding it to columncollection
2135                     isToAdd = true;
2136                 }
2137             }
2138             else {
2139                 column = new DataColumn(columnName, type, null, MappingType.Element);
2140             }
2141
2142             SetProperties(column, el.UnhandledAttributes);
2143             HandleColumnExpression(column, el.UnhandledAttributes);
2144             SetExtProperties(column, el.UnhandledAttributes);
2145
2146             if (!Common.ADP.IsEmpty(column.Expression)) {
2147                 ColumnExpressions.Add(column);
2148             }
2149
2150 // Update XSD type to point to simple types actual namespace instead of normalized default namespace in case of remoting
2151             if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0) {
2152                 if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE)!= null) {
2153                   column.XmlDataType = xsdType.SimpleTypeQualifiedName;
2154                 }
2155             }
2156             else {
2157                 column.XmlDataType = strType;
2158             }
2159             column.SimpleType = xsdType;            
2160
2161             column.AllowDBNull = this.FromInference ||(elem.MinOccurs == 0 ) || elem.IsNillable;
2162
2163
2164             if (!elem.RefName.IsEmpty || elem.QualifiedName.Namespace != table.Namespace)
2165             { // if ref element (or in diferent NS) it is global element, so form MUST BE Qualified
2166                 column.Namespace = elem.QualifiedName.Namespace;
2167                 column.Namespace = GetStringAttribute(el, "targetNamespace", column.Namespace);
2168             }
2169             else { // it is local, hence check for 'form' on local element, if not specified, check for 'elemenfformdefault' on schema element
2170                 if (elem.Form == XmlSchemaForm.Unqualified) {
2171                     column.Namespace = String.Empty;                    
2172                 }
2173                 else if (elem.Form == XmlSchemaForm.None) {
2174                     XmlSchemaObject e = (XmlSchemaObject)elem.Parent;
2175                     while (e.Parent != null) {
2176                         e = e.Parent;
2177                     }
2178                     if (((XmlSchema)e).ElementFormDefault == XmlSchemaForm.Unqualified) {
2179                         column.Namespace = String.Empty;
2180                     }
2181                 }
2182                 else {
2183                     column.Namespace = elem.QualifiedName.Namespace;
2184                     column.Namespace = GetStringAttribute(el, "targetNamespace", column.Namespace);
2185                 }
2186             }
2187
2188             String tmp = GetStringAttribute(elem, Keywords.MSD_ORDINAL, (-1).ToString(CultureInfo.CurrentCulture));
2189             int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
2190
2191             if(isToAdd) {
2192                 if(ordinal>-1 && ordinal<table.Columns.Count)
2193                     table.Columns.AddAt(ordinal, column);
2194                 else
2195                     table.Columns.Add(column);
2196             }
2197
2198             if (column.Namespace == table.Namespace)
2199                 column._columnUri = null; // to not raise a column change namespace again
2200
2201             if(this.FromInference) {// search for prefix after adding to table, so NS has its final value, and 
2202                 column.Prefix = GetPrefix(column.Namespace); // it can inherit its NS from DataTable, if it is null
2203             }
2204
2205             string strDefault = el.DefaultValue;
2206             if (strDefault != null )
2207                 try {
2208                     column.DefaultValue = column.ConvertXmlToObject(strDefault);
2209                 }
2210                 catch (System.FormatException) {
2211
2212                     throw ExceptionBuilder.CannotConvert(strDefault, type.FullName);
2213                 }    
2214         }
2215
2216         internal void HandleDataSet(XmlSchemaElement node, bool isNewDataSet) {
2217             string dsName = node.Name;
2218             string dsNamespace = node.QualifiedName.Namespace;
2219             int initialTableCount = _ds.Tables.Count; // just use for inference backward compatablity
2220
2221             List<DataTable> tableSequenceList = new List<DataTable>();
2222
2223             String value = GetMsdataAttribute(node, Keywords.MSD_LOCALE);
2224             if (null != value) { // set by user
2225                 if (0 != value.Length) {
2226                     // <... msdata:Locale="en-US"/>
2227                     _ds.Locale = new CultureInfo(value);
2228                 }
2229                 else {
2230                     // everett bug behavior before <... msdata:Locale=""/> becoming CultureInfo(0x409)
2231                     _ds.Locale = CultureInfo.InvariantCulture;
2232                 }
2233             }
2234             else { // not set by user
2235                 // MSD_LOCALE overrides MSD_USECURRENTLOCALE
2236                 if (GetBooleanAttribute(node, Keywords.MSD_USECURRENTLOCALE, false)) {
2237                     _ds.SetLocaleValue(CultureInfo.CurrentCulture, false);
2238                 }
2239                 else {
2240                     // everett behavior before <... msdata:UseCurrentLocale="true"/>
2241                     _ds.SetLocaleValue(new CultureInfo(0x409), false);
2242                 }
2243             }
2244             
2245             // reuse variable
2246             value =  GetMsdataAttribute(node, Keywords.MSD_DATASETNAME);
2247             if (value!=null && value.Length != 0) {
2248                 dsName = value;
2249             }
2250
2251             value =  GetMsdataAttribute(node, Keywords.MSD_DATASETNAMESPACE);
2252             if (value!=null && value.Length != 0) {
2253                 dsNamespace = value;
2254             }
2255
2256             SetProperties(_ds, node.UnhandledAttributes);
2257             SetExtProperties(_ds, node.UnhandledAttributes);
2258
2259
2260             if (dsName != null && dsName.Length != 0)
2261                 _ds.DataSetName = XmlConvert.DecodeName(dsName);
2262
2263  //            _ds.Namespace = node.QualifiedName.Namespace;
2264             _ds.Namespace = dsNamespace;
2265
2266             if (this.FromInference)
2267                 _ds.Prefix = GetPrefix(_ds.Namespace);
2268
2269             XmlSchemaComplexType ct = (XmlSchemaComplexType) FindTypeNode(node);
2270             if (ct.Particle != null) {
2271                 XmlSchemaObjectCollection items = GetParticleItems(ct.Particle);
2272             
2273                 if (items == null) {
2274                     return;
2275                 }
2276
2277                 foreach (XmlSchemaAnnotated el in items){
2278                     if (el is XmlSchemaElement) {
2279                         if(((XmlSchemaElement)el).RefName.Name.Length != 0) {
2280                             if (!FromInference) {
2281                                 continue;
2282                             }
2283                             else {
2284                                 DataTable tempTable = _ds.Tables.GetTable(XmlConvert.DecodeName(GetInstanceName((XmlSchemaElement)el)), node.QualifiedName.Namespace);
2285                                 if (tempTable != null) {
2286                                     tableSequenceList.Add(tempTable); // if ref table is created, add it
2287                                 }
2288                                 bool isComplexTypeOrValidElementType = false;
2289                                 if (node.ElementSchemaType != null || !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)) {
2290                                     isComplexTypeOrValidElementType = true;
2291                                 }
2292  //                          bool isComplexTypeOrValidElementType = (node.ElementType != null || !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType));
2293                                 if ((((XmlSchemaElement)el).MaxOccurs != Decimal.One )  && (!isComplexTypeOrValidElementType)) {
2294                                     continue;
2295                                 }
2296                             }
2297                         }
2298
2299                         DataTable child = HandleTable ((XmlSchemaElement)el);
2300                         if (child!=null) {
2301                             child.fNestedInDataset = true;
2302                         }
2303                         if (FromInference) {
2304                             tableSequenceList.Add(child);
2305                         }
2306                     }
2307                     else if (el is XmlSchemaChoice){ // should we check for inference?
2308                         XmlSchemaObjectCollection choiceItems = ((XmlSchemaChoice)el).Items;
2309                         if (choiceItems == null)
2310                             continue;
2311                         foreach (XmlSchemaAnnotated choiceEl in choiceItems) {
2312                             if (choiceEl is XmlSchemaElement) {
2313                                 if (((XmlSchemaParticle)el).MaxOccurs > Decimal.One && (((XmlSchemaElement)choiceEl).SchemaType is XmlSchemaComplexType)) // amir
2314                                 ((XmlSchemaElement)choiceEl).MaxOccurs = ((XmlSchemaParticle)el).MaxOccurs;
2315                                 if ((((XmlSchemaElement)choiceEl).RefName.Name.Length != 0) && (!FromInference && ((XmlSchemaElement)choiceEl).MaxOccurs != Decimal.One && !(((XmlSchemaElement)choiceEl).SchemaType is XmlSchemaComplexType)))
2316                                     continue;
2317
2318                                 DataTable child = HandleTable ((XmlSchemaElement)choiceEl);
2319                                 if (FromInference) {
2320                                     tableSequenceList.Add(child);
2321                                 }
2322                                 if (child != null)
2323                                 {
2324                                     child.fNestedInDataset = true;
2325                                 }
2326                             }
2327                         }
2328                     }
2329                 } 
2330             }
2331
2332             // Handle the non-nested keyref constraints
2333             if (node.Constraints != null) {
2334                 foreach (XmlSchemaIdentityConstraint key in node.Constraints) {
2335                         XmlSchemaKeyref keyref = key as XmlSchemaKeyref;
2336                         if (keyref == null)
2337                             continue;
2338
2339                         bool isNested = GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED,  /*default:*/ false);                                
2340                         if (isNested)
2341                             continue;
2342
2343                         HandleKeyref(keyref);
2344                     }
2345             }
2346             if (FromInference && isNewDataSet) {
2347                 List<DataTable> _tableList = new List<DataTable>(_ds.Tables.Count);
2348                 foreach(DataTable dt in tableSequenceList) {
2349                     AddTablesToList(_tableList, dt);
2350                 }
2351                 _ds.Tables.ReplaceFromInference(_tableList); // replace the list with the one in correct order: BackWard compatability for inference
2352             }
2353         }
2354
2355         private void AddTablesToList(List<DataTable> tableList, DataTable dt) { // kind of depth _first travarsal
2356             if (!tableList.Contains(dt)) {
2357                 tableList.Add(dt);
2358                 foreach(DataTable childTable in tableDictionary[dt]) {
2359                     AddTablesToList(tableList, childTable);
2360                 }
2361             }
2362         }
2363         
2364         private string GetPrefix(string ns) {
2365             if (ns == null)
2366                 return null;
2367             foreach (XmlSchema schemaRoot in _schemaSet.Schemas()) {
2368                 XmlQualifiedName[] qualifiedNames = schemaRoot.Namespaces.ToArray();
2369                 for(int i = 0; i < qualifiedNames.Length; i++) {
2370                     if (qualifiedNames[i].Namespace == ns)
2371                         return qualifiedNames[i].Name;
2372                 }
2373             }
2374             return null;
2375         }
2376
2377         private string GetNamespaceFromPrefix(string prefix) {
2378             if ((prefix == null) ||(prefix.Length == 0))
2379                 return null;
2380             foreach (XmlSchema schemaRoot in _schemaSet.Schemas()) {
2381                 XmlQualifiedName[] qualifiedNames = schemaRoot.Namespaces.ToArray();
2382                 for(int i = 0; i < qualifiedNames.Length; i++) {
2383                     if (qualifiedNames[i].Name == prefix)
2384                         return qualifiedNames[i].Namespace;
2385                 }
2386             }
2387             return null;
2388         }
2389
2390
2391         private String GetTableNamespace(XmlSchemaIdentityConstraint key) {
2392             string xpath = key.Selector.XPath;
2393             string [] split = xpath.Split('/');
2394             string prefix =string.Empty;
2395             
2396             string QualifiedTableName = split[split.Length - 1]; //get the last string after '/' and ':'
2397             
2398             if ((QualifiedTableName == null) || (QualifiedTableName.Length == 0))
2399                 throw ExceptionBuilder.InvalidSelector(xpath);
2400
2401             if (QualifiedTableName.IndexOf(':') != -1)
2402                 prefix = QualifiedTableName.Substring(0, QualifiedTableName.IndexOf(':'));
2403             else
2404                 return GetMsdataAttribute(key, Keywords.MSD_TABLENS);
2405
2406             prefix  = XmlConvert.DecodeName(prefix );
2407
2408             return GetNamespaceFromPrefix(prefix);
2409         }
2410         
2411         private String GetTableName(XmlSchemaIdentityConstraint key) {
2412             string xpath = key.Selector.XPath;
2413             string [] split = xpath.Split('/',':');
2414             String tableName = split[split.Length - 1]; //get the last string after '/' and ':'
2415             
2416             if ((tableName == null) || (tableName.Length == 0))
2417                 throw ExceptionBuilder.InvalidSelector(xpath);
2418                 
2419             tableName = XmlConvert.DecodeName(tableName);
2420             return tableName;            
2421         }
2422         
2423         internal bool IsTable(XmlSchemaElement node) {
2424             if (node.MaxOccurs == decimal.Zero)
2425                 return false;
2426
2427             XmlAttribute[] attribs = node.UnhandledAttributes;
2428             if (attribs != null) {
2429                 for(int i = 0; i < attribs.Length; i++) {
2430                     XmlAttribute attrib = attribs[i];
2431                     if (attrib.LocalName == Keywords.MSD_DATATYPE &&
2432                         attrib.Prefix == Keywords.MSD &&
2433                         attrib.NamespaceURI == Keywords.MSDNS)
2434                         return false;
2435                 }
2436             }
2437
2438             Object typeNode = FindTypeNode(node);
2439
2440             if ( (node.MaxOccurs > decimal.One) && typeNode == null ){
2441                 return true;
2442             }
2443             
2444
2445             if ((typeNode==null) || !(typeNode is XmlSchemaComplexType)) {
2446                 return false;
2447             }
2448
2449             XmlSchemaComplexType ctNode = (XmlSchemaComplexType) typeNode;
2450
2451             if (ctNode.IsAbstract)
2452                 throw ExceptionBuilder.CannotInstantiateAbstract(node.Name);
2453
2454             return true;
2455         }
2456
2457 //        internal bool IsTopLevelElement (XmlSchemaElement node) {
2458 //            return (elements.IndexOf(node) != -1);           
2459 //        }
2460         internal DataTable HandleTable(XmlSchemaElement node) {
2461         
2462             if (!IsTable(node))
2463                 return null;
2464             
2465             Object typeNode = FindTypeNode(node);
2466
2467             if ( (node.MaxOccurs > decimal.One) && typeNode == null ){
2468                 return InstantiateSimpleTable(node);
2469             }
2470             
2471             DataTable table = InstantiateTable(node,(XmlSchemaComplexType)typeNode, (node.RefName != null)); // this is wrong , correct check should be node.RefName.IsEmpty
2472
2473             table.fNestedInDataset = false;
2474             return table;
2475
2476         }
2477
2478     }
2479
2480     internal sealed class XmlIgnoreNamespaceReader : XmlNodeReader {
2481         private List<string> namespacesToIgnore;    
2482     // 
2483     // Constructor
2484     //
2485         internal XmlIgnoreNamespaceReader(XmlDocument xdoc, string[] namespacesToIgnore) : base(xdoc) {
2486             this.namespacesToIgnore = new List<string>(namespacesToIgnore);
2487         }
2488
2489     //
2490     // XmlReader implementation
2491     //
2492
2493         public override bool MoveToFirstAttribute() {
2494             if (base.MoveToFirstAttribute()) {
2495                 if ( namespacesToIgnore.Contains(this.NamespaceURI) ||
2496                     (this.NamespaceURI == Keywords.XML_XMLNS && this.LocalName != "lang")) { //try next one
2497                     return MoveToNextAttribute();
2498                 }
2499                 else {
2500                     return true;
2501                 }
2502             }
2503             return false;
2504         }
2505
2506         public override bool MoveToNextAttribute() {
2507             bool moved, flag;
2508             do {
2509                 moved = false;
2510                 flag = false;
2511                 if (base.MoveToNextAttribute()) {
2512                     moved = true;
2513
2514                     if ( namespacesToIgnore.Contains(this.NamespaceURI) ||
2515                         (this.NamespaceURI == Keywords.XML_XMLNS && this.LocalName != "lang")) {
2516                         flag = true;
2517                     }
2518                 }
2519             } while(flag);
2520             return moved;
2521         }
2522     }
2523 }