private void FillDataColumnRepeatedSimpleElement (XmlSchemaElement parent, XmlSchemaElement el, DataColumn col)
		{
			if (targetElements.Contains (el))
				return; // do nothing

			AddParentKeyColumn (parent, el, col);
			DataColumn pkey = currentTable.PrimaryKey;

			string elName = XmlConvert.DecodeName (el.QualifiedName.Name);
			string parentName = XmlConvert.DecodeName (parent.QualifiedName.Name);

			DataTable dt = new DataTable ();
			dt.TableName = elName;
			dt.Namespace = el.QualifiedName.Namespace;
			// reference key column to parent
			DataColumn cc = new DataColumn ();
			cc.ColumnName = parentName + "_Id";
			cc.Namespace = parent.QualifiedName.Namespace;
			cc.ColumnMapping = MappingType.Hidden;
			cc.DataType = typeof (int);

			// repeatable content simple element
			DataColumn cc2 = new DataColumn ();
			cc2.ColumnName = elName + "_Column";
			cc2.Namespace = el.QualifiedName.Namespace;
			cc2.ColumnMapping = MappingType.SimpleContent;
			cc2.AllowDBNull = false;
			cc2.DataType = ConvertDatatype (GetSchemaPrimitiveType (el.ElementType));

			dt.Columns.Add (cc2);
			dt.Columns.Add (cc);
			dataset.Tables.Add (dt);

			RelationStructure rel = new RelationStructure ();
			rel.ParentTableName = parentName;
			rel.ChildTableName = dt.TableName;
			rel.ParentColumnName = pkey.ColumnName;
			rel.ChildColumnName = cc.ColumnName;
			rel.IsNested = true;
			rel.CreateConstraint = true;
			relations.Add (rel);
		}
		private void HandleRelationshipAnnotation (XmlElement el, bool nested)
		{
			string name = el.GetAttribute ("name");
			string ptn = el.GetAttribute ("parent", XmlConstants.MsdataNamespace);
			string ctn = el.GetAttribute ("child", XmlConstants.MsdataNamespace);
			string pkn = el.GetAttribute ("parentkey", XmlConstants.MsdataNamespace);
			string fkn = el.GetAttribute ("childkey", XmlConstants.MsdataNamespace);

			RelationStructure rel = new RelationStructure ();
			rel.ExplicitName = name;
			rel.ParentTableName = ptn;
			rel.ChildTableName = ctn;
			rel.ParentColumnName = pkn;
			rel.ChildColumnName = fkn;
			rel.IsNested = nested;
			rel.CreateConstraint = false; // by default?
			relations.Add (rel);
		}
		private DataRelation GenerateRelationship (RelationStructure rs)
		{
			DataTable ptab = dataset.Tables [rs.ParentTableName];
			DataTable ctab = dataset.Tables [rs.ChildTableName];
			DataColumn pcol = ptab.Columns [rs.ParentColumnName];
			DataColumn ccol = ctab.Columns [rs.ChildColumnName];

			if (ccol == null) {
				ccol = new DataColumn ();
				ccol.ColumnName = pcol.ColumnName;
				ccol.Namespace = String.Empty; // don't copy
				ccol.ColumnMapping = MappingType.Hidden;
				ccol.DataType = pcol.DataType;
				ctab.Columns.Add (ccol);
			}

			string name = rs.ExplicitName != null ? rs.ExplicitName : XmlConvert.DecodeName (ptab.TableName) + '_' + XmlConvert.DecodeName (ctab.TableName);
			DataRelation rel = new DataRelation (name, pcol, ccol, rs.CreateConstraint);
			rel.Nested = rs.IsNested;
			if (rs.CreateConstraint)
				rel.ParentTable.PrimaryKey = rel.ParentColumns;
			return rel;
		}
		private void FillDataColumnComplexElement (XmlSchemaElement parent, XmlSchemaElement el, DataColumn col)
		{
			if (targetElements.Contains (el))
				return; // do nothing

			string elName = XmlConvert.DecodeName (el.QualifiedName.Name);
			if (elName == dataset.DataSetName)
				// Well, why it is ArgumentException :-?
				throw new ArgumentException ("Nested element must not have the same name as DataSet's name.");

			if (el.Annotation != null)
				HandleAnnotations (el.Annotation, true);
			else {
				AddParentKeyColumn (parent, el, col);
				DataColumn pkey = currentTable.PrimaryKey;

				RelationStructure rel = new RelationStructure ();
				rel.ParentTableName = XmlConvert.DecodeName (parent.QualifiedName.Name);
				rel.ChildTableName = elName;
				rel.ParentColumnName = pkey.ColumnName;
				rel.ChildColumnName = pkey.ColumnName;
				rel.CreateConstraint = true;
				rel.IsNested = true;
				relations.Add (rel);
			}

			// If the element is not referenced one, the element will be handled later.
			if (el.RefName == XmlQualifiedName.Empty)
				targetElements.Add (el);

		}
		public void Add (RelationStructure rel)
		{
			List.Add (rel);
		}
		private void FillDataColumnComplexElement (XmlSchemaElement parent, XmlSchemaElement el, DataColumn col)
		{
			if (targetElements.Contains (el))
				return; // do nothing

			string elName = XmlHelper.Decode (el.QualifiedName.Name);
			if (elName == dataset.DataSetName)
				// Well, why it is ArgumentException :-?
				throw new ArgumentException ("Nested element must not have the same name as DataSet's name.");

			if (el.Annotation != null)
				HandleAnnotations (el.Annotation, true);
			// If xsd:keyref xsd:key for this table exists, then don't add
			// relation here manually.
			else if (!DataSetDefinesKey (elName)) {
				AddParentKeyColumn (parent, el, col);

				RelationStructure rel = new RelationStructure ();
				rel.ParentTableName = XmlHelper.Decode (parent.QualifiedName.Name);
				rel.ChildTableName = elName;
				rel.ParentColumnName = col.ColumnName;
				rel.ChildColumnName = col.ColumnName;
				rel.CreateConstraint = true;
				rel.IsNested = true;
				relations.Add (rel);
			}

			// If the element is not referenced one, the element will be handled later.
			if (el.RefName == XmlQualifiedName.Empty)
				ProcessDataTableElement (el);

		}
		private DataRelation GenerateRelationship (RelationStructure rs)
		{
			DataTable ptab = dataset.Tables [rs.ParentTableName];
			DataTable ctab = dataset.Tables [rs.ChildTableName];

			DataRelation rel ;
			string name = rs.ExplicitName != null ? rs.ExplicitName : XmlHelper.Decode (ptab.TableName) + '_' + XmlHelper.Decode (ctab.TableName);

			// Annotation Relations belonging to a DataSet can contain multiple colnames
			// in parentkey and childkey.
			if (datasetElement != null) {
				String[] pcolnames = rs.ParentColumnName.Split (null);
				String[] ccolnames = rs.ChildColumnName.Split (null);

				DataColumn[] pcol = new DataColumn [pcolnames.Length];
				for (int i=0; i<pcol.Length; ++i)
					pcol [i] = ptab.Columns [XmlHelper.Decode (pcolnames [i])];

				DataColumn[] ccol = new DataColumn [ccolnames.Length];
				for (int i=0; i < ccol.Length; ++i) {
					ccol [i] = ctab.Columns [XmlHelper.Decode (ccolnames [i])];
					if (ccol [i] == null)
						ccol [i] = CreateChildColumn (pcol [i], ctab);
				}
				rel = new DataRelation (name, pcol, ccol, rs.CreateConstraint);
			} else {
				DataColumn pcol = ptab.Columns [XmlHelper.Decode (rs.ParentColumnName)];
				DataColumn ccol = ctab.Columns [XmlHelper.Decode (rs.ChildColumnName)];
				if (ccol == null) 
					ccol = CreateChildColumn (pcol, ctab);
				rel = new DataRelation (name, pcol, ccol, rs.CreateConstraint);
			}
			rel.Nested = rs.IsNested;
			if (rs.CreateConstraint)
				rel.ParentTable.PrimaryKey = rel.ParentColumns;
			return rel;
		}
		private void HandleRelationshipAnnotation (XmlElement el, bool nested)
		{
			string name = el.GetAttribute ("name");
			string ptn = el.GetAttribute ("parent", XmlConstants.MsdataNamespace);
			string ctn = el.GetAttribute ("child", XmlConstants.MsdataNamespace);
			string pkn = el.GetAttribute ("parentkey", XmlConstants.MsdataNamespace);
			string fkn = el.GetAttribute ("childkey", XmlConstants.MsdataNamespace);

			RelationStructure rel = new RelationStructure ();
			rel.ExplicitName = XmlHelper.Decode (name);
			rel.ParentTableName = XmlHelper.Decode (ptn);
			rel.ChildTableName = XmlHelper.Decode (ctn);
			// ColumnNames will be decoded wherever they are used as they can
			// contain 'space' separated list of column-names.
			rel.ParentColumnName = pkn;
			rel.ChildColumnName = fkn;
			rel.IsNested = nested;
			rel.CreateConstraint = false; // by default?
			relations.Add (rel);
		}
		private void PopulateRelationStructure (string parent, string child, string pkeyColumn)
		{
			if (relations [parent, child] != null)
				return;
			RelationStructure rs = new RelationStructure ();
			rs.ParentTableName = parent;
			rs.ChildTableName = child;
			rs.ParentColumnName = pkeyColumn;
			rs.ChildColumnName = pkeyColumn;
			rs.CreateConstraint = true;
			rs.IsNested = true;
			relations.Add (rs);
		}