2004-10-05 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / XPathAtomicValue.cs
1 //
2 // XPathAtomicValue.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C)2004 Novell Inc.
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if NET_2_0
32
33 using System.Collections;
34 using System.Xml;
35 using System.Xml.Schema;
36
37 namespace System.Xml.XPath
38 {
39         public sealed class XPathAtomicValue : XPathItem, ICloneable
40         {
41                 bool booleanValue;
42                 DateTime dateTimeValue;
43                 decimal decimalValue;
44                 double doubleValue;
45                 int intValue;
46                 long longValue;
47                 object objectValue;
48                 float floatValue;
49                 string stringValue;
50                 XmlSchemaType schemaType;
51                 XmlTypeCode xmlTypeCode;
52                 ICollection valueAsList;
53
54                 #region Constructors
55
56                 [MonoTODO]
57                 public XPathAtomicValue (bool value, XmlSchemaType xmlType)
58                 {
59                         Init (value, xmlType);
60                 }
61                 
62                 private void Init (bool value, XmlSchemaType xmlType)
63                 {
64                         if (xmlType == null)
65                                 throw new ArgumentNullException ("xmlType");
66                         xmlTypeCode = XmlTypeCode.Boolean;
67                         this.booleanValue = value;
68                         schemaType = xmlType;
69                 }
70
71                 [MonoTODO]
72                 public XPathAtomicValue (DateTime value, XmlSchemaType xmlType)
73                 {
74                         Init (value, xmlType);
75                 }
76                 
77                 private void Init (DateTime value, XmlSchemaType xmlType)
78                 {
79                         if (xmlType == null)
80                                 throw new ArgumentNullException ("xmlType");
81                         xmlTypeCode = XmlTypeCode.DateTime;
82                         this.dateTimeValue = value;
83                         schemaType = xmlType;
84                 }
85
86                 [MonoTODO]
87                 public XPathAtomicValue (decimal value, XmlSchemaType xmlType)
88                 {
89                         Init (value, xmlType);
90                 }
91                 
92                 private void Init (decimal value, XmlSchemaType xmlType)
93                 {
94                         if (xmlType == null)
95                                 throw new ArgumentNullException ("xmlType");
96                         xmlTypeCode = XmlTypeCode.Decimal;
97                         this.decimalValue = value;
98                         schemaType = xmlType;
99                 }
100
101                 [MonoTODO]
102                 public XPathAtomicValue (double value, XmlSchemaType xmlType)
103                 {
104                         Init (value, xmlType);
105                 }
106                 
107                 private void Init (double value, XmlSchemaType xmlType)
108                 {
109                         if (xmlType == null)
110                                 throw new ArgumentNullException ("xmlType");
111                         xmlTypeCode = XmlTypeCode.Double;
112                         this.doubleValue = value;
113                         schemaType = xmlType;
114                 }
115
116                 [MonoTODO]
117                 public XPathAtomicValue (int value, XmlSchemaType xmlType)
118                 {
119                         Init (value, xmlType);
120                 }
121                 
122                 private void Init (int value, XmlSchemaType xmlType)
123                 {
124                         if (xmlType == null)
125                                 throw new ArgumentNullException ("xmlType");
126                         xmlTypeCode = XmlTypeCode.Int;
127                         this.intValue = value;
128                         schemaType = xmlType;
129                 }
130
131                 [MonoTODO]
132                 public XPathAtomicValue (long value, XmlSchemaType xmlType)
133                 {
134                         Init (value, xmlType);
135                 }
136                 
137                 private void Init (long value, XmlSchemaType xmlType)
138                 {
139                         if (xmlType == null)
140                                 throw new ArgumentNullException ("xmlType");
141                         xmlTypeCode = XmlTypeCode.Long;
142                         this.longValue = value;
143                         schemaType = xmlType;
144                 }
145
146                 [MonoTODO]
147                 public XPathAtomicValue (float value, XmlSchemaType xmlType)
148                 {
149                         Init (value, xmlType);
150                 }
151                 
152                 private void Init (float value, XmlSchemaType xmlType)
153                 {
154                         if (xmlType == null)
155                                 throw new ArgumentNullException ("xmlType");
156                         xmlTypeCode = XmlTypeCode.Float;
157                         this.floatValue = value;
158                         schemaType = xmlType;
159                 }
160
161                 [MonoTODO]
162                 public XPathAtomicValue (string value, XmlSchemaType xmlType)
163                 {
164                         Init (value, xmlType);
165                 }
166                 
167                 public void Init (string value, XmlSchemaType xmlType)
168                 {
169                         if (value == null)
170                                 throw new ArgumentNullException ("value");
171                         if (xmlType == null)
172                                 throw new ArgumentNullException ("xmlType");
173                         xmlTypeCode = XmlTypeCode.String;
174                         this.stringValue = value;
175                         schemaType = xmlType;
176                 }
177
178                 [MonoTODO]
179                 public XPathAtomicValue (object value, XmlSchemaType xmlType)
180                 {
181                         Init (value, xmlType);
182                 }
183
184                 private void Init (object value, XmlSchemaType xmlType)
185                 {
186                         // It accepts any kind of object, but will be rejected on each value properties.
187                         if (value == null)
188                                 throw new ArgumentNullException ("value");
189                         if (xmlType == null)
190                                 throw new ArgumentNullException ("xmlType");
191
192                         switch (Type.GetTypeCode (value.GetType ())) {
193                         case TypeCode.Int16:
194                         case TypeCode.UInt16:
195                         case TypeCode.Int32:
196                                 Init ((int) value, xmlType);
197                                 return;
198                         case TypeCode.Decimal:
199                                 Init ((decimal) value, xmlType);
200                                 return;
201                         case TypeCode.Double:
202                                 Init ((double) value, xmlType);
203                                 return;
204                         case TypeCode.Single:
205                                 Init ((float) value, xmlType);
206                                 return;
207                         case TypeCode.Int64:
208                         case TypeCode.UInt32:
209                                 Init ((long) value, xmlType);
210                                 return;
211                         case TypeCode.String:
212                                 Init ((string) value, xmlType);
213                                 return;
214                         case TypeCode.DateTime:
215                                 Init ((DateTime) value, xmlType);
216                                 return;
217                         case TypeCode.Boolean:
218                                 Init ((bool) value, xmlType);
219                                 return;
220                         }
221
222                         ICollection col = value as ICollection;
223                         if (col != null && col.Count == 1) {
224                                 if (col is IList)
225                                         Init (((IList) col) [0], xmlType);
226                                 else {
227                                         IEnumerator en = col.GetEnumerator ();
228                                         if (!en.MoveNext ())
229                                                 return;
230                                         if (en.Current is DictionaryEntry)
231                                                 Init (((DictionaryEntry) en.Current).Value, xmlType);
232                                         else
233                                                 Init (en.Current, xmlType);
234                                 }
235                                 return;
236                         }
237
238                         XPathAtomicValue another = value as XPathAtomicValue;
239                         if (another != null) {
240                                 switch (another.xmlTypeCode) {
241                                 case XmlTypeCode.Boolean:
242                                         Init (another.booleanValue, xmlType);
243                                         return;
244                                 case XmlTypeCode.DateTime:
245                                         Init (another.dateTimeValue, xmlType);
246                                         return;
247                                 case XmlTypeCode.Decimal:
248                                         Init (another.decimalValue, xmlType);
249                                         return;
250                                 case XmlTypeCode.Double:
251                                         Init (another.doubleValue, xmlType);
252                                         return;
253                                 case XmlTypeCode.Int:
254                                         Init (another.intValue, xmlType);
255                                         return;
256                                 case XmlTypeCode.Long:
257                                         Init (another.longValue, xmlType);
258                                         return;
259                                 case XmlTypeCode.Float:
260                                         Init (another.floatValue, xmlType);
261                                         return;
262                                 case XmlTypeCode.String:
263                                         Init (another.stringValue, xmlType);
264                                         return;
265                                 default:
266                                         objectValue = another.objectValue;
267                                         break;
268                                 }
269                         }
270
271                         objectValue = value;
272                         schemaType = xmlType;
273                 }
274
275                 #endregion
276
277                 #region Methods
278
279                 object ICloneable.Clone ()
280                 {
281                         return this.Clone ();
282                 }
283
284                 [MonoTODO]
285                 public XPathAtomicValue Clone ()
286                 {
287                         return new XPathAtomicValue (this, schemaType);
288                 }
289
290                 [MonoTODO]
291                 public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
292                 {
293                         switch (XmlTypeCodeFromRuntimeType (type, false)) {
294                         case XmlTypeCode.Int:
295                         case XmlTypeCode.Short:
296                         case XmlTypeCode.UnsignedShort:
297                                 return ValueAsInt32;
298                         case XmlTypeCode.Decimal:
299                                 return ValueAsDecimal;
300                         case XmlTypeCode.Double:
301                                 return ValueAsDouble;
302                         case XmlTypeCode.Float:
303                                 return ValueAsSingle;
304                         case XmlTypeCode.Long:
305                         case XmlTypeCode.UnsignedInt:
306                                 return ValueAsInt64;
307                         case XmlTypeCode.String:
308                                 return Value;
309                         case XmlTypeCode.DateTime:
310                                 return ValueAsDateTime;
311                         case XmlTypeCode.Boolean:
312                                 return ValueAsBoolean;
313                         case XmlTypeCode.Item:
314                                 return TypedValue;
315                         case XmlTypeCode.QName:
316                                 return XmlQualifiedName.Parse (Value, nsResolver);
317                         }
318                         if (type.GetInterface ("System.Collections.ICollection") != null)
319                                 return ValueAsList;
320                         throw new NotImplementedException ();
321                 }
322
323                 #endregion
324
325                 #region Properties
326
327                 // As long as I tried, neither of such XPathAtomicValue created
328                 // with XmlText that contains atomic value, XmlElement that
329                 // contains such XmlText, XmlDocument nor XPathNavigator 
330                 // created from such nodes returned false. So it won't be 
331                 // true on this class. Apparently this class needs more
332                 // documentation.
333                 public override bool IsNode {
334                         get { return false; }
335                 }
336
337                 internal XmlTypeCode ResolvedTypeCode {
338                         get {
339                                 if (schemaType != XmlSchemaComplexType.AnyType)
340                                         return schemaType.TypeCode;
341                                 else
342                                         return xmlTypeCode;
343                         }
344                 }
345
346                 [MonoTODO]
347                 public override object TypedValue {
348                         get {
349                                 switch (ResolvedTypeCode) {
350                                 case XmlTypeCode.Boolean:
351                                         return ValueAsBoolean;
352                                 case XmlTypeCode.DateTime:
353                                         return ValueAsDateTime;
354                                 case XmlTypeCode.Decimal:
355                                         return ValueAsDecimal;
356                                 case XmlTypeCode.Double:
357                                         return ValueAsDouble;
358                                 case XmlTypeCode.Long:
359                                         return ValueAsInt64;
360                                 case XmlTypeCode.Int:
361                                         return ValueAsInt32;
362                                 case XmlTypeCode.Float:
363                                         return ValueAsSingle;
364                                 case XmlTypeCode.String:
365                                         return Value;
366                                 }
367                                 return objectValue;
368                         }
369                 }
370
371                 [MonoTODO]
372                 // This method works like ValueAsString.
373                 public override string Value {
374                         get {
375                                 switch (ResolvedTypeCode) {
376                                 case XmlTypeCode.Boolean:
377                                         stringValue = XQueryConvert.BooleanToString (ValueAsBoolean);
378                                         break;
379                                 case XmlTypeCode.DateTime:
380                                         stringValue = XQueryConvert.DateTimeToString (ValueAsDateTime);
381                                         break;
382                                 case XmlTypeCode.Decimal:
383                                         stringValue = XQueryConvert.DecimalToString (ValueAsDecimal);
384                                         break;
385                                 case XmlTypeCode.Double:
386                                         stringValue = XQueryConvert.DoubleToString (ValueAsDouble);
387                                         break;
388                                 case XmlTypeCode.Long:
389                                         stringValue = XQueryConvert.IntegerToString (ValueAsInt64);
390                                         break;
391                                 case XmlTypeCode.Int:
392                                         stringValue = XQueryConvert.IntToString (ValueAsInt32);
393                                         break;
394                                 case XmlTypeCode.Float:
395                                         stringValue = XQueryConvert.FloatToString (ValueAsSingle);
396                                         break;
397                                 case XmlTypeCode.String:
398                                         return stringValue;
399
400                                 case XmlTypeCode.None:
401                                 case XmlTypeCode.Item:
402                                 case XmlTypeCode.AnyAtomicType:
403                                         switch (XmlTypeCodeFromRuntimeType (objectValue.GetType (), false)) {
404                                         case XmlTypeCode.String:
405                                                 stringValue = (string) objectValue;
406                                                 break;
407                                         case XmlTypeCode.DateTime:
408                                                 stringValue = XQueryConvert.DateTimeToString ((DateTime) objectValue);
409                                                 break;
410                                         case XmlTypeCode.Boolean:
411                                                 stringValue = XQueryConvert.BooleanToString ((bool) objectValue);
412                                                 break;
413                                         case XmlTypeCode.Float:
414                                                 stringValue = XQueryConvert.FloatToString ((float) objectValue);
415                                                 break;
416                                         case XmlTypeCode.Double:
417                                                 stringValue = XQueryConvert.DoubleToString ((double) objectValue);
418                                                 break;
419                                         case XmlTypeCode.Decimal:
420                                                 stringValue = XQueryConvert.DecimalToString ((decimal) objectValue);
421                                                 break;
422                                         case XmlTypeCode.Long:
423                                                 stringValue = XQueryConvert.IntegerToString ((long) objectValue);
424                                                 break;
425                                         case XmlTypeCode.Int:
426                                                 stringValue = XQueryConvert.IntToString ((int) objectValue);
427                                                 break;
428                                         }
429                                         break;
430                                 }
431                                 if (stringValue != null)
432                                         return stringValue;
433
434                                 if (objectValue != null)
435                                         throw new InvalidCastException (String.Format ("Conversion from runtime type {0} to {1} is not supported", objectValue.GetType (), XmlTypeCode.String));
436                                 else
437                                         throw new InvalidCastException (String.Format ("Conversion from schema type {0} (type code {1}) to {2} is not supported", schemaType.QualifiedName, xmlTypeCode, XmlTypeCode.String));
438                         }
439                 }
440
441                 [MonoTODO]
442                 public override bool ValueAsBoolean {
443                         get {
444                                 switch (xmlTypeCode) {
445                                 case XmlTypeCode.Boolean:
446                                         return booleanValue;
447                                 case XmlTypeCode.Decimal:
448                                         return XQueryConvert.DecimalToBoolean (decimalValue);
449                                 case XmlTypeCode.Double:
450                                         return XQueryConvert.DoubleToBoolean (doubleValue);
451                                 case XmlTypeCode.Long:
452                                         return XQueryConvert.IntegerToBoolean (longValue);
453                                 case XmlTypeCode.Int:
454                                         return XQueryConvert.IntToBoolean (intValue);
455                                 case XmlTypeCode.Float:
456                                         return XQueryConvert.FloatToBoolean (floatValue);
457                                 case XmlTypeCode.String:
458                                         return XQueryConvert.StringToBoolean (stringValue);
459
460                                 case XmlTypeCode.None:
461                                 case XmlTypeCode.Item:
462                                 case XmlTypeCode.AnyAtomicType:
463                                         if (objectValue is bool)
464                                                 return (bool) objectValue;
465                                         break;
466
467                                 }
468
469                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsBoolean.QualifiedName));
470                         }
471                 }
472
473                 [MonoTODO]
474                 public override DateTime ValueAsDateTime {
475                         get {
476                                 switch (xmlTypeCode) {
477                                 case XmlTypeCode.DateTime:
478                                         return dateTimeValue;
479                                 case XmlTypeCode.String:
480                                         return XQueryConvert.StringToDateTime (stringValue);
481                                 case XmlTypeCode.None:
482                                 case XmlTypeCode.Item:
483                                 case XmlTypeCode.AnyAtomicType:
484                                         if (objectValue is DateTime)
485                                                 return (DateTime) objectValue;
486                                         break;
487
488                                 }
489
490                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDateTime.QualifiedName));
491                         }
492                 }
493
494                 [MonoTODO]
495                 public override decimal ValueAsDecimal {
496                         get {
497                                 switch (xmlTypeCode) {
498                                 case XmlTypeCode.Boolean:
499                                         return XQueryConvert.BooleanToDecimal (booleanValue);
500                                 case XmlTypeCode.Decimal:
501                                         return decimalValue;
502                                 case XmlTypeCode.Double:
503                                         return XQueryConvert.DoubleToDecimal (doubleValue);
504                                 case XmlTypeCode.Long:
505                                         return XQueryConvert.IntegerToDecimal (longValue);
506                                 case XmlTypeCode.Int:
507                                         return XQueryConvert.IntToDecimal (intValue);
508                                 case XmlTypeCode.Float:
509                                         return XQueryConvert.FloatToDecimal (floatValue);
510                                 case XmlTypeCode.String:
511                                         return XQueryConvert.StringToDecimal (stringValue);
512                                 case XmlTypeCode.None:
513                                 case XmlTypeCode.Item:
514                                 case XmlTypeCode.AnyAtomicType:
515                                         if (objectValue is decimal)
516                                                 return (decimal) objectValue;
517                                         break;
518
519                                 }
520
521                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDecimal.QualifiedName));
522                         }
523                 }
524
525                 [MonoTODO]
526                 public override double ValueAsDouble {
527                         get {
528                                 switch (xmlTypeCode) {
529                                 case XmlTypeCode.Boolean:
530                                         return XQueryConvert.BooleanToDouble (booleanValue);
531                                 case XmlTypeCode.Decimal:
532                                         return XQueryConvert.DecimalToDouble (decimalValue);
533                                 case XmlTypeCode.Double:
534                                         return doubleValue;
535                                 case XmlTypeCode.Long:
536                                         return XQueryConvert.IntegerToDouble (longValue);
537                                 case XmlTypeCode.Int:
538                                         return XQueryConvert.IntToDouble (intValue);
539                                 case XmlTypeCode.Float:
540                                         return XQueryConvert.FloatToDouble (floatValue);
541                                 case XmlTypeCode.String:
542                                         return XQueryConvert.StringToDouble (stringValue);
543                                 case XmlTypeCode.None:
544                                 case XmlTypeCode.Item:
545                                 case XmlTypeCode.AnyAtomicType:
546                                         if (objectValue is double)
547                                                 return (double) objectValue;
548                                         break;
549
550                                 }
551
552                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDouble.QualifiedName));
553                         }
554                 }
555
556                 [MonoTODO]
557                 public override int ValueAsInt32 {
558                         get {
559                                 switch (xmlTypeCode) {
560                                 case XmlTypeCode.Boolean:
561                                         return XQueryConvert.BooleanToInt (booleanValue);
562                                 case XmlTypeCode.Decimal:
563                                         return XQueryConvert.DecimalToInt (decimalValue);
564                                 case XmlTypeCode.Double:
565                                         return XQueryConvert.DoubleToInt (doubleValue);
566                                 case XmlTypeCode.Long:
567                                         return XQueryConvert.IntegerToInt (longValue);
568                                 case XmlTypeCode.Int:
569                                         return intValue;
570                                 case XmlTypeCode.Float:
571                                         return XQueryConvert.FloatToInt (floatValue);
572                                 case XmlTypeCode.String:
573                                         return XQueryConvert.StringToInt (stringValue);
574                                 case XmlTypeCode.None:
575                                 case XmlTypeCode.Item:
576                                 case XmlTypeCode.AnyAtomicType:
577                                         if (objectValue is int)
578                                                 return (int) objectValue;
579                                         break;
580
581                                 }
582
583                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsInt.QualifiedName));
584                         }
585                 }
586
587                 [MonoTODO]
588                 public override long ValueAsInt64 {
589                         get {
590                                 switch (xmlTypeCode) {
591                                 case XmlTypeCode.Boolean:
592                                         return XQueryConvert.BooleanToInteger (booleanValue);
593                                 case XmlTypeCode.Decimal:
594                                         return XQueryConvert.DecimalToInteger (decimalValue);
595                                 case XmlTypeCode.Double:
596                                         return XQueryConvert.DoubleToInteger (doubleValue);
597                                 case XmlTypeCode.Long:
598                                         return longValue;
599                                 case XmlTypeCode.Int:
600                                         return XQueryConvert.IntegerToInt (intValue);
601                                 case XmlTypeCode.Float:
602                                         return XQueryConvert.FloatToInteger (floatValue);
603                                 case XmlTypeCode.String:
604                                         return XQueryConvert.StringToInteger (stringValue);
605                                 case XmlTypeCode.None:
606                                 case XmlTypeCode.Item:
607                                 case XmlTypeCode.AnyAtomicType:
608                                         if (objectValue is long)
609                                                 return (long) objectValue;
610                                         break;
611
612                                 }
613
614                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsLong.QualifiedName));
615                         }
616                 }
617
618                 [MonoTODO]
619                 public override float ValueAsSingle {
620                         get {
621                                 switch (xmlTypeCode) {
622                                 case XmlTypeCode.Boolean:
623                                         return XQueryConvert.BooleanToFloat (booleanValue);
624                                 case XmlTypeCode.Decimal:
625                                         return XQueryConvert.DecimalToFloat (decimalValue);
626                                 case XmlTypeCode.Double:
627                                         return XQueryConvert.DoubleToFloat (doubleValue);
628                                 case XmlTypeCode.Float:
629                                         return floatValue;
630                                 case XmlTypeCode.Int:
631                                         return XQueryConvert.FloatToInt (intValue);
632                                 case XmlTypeCode.Long:
633                                         return XQueryConvert.IntegerToFloat (longValue);
634                                 case XmlTypeCode.String:
635                                         return XQueryConvert.StringToFloat (stringValue);
636                                 case XmlTypeCode.None:
637                                 case XmlTypeCode.Item:
638                                 case XmlTypeCode.AnyAtomicType:
639                                         if (objectValue is float)
640                                                 return (float) objectValue;
641                                         break;
642
643                                 }
644
645                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsFloat.QualifiedName));
646                         }
647                 }
648
649                 [MonoTODO]
650                 public override ICollection ValueAsList {
651                         get {
652                                 if (valueAsList != null)
653                                         return valueAsList;
654                                 if (objectValue is ICollection)
655                                         valueAsList = objectValue as ICollection;
656                                 else if (objectValue is Array)
657                                         valueAsList = new ArrayList ((Array) objectValue);
658                                 else if (xmlTypeCode != XmlTypeCode.None) {
659                                         ArrayList al = new ArrayList ();
660                                         al.Add (TypedValue);
661                                         valueAsList = al;
662                                 }
663                                 else
664                                         throw new NotImplementedException ();
665                                 return valueAsList;
666                         }
667                 }
668
669                 [MonoTODO]
670                 public override Type ValueType {
671                         get { return schemaType.Datatype.ValueType; }
672                 }
673
674                 [MonoTODO]
675                 public override XmlSchemaType XmlType {
676                         get { return schemaType; }
677                 }
678
679                 #endregion
680
681                 #region internal static members
682
683                 internal static Type RuntimeTypeFromXmlTypeCode (XmlTypeCode typeCode)
684                 {
685                         switch (typeCode) {
686                         case XmlTypeCode.Int:
687                                 return typeof (int);
688                         case XmlTypeCode.Decimal:
689                                 return typeof (decimal);
690                         case XmlTypeCode.Double:
691                                 return typeof (double);
692                         case XmlTypeCode.Float:
693                                 return typeof (float);
694                         case XmlTypeCode.Long:
695                                 return typeof (long);
696                         case XmlTypeCode.Short:
697                                 return typeof (short);
698                         case XmlTypeCode.UnsignedShort:
699                                 return typeof (ushort);
700                         case XmlTypeCode.UnsignedInt:
701                                 return typeof (uint);
702                         case XmlTypeCode.String:
703                                 return typeof (string);
704                         case XmlTypeCode.DateTime:
705                                 return typeof (DateTime);
706                         case XmlTypeCode.Boolean:
707                                 return typeof (bool);
708                         case XmlTypeCode.Item:
709                                 return typeof (object);
710                         }
711                         throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer Runtime Type from XmlTypeCode {0}.", typeCode));
712                 }
713
714                 internal static XmlTypeCode XmlTypeCodeFromRuntimeType (Type cliType, bool raiseError)
715                 {
716                         switch (Type.GetTypeCode (cliType)) {
717                         case TypeCode.Int32:
718                                 return XmlTypeCode.Int;
719                         case TypeCode.Decimal:
720                                 return XmlTypeCode.Decimal;
721                         case TypeCode.Double:
722                                 return XmlTypeCode.Double;
723                         case TypeCode.Single:
724                                 return XmlTypeCode.Float;
725                         case TypeCode.Int64:
726                                 return XmlTypeCode.Long;
727                         case TypeCode.Int16:
728                                 return XmlTypeCode.Short;
729                         case TypeCode.UInt16:
730                                 return XmlTypeCode.UnsignedShort;
731                         case TypeCode.UInt32:
732                                 return XmlTypeCode.UnsignedInt;
733                         case TypeCode.String:
734                                 return XmlTypeCode.String;
735                         case TypeCode.DateTime:
736                                 return XmlTypeCode.DateTime;
737                         case TypeCode.Boolean:
738                                 return XmlTypeCode.Boolean;
739                         case TypeCode.Object:
740                                 return XmlTypeCode.Item;
741                         }
742                         if (raiseError)
743                                 throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer XmlTypeCode from Runtime Type {0}", cliType));
744                         else
745                                 return XmlTypeCode.None;
746                 }
747                 #endregion
748         }
749 }
750
751 #endif