1 using System;
   2 using System.Collections;
   3 using System.IO;
   4 
   5 // this file has been semiautomatically generated from 'D:/work/soulng-project/sngxml/xpath/XPathExpr.hpp' using cpp2cm version 1.0.0
   6 
   7 // this file has been semiautomatically generated from 'D:/work/soulng-project/sngxml/xpath/XPathExpr.cpp' using cpp2cm version 1.0.0
   8 
   9 namespace System.XPath
  10 {
  11     using Axis = System.Dom.Axis;
  12     using NodeType = System.Dom.NodeType;
  13     public enum Operator
  14     {
  15         equalnotEquallessgreaterlessOrEqualgreaterOrEqualplusminusmuldivmodslashslashSlash
  16     }
  17     public abstract class XPathExpr
  18     {
  19         public suppress XPathExpr(const XPathExpr&);
  20         public suppress XPathExpr(XPathExpr&&);
  21         public XPathExpr()
  22         {
  23         }
  24         public virtual ~XPathExpr()
  25         {
  26         }
  27         public suppress XPathExpr& operator=(const XPathExpr&);
  28         public suppress XPathExpr&& operator=(XPathExpr&&);
  29         public virtual UniquePtr<XPathObject> Evaluate(XPathContext& context)
  30         {
  31             return UniquePtr<XPathObject>();
  32         }
  33         public virtual ustring TextValue() const
  34         {
  35             return ustring();
  36         }
  37         public abstract UniquePtr<System.Dom.Node> ToDom() const;
  38     }
  39     public abstract class XPathUnaryExpr : XPathExpr
  40     {
  41         public XPathUnaryExpr(XPathExpr* operand_) : 
  42             operand(operand_)
  43         {
  44         }
  45         public XPathExpr* Operand() const
  46         {
  47             return operand.Get();
  48         }
  49         private UniquePtr<XPathExpr> operand;
  50     }
  51     public abstract class XPathBinaryExpr : XPathExpr
  52     {
  53         public XPathBinaryExpr(XPathExpr* left_XPathExpr* right_) : 
  54             left(left_)right(right_)
  55         {
  56         }
  57         public XPathExpr* Left() const
  58         {
  59             return left.Get();
  60         }
  61         public XPathExpr* Right() const
  62         {
  63             return right.Get();
  64         }
  65         private UniquePtr<XPathExpr> left;
  66         private UniquePtr<XPathExpr> right;
  67     }
  68     public class XPathOrExpr : XPathBinaryExpr
  69     {
  70         public XPathOrExpr(XPathExpr* left_XPathExpr* right_) : 
  71             base(left_right_)
  72         {
  73         }
  74         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
  75         {
  76             XPathFunction* boolean = GetXPathLibraryFunction(u"boolean");
  77             UniquePtr<XPathObject> left = Left()->Evaluate(context);
  78             List<XPathObject*> leftArgs;
  79             leftArgs.Add(left.Get());
  80             UniquePtr<XPathObject> leftAsBoolean = boolean->Evaluate(contextleftArgs);
  81             if (leftAsBoolean->Type() != XPathObjectType.boolean)
  82             {
  83                 throw Exception("boolean result expected");
  84             }
  85             if (cast<XPathBoolean*>(leftAsBoolean.Get())->Value())
  86             {
  87                 return leftAsBoolean;
  88             }
  89             UniquePtr<XPathObject> right = Right()->Evaluate(context);
  90             List<XPathObject*> rightArgs;
  91             rightArgs.Add(right.Get());
  92             UniquePtr<XPathObject> rightAsBoolean = boolean->Evaluate(contextrightArgs);
  93             if (rightAsBoolean->Type() != XPathObjectType.boolean)
  94             {
  95                 throw Exception("boolean result expected");
  96             }
  97             return rightAsBoolean;
  98         }
  99         public override UniquePtr<System.Dom.Node> ToDom() const
 100         {
 101             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"or"));
 102             element->AppendChild(Left()->ToDom());
 103             element->AppendChild(Right()->ToDom());
 104             return UniquePtr<System.Dom.Node>(element.Release());
 105         }
 106     }
 107     public class XPathAndExpr : XPathBinaryExpr
 108     {
 109         public XPathAndExpr(XPathExpr* left_XPathExpr* right_) : 
 110             base(left_right_)
 111         {
 112         }
 113         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 114         {
 115             XPathFunction* boolean = GetXPathLibraryFunction(u"boolean");
 116             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 117             List<XPathObject*> leftArgs;
 118             leftArgs.Add(left.Get());
 119             UniquePtr<XPathObject> leftAsBoolean = boolean->Evaluate(contextleftArgs);
 120             if (leftAsBoolean->Type() != XPathObjectType.boolean)
 121             {
 122                 throw Exception("boolean result expected");
 123             }
 124             if (!cast<XPathBoolean*>(leftAsBoolean.Get())->Value())
 125             {
 126                 return leftAsBoolean;
 127             }
 128             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 129             List<XPathObject*> rightArgs;
 130             rightArgs.Add(right.Get());
 131             UniquePtr<XPathObject> rightAsBoolean = boolean->Evaluate(contextrightArgs);
 132             if (rightAsBoolean->Type() != XPathObjectType.boolean)
 133             {
 134                 throw Exception("boolean result expected");
 135             }
 136             return rightAsBoolean;
 137         }
 138         public override UniquePtr<System.Dom.Node> ToDom() const
 139         {
 140             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"and"));
 141             element->AppendChild(Left()->ToDom());
 142             element->AppendChild(Right()->ToDom());
 143             return UniquePtr<System.Dom.Node>(element.Release());
 144         }
 145     }
 146     public class XPathEqualExpr : XPathBinaryExpr
 147     {
 148         public XPathEqualExpr(XPathExpr* left_XPathExpr* right_) : 
 149             base(left_right_)
 150         {
 151         }
 152         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 153         {
 154             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 155             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 156             return CompareEquality(contextleft.Get()right.Get());
 157         }
 158         public override UniquePtr<System.Dom.Node> ToDom() const
 159         {
 160             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"equal"));
 161             element->AppendChild(Left()->ToDom());
 162             element->AppendChild(Right()->ToDom());
 163             return UniquePtr<System.Dom.Node>(element.Release());
 164         }
 165     }
 166     public class XPathNotEqualExpr : XPathBinaryExpr
 167     {
 168         public XPathNotEqualExpr(XPathExpr* left_XPathExpr* right_) : 
 169             base(left_right_)
 170         {
 171         }
 172         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 173         {
 174             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 175             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 176             UniquePtr<XPathObject> equal = CompareEquality(contextleft.Get()right.Get());
 177             if (equal->Type() != XPathObjectType.boolean)
 178             {
 179                 throw Exception("boolean result expected");
 180             }
 181             return UniquePtr<XPathObject>(new XPathBoolean(!cast<XPathBoolean*>(equal.Get())->Value()));
 182         }
 183         public override UniquePtr<System.Dom.Node> ToDom() const
 184         {
 185             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"notEqual"));
 186             element->AppendChild(Left()->ToDom());
 187             element->AppendChild(Right()->ToDom());
 188             return UniquePtr<System.Dom.Node>(element.Release());
 189         }
 190     }
 191     public class XPathLessExpr : XPathBinaryExpr
 192     {
 193         public XPathLessExpr(XPathExpr* left_XPathExpr* right_) : 
 194             base(left_right_)
 195         {
 196         }
 197         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 198         {
 199             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 200             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 201             return Compare(contextleft.Get()right.Get()Operator.less);
 202         }
 203         public override UniquePtr<System.Dom.Node> ToDom() const
 204         {
 205             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"less"));
 206             element->AppendChild(Left()->ToDom());
 207             element->AppendChild(Right()->ToDom());
 208             return UniquePtr<System.Dom.Node>(element.Release());
 209         }
 210     }
 211     public class XPathGreaterExpr : XPathBinaryExpr
 212     {
 213         public XPathGreaterExpr(XPathExpr* left_XPathExpr* right_) : 
 214             base(left_right_)
 215         {
 216         }
 217         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 218         {
 219             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 220             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 221             return Compare(contextleft.Get()right.Get()Operator.greater);
 222         }
 223         public override UniquePtr<System.Dom.Node> ToDom() const
 224         {
 225             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"greater"));
 226             element->AppendChild(Left()->ToDom());
 227             element->AppendChild(Right()->ToDom());
 228             return UniquePtr<System.Dom.Node>(element.Release());
 229         }
 230     }
 231     public class XPathLessOrEqualExpr : XPathBinaryExpr
 232     {
 233         public XPathLessOrEqualExpr(XPathExpr* left_XPathExpr* right_) : 
 234             base(left_right_)
 235         {
 236         }
 237         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 238         {
 239             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 240             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 241             return Compare(contextleft.Get()right.Get()Operator.lessOrEqual);
 242         }
 243         public override UniquePtr<System.Dom.Node> ToDom() const
 244         {
 245             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"lessOrEqual"));
 246             element->AppendChild(Left()->ToDom());
 247             element->AppendChild(Right()->ToDom());
 248             return UniquePtr<System.Dom.Node>(element.Release());
 249         }
 250     }
 251     public class XPathGreaterOrEqualExpr : XPathBinaryExpr
 252     {
 253         public XPathGreaterOrEqualExpr(XPathExpr* left_XPathExpr* right_) : 
 254             base(left_right_)
 255         {
 256         }
 257         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 258         {
 259             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 260             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 261             return Compare(contextleft.Get()right.Get()Operator.greaterOrEqual);
 262         }
 263         public override UniquePtr<System.Dom.Node> ToDom() const
 264         {
 265             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"greaterOrEqual"));
 266             element->AppendChild(Left()->ToDom());
 267             element->AppendChild(Right()->ToDom());
 268             return UniquePtr<System.Dom.Node>(element.Release());
 269         }
 270     }
 271     public class XPathAddExpr : XPathBinaryExpr
 272     {
 273         public XPathAddExpr(XPathExpr* left_XPathExpr* right_) : 
 274             base(left_right_)
 275         {
 276         }
 277         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 278         {
 279             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 280             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 281             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
 282             List<XPathObject*> leftArgs;
 283             leftArgs.Add(left.Get());
 284             UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
 285             if (leftAsNumber->Type() != XPathObjectType.number)
 286             {
 287                 throw Exception("number result expected");
 288             }
 289             double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
 290             List<XPathObject*> rightArgs;
 291             rightArgs.Add(right.Get());
 292             UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
 293             if (rightAsNumber->Type() != XPathObjectType.number)
 294             {
 295                 throw Exception("number result expected");
 296             }
 297             double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
 298             return UniquePtr<XPathObject>(new XPathNumber(leftNumber + rightNumber));
 299         }
 300         public override UniquePtr<System.Dom.Node> ToDom() const
 301         {
 302             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"add"));
 303             element->AppendChild(Left()->ToDom());
 304             element->AppendChild(Right()->ToDom());
 305             return UniquePtr<System.Dom.Node>(element.Release());
 306         }
 307     }
 308     public class XPathSubExpr : XPathBinaryExpr
 309     {
 310         public XPathSubExpr(XPathExpr* left_XPathExpr* right_) : 
 311             base(left_right_)
 312         {
 313         }
 314         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 315         {
 316             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 317             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 318             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
 319             List<XPathObject*> leftArgs;
 320             leftArgs.Add(left.Get());
 321             UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
 322             if (leftAsNumber->Type() != XPathObjectType.number)
 323             {
 324                 throw Exception("number result expected");
 325             }
 326             double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
 327             List<XPathObject*> rightArgs;
 328             rightArgs.Add(right.Get());
 329             UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
 330             if (rightAsNumber->Type() != XPathObjectType.number)
 331             {
 332                 throw Exception("number result expected");
 333             }
 334             double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
 335             return UniquePtr<XPathObject>(new XPathNumber(leftNumber - rightNumber));
 336         }
 337         public override UniquePtr<System.Dom.Node> ToDom() const
 338         {
 339             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"sub"));
 340             element->AppendChild(Left()->ToDom());
 341             element->AppendChild(Right()->ToDom());
 342             return UniquePtr<System.Dom.Node>(element.Release());
 343         }
 344     }
 345     public class XPathMulExpr : XPathBinaryExpr
 346     {
 347         public XPathMulExpr(XPathExpr* left_XPathExpr* right_) : 
 348             base(left_right_)
 349         {
 350         }
 351         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 352         {
 353             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 354             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 355             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
 356             List<XPathObject*> leftArgs;
 357             leftArgs.Add(left.Get());
 358             UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
 359             if (leftAsNumber->Type() != XPathObjectType.number)
 360             {
 361                 throw Exception("number result expected");
 362             }
 363             double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
 364             List<XPathObject*> rightArgs;
 365             rightArgs.Add(right.Get());
 366             UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
 367             if (rightAsNumber->Type() != XPathObjectType.number)
 368             {
 369                 throw Exception("number result expected");
 370             }
 371             double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
 372             return UniquePtr<XPathObject>(new XPathNumber(leftNumber * rightNumber));
 373         }
 374         public override UniquePtr<System.Dom.Node> ToDom() const
 375         {
 376             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"mul"));
 377             element->AppendChild(Left()->ToDom());
 378             element->AppendChild(Right()->ToDom());
 379             return UniquePtr<System.Dom.Node>(element.Release());
 380         }
 381     }
 382     public class XPathDivExpr : XPathBinaryExpr
 383     {
 384         public XPathDivExpr(XPathExpr* left_XPathExpr* right_) : 
 385             base(left_right_)
 386         {
 387         }
 388         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 389         {
 390             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 391             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 392             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
 393             List<XPathObject*> leftArgs;
 394             leftArgs.Add(left.Get());
 395             UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
 396             if (leftAsNumber->Type() != XPathObjectType.number)
 397             {
 398                 throw Exception("number result expected");
 399             }
 400             double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
 401             List<XPathObject*> rightArgs;
 402             rightArgs.Add(right.Get());
 403             UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
 404             if (rightAsNumber->Type() != XPathObjectType.number)
 405             {
 406                 throw Exception("number result expected");
 407             }
 408             double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
 409             return UniquePtr<XPathObject>(new XPathNumber(leftNumber / rightNumber));
 410         }
 411         public override UniquePtr<System.Dom.Node> ToDom() const
 412         {
 413             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"div"));
 414             element->AppendChild(Left()->ToDom());
 415             element->AppendChild(Right()->ToDom());
 416             return UniquePtr<System.Dom.Node>(element.Release());
 417         }
 418     }
 419     public class XPathModExpr : XPathBinaryExpr
 420     {
 421         public XPathModExpr(XPathExpr* left_XPathExpr* right_) : 
 422             base(left_right_)
 423         {
 424         }
 425         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 426         {
 427             UniquePtr<XPathObject> left = Left()->Evaluate(context);
 428             UniquePtr<XPathObject> right = Right()->Evaluate(context);
 429             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
 430             List<XPathObject*> leftArgs;
 431             leftArgs.Add(left.Get());
 432             UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
 433             if (leftAsNumber->Type() != XPathObjectType.number)
 434             {
 435                 throw Exception("number result expected");
 436             }
 437             long leftNumber = cast<long>(cast<XPathNumber*>(leftAsNumber.Get())->Value());
 438             List<XPathObject*> rightArgs;
 439             rightArgs.Add(right.Get());
 440             UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
 441             if (rightAsNumber->Type() != XPathObjectType.number)
 442             {
 443                 throw Exception("number result expected");
 444             }
 445             long rightNumber = cast<long>(cast<XPathNumber*>(rightAsNumber.Get())->Value());
 446             return UniquePtr<XPathObject>(new XPathNumber(double(leftNumber % rightNumber)));
 447         }
 448         public override UniquePtr<System.Dom.Node> ToDom() const
 449         {
 450             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"mod"));
 451             element->AppendChild(Left()->ToDom());
 452             element->AppendChild(Right()->ToDom());
 453             return UniquePtr<System.Dom.Node>(element.Release());
 454         }
 455     }
 456     public class XPathUnaryMinusExpr : XPathUnaryExpr
 457     {
 458         public XPathUnaryMinusExpr(XPathExpr* operand_) : 
 459             base(operand_)
 460         {
 461         }
 462         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 463         {
 464             UniquePtr<XPathObject> operand = Operand()->Evaluate(context);
 465             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
 466             List<XPathObject*> operandArgs;
 467             operandArgs.Add(operand.Get());
 468             UniquePtr<XPathObject> operandAsNumber = numberFunction->Evaluate(contextoperandArgs);
 469             if (operandAsNumber->Type() != XPathObjectType.number)
 470             {
 471                 throw Exception("number result expected");
 472             }
 473             double operandNumber = cast<XPathNumber*>(operandAsNumber.Get())->Value();
 474             return UniquePtr<XPathObject>(new XPathNumber(-operandNumber));
 475         }
 476         public override UniquePtr<System.Dom.Node> ToDom() const
 477         {
 478             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"unaryMinus"));
 479             element->AppendChild(Operand()->ToDom());
 480             return UniquePtr<System.Dom.Node>(element.Release());
 481         }
 482     }
 483     public class XPathUnionExpr : XPathBinaryExpr
 484     {
 485         public XPathUnionExpr(XPathExpr* left_XPathExpr* right_) : 
 486             base(left_right_)
 487         {
 488         }
 489         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 490         {
 491             UniquePtr<XPathNodeSet> result(new XPathNodeSet());
 492             UniquePtr<XPathObject> leftResult = Left()->Evaluate(context);
 493             if (leftResult->Type() != XPathObjectType.nodeSet)
 494             {
 495                 throw Exception("node set expected");
 496             }
 497             XPathNodeSet* leftNodeSet = cast<XPathNodeSet*>(leftResult.Get());
 498             int n = leftNodeSet->Length();
 499             for (int i = 0; i < n; ++i;)
 500             {
 501                 result->Add((*leftNodeSet)[i]);
 502             }
 503             UniquePtr<XPathObject> rightResult = Right()->Evaluate(context);
 504             if (rightResult->Type() != XPathObjectType.nodeSet)
 505             {
 506                 throw Exception("node set expected");
 507             }
 508             XPathNodeSet* rightNodeSet = cast<XPathNodeSet*>(rightResult.Get());
 509             int m = rightNodeSet->Length();
 510             for (int i = 0; i < m; ++i;)
 511             {
 512                 result->Add((*rightNodeSet)[i]);
 513             }
 514             return UniquePtr<XPathObject>(result.Release());
 515         }
 516         public override UniquePtr<System.Dom.Node> ToDom() const
 517         {
 518             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"union"));
 519             element->AppendChild(Left()->ToDom());
 520             element->AppendChild(Right()->ToDom());
 521             return UniquePtr<System.Dom.Node>(element.Release());
 522         }
 523     }
 524     public class XPathCombineStepExpr : XPathBinaryExpr
 525     {
 526         public XPathCombineStepExpr(XPathExpr* left_XPathExpr* right_) : 
 527             base(left_right_)
 528         {
 529         }
 530         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 531         {
 532             UniquePtr<XPathNodeSet> result(new XPathNodeSet());
 533             UniquePtr<XPathObject> leftResult = Left()->Evaluate(context);
 534             if (leftResult->Type() != XPathObjectType.nodeSet)
 535             {
 536                 throw Exception("node set expected");
 537             }
 538             XPathNodeSet* leftNodeSet = cast<XPathNodeSet*>(leftResult.Get());
 539             int n = leftNodeSet->Length();
 540             for (int i = 0; i < n; ++i;)
 541             {
 542                 System.Dom.Node* node = (*leftNodeSet)[i];
 543                 XPathContext rightContext(nodei + 1n);
 544                 UniquePtr<XPathObject> rightResult = Right()->Evaluate(rightContext);
 545                 if (rightResult->Type() != XPathObjectType.nodeSet)
 546                 {
 547                     throw Exception("node set expected");
 548                 }
 549                 XPathNodeSet* rightNodeSet = cast<XPathNodeSet*>(rightResult.Get());
 550                 int m = rightNodeSet->Length();
 551                 for (int i = 0; i < m; ++i;)
 552                 {
 553                     System.Dom.Node* node = (*rightNodeSet)[i];
 554                     result->Add(node);
 555                 }
 556             }
 557             return UniquePtr<XPathObject>(result.Release());
 558         }
 559         public override UniquePtr<System.Dom.Node> ToDom() const
 560         {
 561             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"combineStep"));
 562             element->AppendChild(Left()->ToDom());
 563             element->AppendChild(Right()->ToDom());
 564             return UniquePtr<System.Dom.Node>(element.Release());
 565         }
 566     }
 567     public class XPathRootNodeExpr : XPathExpr
 568     {
 569         public XPathRootNodeExpr()
 570         {
 571         }
 572         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 573         {
 574             UniquePtr<XPathNodeSet> nodeSet(new XPathNodeSet());
 575             if (context.Node()->GetNodeType() == NodeType.documentNode)
 576             {
 577                 nodeSet->Add(context.Node());
 578             }
 579             else
 580             {
 581                 nodeSet->Add(context.Node()->OwnerDocument());
 582             }
 583             return UniquePtr<XPathObject>(nodeSet.Release());
 584         }
 585         public override UniquePtr<System.Dom.Node> ToDom() const
 586         {
 587             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"root"));
 588             return UniquePtr<System.Dom.Node>(element.Release());
 589         }
 590     }
 591     public class XPathFilterExpr : XPathUnaryExpr
 592     {
 593         public XPathFilterExpr(XPathExpr* expr_XPathExpr* predicate_) : 
 594             base(expr_)predicate(predicate_)
 595         {
 596         }
 597         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 598         {
 599             UniquePtr<XPathObject> result = Operand()->Evaluate(context);
 600             if (result->Type() != XPathObjectType.nodeSet)
 601             {
 602                 throw Exception("node-set expected");
 603             }
 604             UniquePtr<XPathNodeSet> nodeSet(cast<XPathNodeSet*>(result.Release()));
 605             UniquePtr<XPathNodeSet> filteredNodeSet(new XPathNodeSet());
 606             int n = nodeSet->Length();
 607             for (int i = 0; i < n; ++i;)
 608             {
 609                 System.Dom.Node* node = (*nodeSet)[i];
 610                 XPathContext context(nodei + 1n);
 611                 UniquePtr<XPathObject> result = predicate->Evaluate(context);
 612                 bool booleanResult = false;
 613                 if (result->Type() == XPathObjectType.number)
 614                 {
 615                     XPathNumber* number = cast<XPathNumber*>(result.Get());
 616                     if (number->Value() == context.Position())
 617                     {
 618                         booleanResult = true;
 619                     }
 620                 }
 621                 else
 622                 {
 623                     XPathFunction* boolean = GetXPathLibraryFunction(u"boolean");
 624                     List<XPathObject*> args;
 625                     args.Add(result.Get());
 626                     UniquePtr<XPathObject> resultAsBoolean = boolean->Evaluate(contextargs);
 627                     booleanResult = cast<XPathBoolean*>(resultAsBoolean.Get())->Value();
 628                 }
 629                 if (booleanResult)
 630                 {
 631                     filteredNodeSet->Add(node);
 632                 }
 633             }
 634             Swap(nodeSetfilteredNodeSet);
 635             return UniquePtr<XPathObject>(nodeSet.Release());
 636         }
 637         public override UniquePtr<System.Dom.Node> ToDom() const
 638         {
 639             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"filter"));
 640             element->AppendChild(Operand()->ToDom());
 641             UniquePtr<System.Dom.Element> predicateElement(new System.Dom.Element(u"predicate"));
 642             predicateElement->AppendChild(predicate->ToDom());
 643             element->AppendChild(UniquePtr<System.Dom.Node>(predicateElement.Release()));
 644             return UniquePtr<System.Dom.Node>(element.Release());
 645         }
 646         private UniquePtr<XPathExpr> predicate;
 647     }
 648     public abstract class XPathNodeTestExpr : XPathExpr
 649     {
 650         public virtual bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 651         {
 652             return true;
 653         }
 654     }
 655     public class XPathLocationStepExpr : XPathExpr
 656     {
 657         public suppress XPathLocationStepExpr(const XPathLocationStepExpr&);
 658         public suppress XPathLocationStepExpr(XPathLocationStepExpr&&);
 659         public XPathLocationStepExpr(System.Dom.Axis axis_XPathNodeTestExpr* nodeTest_) : 
 660             axis(axis_)nodeTest(nodeTest_)
 661         {
 662         }
 663         public suppress XPathLocationStepExpr& operator=(const XPathLocationStepExpr&);
 664         public suppress XPathLocationStepExpr&& operator=(XPathLocationStepExpr&&);
 665         public void AddPredicate(XPathExpr* predicate)
 666         {
 667             predicates.Add(UniquePtr<XPathExpr>(predicate));
 668         }
 669         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 670         {
 671             UniquePtr<XPathNodeSet> nodeSet(new XPathNodeSet());
 672             NodeSelectionOp selectNodes(nodeTest.Get()*nodeSetaxis);
 673             context.Node()->Walk(selectNodesaxis);
 674             for (const UniquePtr<XPathExpr>& predicate : predicates)
 675             {
 676                 UniquePtr<XPathNodeSet> filteredNodeSet(new XPathNodeSet());
 677                 int n = nodeSet->Length();
 678                 for (int i = 0; i < n; ++i;)
 679                 {
 680                     System.Dom.Node* node = (*nodeSet)[i];
 681                     XPathContext context(nodei + 1n);
 682                     UniquePtr<XPathObject> result = predicate->Evaluate(context);
 683                     bool booleanResult = false;
 684                     if (result->Type() == XPathObjectType.number)
 685                     {
 686                         XPathNumber* number = cast<XPathNumber*>(result.Get());
 687                         if (number->Value() == context.Position())
 688                         {
 689                             booleanResult = true;
 690                         }
 691                     }
 692                     else
 693                     {
 694                         XPathFunction* boolean = GetXPathLibraryFunction(u"boolean");
 695                         List<XPathObject*> args;
 696                         args.Add(result.Get());
 697                         UniquePtr<XPathObject> resultAsBoolean = boolean->Evaluate(contextargs);
 698                         booleanResult = cast<XPathBoolean*>(resultAsBoolean.Get())->Value();
 699                     }
 700                     if (booleanResult)
 701                     {
 702                         filteredNodeSet->Add(node);
 703                     }
 704                 }
 705                 Swap(nodeSetfilteredNodeSet);
 706             }
 707             return UniquePtr<XPathObject>(nodeSet.Release());
 708         }
 709         public override UniquePtr<System.Dom.Node> ToDom() const
 710         {
 711             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"locationStep"));
 712             System.Dom.Element* axisElement = new System.Dom.Element(u"axis");
 713             ustring axisName =  System.Dom.AxisName(axis);
 714             axisElement->SetAttribute(u"name"axisName);
 715             element->AppendChild(UniquePtr<System.Dom.Node>(axisElement));
 716             System.Dom.Element* nodeTestElement = new System.Dom.Element(u"nodeTest");
 717             nodeTestElement->AppendChild(nodeTest->ToDom());
 718             element->AppendChild(UniquePtr<System.Dom.Node>(nodeTestElement));
 719             UniquePtr<System.Dom.Element> predicatesElement(new System.Dom.Element(u"predicates"));
 720             for (const UniquePtr<XPathExpr>& predicate : predicates)
 721             {
 722                 predicatesElement->AppendChild(predicate->ToDom());
 723             }
 724             element->AppendChild(UniquePtr<System.Dom.Node>(predicatesElement.Release()));
 725             return UniquePtr<System.Dom.Node>(element.Release());
 726         }
 727         private System.Dom.Axis axis;
 728         private UniquePtr<XPathNodeTestExpr> nodeTest;
 729         private List<UniquePtr<XPathExpr>> predicates;
 730     }
 731     public class XPathPILiteralTest : XPathNodeTestExpr
 732     {
 733         public XPathPILiteralTest(XPathExpr* literal_) : 
 734             literal(literal_)
 735         {
 736         }
 737         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 738         {
 739             if (node->GetNodeType() == NodeType.processingInstructionNode)
 740             {
 741                 System.Dom.ProcessingInstruction* pi = cast<System.Dom.ProcessingInstruction*>(node);
 742                 if (pi->Target() == literal->TextValue())
 743                 {
 744                     return true;
 745                 }
 746             }
 747             return false;
 748         }
 749         public override UniquePtr<System.Dom.Node> ToDom() const
 750         {
 751             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"piLiteralTest"));
 752             element->AppendChild(literal->ToDom());
 753             return UniquePtr<System.Dom.Node>(element.Release());
 754         }
 755         private UniquePtr<XPathExpr> literal;
 756     }
 757     public class XPathCommentNodeTest : XPathNodeTestExpr
 758     {
 759         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 760         {
 761             return node->GetNodeType() == NodeType.commentNode;
 762         }
 763         public override UniquePtr<System.Dom.Node> ToDom() const
 764         {
 765             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"commentNodeTest"));
 766             return UniquePtr<System.Dom.Node>(element.Release());
 767         }
 768     }
 769     public class XPathTextNodeTest : XPathNodeTestExpr
 770     {
 771         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 772         {
 773             return node->GetNodeType() == NodeType.textNode;
 774         }
 775         public override UniquePtr<System.Dom.Node> ToDom() const
 776         {
 777             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"textNodeTest"));
 778             return UniquePtr<System.Dom.Node>(element.Release());
 779         }
 780     }
 781     public class XPathPINodeTest : XPathNodeTestExpr
 782     {
 783         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 784         {
 785             return node->GetNodeType() == NodeType.processingInstructionNode;
 786         }
 787         public override UniquePtr<System.Dom.Node> ToDom() const
 788         {
 789             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"piNodeTest"));
 790             return UniquePtr<System.Dom.Node>(element.Release());
 791         }
 792     }
 793     public class XPathAnyNodeTest : XPathNodeTestExpr
 794     {
 795         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 796         {
 797             return true;
 798         }
 799         public override UniquePtr<System.Dom.Node> ToDom() const
 800         {
 801             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"anyNodeTest"));
 802             return UniquePtr<System.Dom.Node>(element.Release());
 803         }
 804     }
 805     public class XPathPrincipalNodeTest : XPathNodeTestExpr
 806     {
 807         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 808         {
 809             if (axis == Axis.attribute)
 810             {
 811                 return node->GetNodeType() == NodeType.attributeNode;
 812             }
 813             else if (axis == Axis.ns)
 814             {
 815                 return false;
 816             }
 817             else
 818             {
 819                 return node->GetNodeType() == NodeType.elementNode;
 820             }
 821         }
 822         public override UniquePtr<System.Dom.Node> ToDom() const
 823         {
 824             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"principalNodeTest"));
 825             return UniquePtr<System.Dom.Node>(element.Release());
 826         }
 827     }
 828     public class XPathPrefixTest : XPathNodeTestExpr
 829     {
 830         public XPathPrefixTest(const ustring& name_) : 
 831             name(name_)
 832         {
 833         }
 834         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 835         {
 836             if (axis == Axis.attribute)
 837             {
 838                 if (node->GetNodeType() == NodeType.attributeNode)
 839                 {
 840                     System.Dom.Attr* attr = cast<System.Dom.Attr*>(node);
 841                     if (attr->Prefix() == name)
 842                     {
 843                         return true;
 844                     }
 845                 }
 846             }
 847             else if (axis == Axis.ns)
 848             {
 849                 return false;
 850             }
 851             else if (node->GetNodeType() == NodeType.elementNode)
 852             {
 853                 System.Dom.Element* element = cast<System.Dom.Element*>(node);
 854                 if (element->Prefix() == name)
 855                 {
 856                     return true;
 857                 }
 858             }
 859             return false;
 860         }
 861         public override UniquePtr<System.Dom.Node> ToDom() const
 862         {
 863             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"prefixTest"));
 864             element->SetAttribute(u"prefix"name);
 865             return UniquePtr<System.Dom.Node>(element.Release());
 866         }
 867         private ustring name;
 868     }
 869     public class XPathNameTest : XPathNodeTestExpr
 870     {
 871         public XPathNameTest(const ustring& name_) : 
 872             name(name_)
 873         {
 874         }
 875         public override bool Select(System.Dom.Node* nodeSystem.Dom.Axis axis) const
 876         {
 877             if (axis == Axis.attribute)
 878             {
 879                 if (node->GetNodeType() == NodeType.attributeNode)
 880                 {
 881                     System.Dom.Attr* attr = cast<System.Dom.Attr*>(node);
 882                     if (attr->Name() == name)
 883                     {
 884                         return true;
 885                     }
 886                 }
 887             }
 888             else if (axis != Axis.ns)
 889             {
 890                 if (node->GetNodeType() == NodeType.elementNode)
 891                 {
 892                     System.Dom.Element* element = cast<System.Dom.Element*>(node);
 893                     if (element->Name() == name)
 894                     {
 895                         return true;
 896                     }
 897                 }
 898             }
 899             return false;
 900         }
 901         public override UniquePtr<System.Dom.Node> ToDom() const
 902         {
 903             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"nameTest"));
 904             element->SetAttribute(u"name"name);
 905             return UniquePtr<System.Dom.Node>(element.Release());
 906         }
 907         private ustring name;
 908     }
 909     public class XPathVariableReference : XPathExpr
 910     {
 911         public XPathVariableReference(const ustring& name_) : 
 912             name(name_)
 913         {
 914         }
 915         public override UniquePtr<System.Dom.Node> ToDom() const
 916         {
 917             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"variableReference"));
 918             element->SetAttribute(u"name"name);
 919             return UniquePtr<System.Dom.Node>(element.Release());
 920         }
 921         private ustring name;
 922     }
 923     public class XPathLiteral : XPathExpr
 924     {
 925         public XPathLiteral(const ustring& value_) : 
 926             value(value_)
 927         {
 928         }
 929         public override ustring TextValue() const
 930         {
 931             return value;
 932         }
 933         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 934         {
 935             return UniquePtr<XPathObject>(new XPathString(value));
 936         }
 937         public override UniquePtr<System.Dom.Node> ToDom() const
 938         {
 939             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"literal"));
 940             element->SetAttribute(u"value"value);
 941             return UniquePtr<System.Dom.Node>(element.Release());
 942         }
 943         private ustring value;
 944     }
 945     public class XPathNumberExpr : XPathExpr
 946     {
 947         public XPathNumberExpr(const ustring& value_)
 948         {
 949             string s = ToUtf8(value_);
 950             value = ParseDouble(ToUtf8(value_));
 951         }
 952         public XPathNumberExpr(double value_) : 
 953             value(value_)
 954         {
 955         }
 956         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 957         {
 958             return UniquePtr<XPathObject>(new XPathNumber(value));
 959         }
 960         public override UniquePtr<System.Dom.Node> ToDom() const
 961         {
 962             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"number"));
 963             element->SetAttribute(u"value"ToUtf32(ToString(value)));
 964             return UniquePtr<System.Dom.Node>(element.Release());
 965         }
 966         private double value;
 967     }
 968     public class XPathFunctionCall : XPathExpr
 969     {
 970         public XPathFunctionCall(const ustring& functionName_) : 
 971             functionName(functionName_)
 972         {
 973         }
 974         public void AddArgument(XPathExpr* argument)
 975         {
 976             arguments.Add(UniquePtr<XPathExpr>(argument));
 977         }
 978         public override UniquePtr<XPathObject> Evaluate(XPathContext& context)
 979         {
 980             XPathFunction* function = GetXPathLibraryFunction(functionName);
 981             if (arguments.Count() < function->MinArity() || arguments.Count() > function->MaxArity())
 982             {
 983                 throw Exception("function \'" + ToUtf8(functionName) + "\' takes " + ToString(function->MinArity()) + "..." + ToString(function->MaxArity()) + " arguments (" + ToString(arguments.Count()) + " arguments provided)");
 984             }
 985             List<UniquePtr<XPathObject>> ownedArgs;
 986             List<XPathObject*> args;
 987             for (const UniquePtr<XPathExpr>& argument : arguments)
 988             {
 989                 UniquePtr<XPathObject> arg = argument->Evaluate(context);
 990                 args.Add(arg.Get());
 991                 ownedArgs.Add(Rvalue(arg));
 992             }
 993             UniquePtr<XPathObject> result = function->Evaluate(contextargs);
 994             return result;
 995         }
 996         public override UniquePtr<System.Dom.Node> ToDom() const
 997         {
 998             UniquePtr<System.Dom.Element> element(new System.Dom.Element(u"functionCall"));
 999             element->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Element(functionName)));
1000             UniquePtr<System.Dom.Element> argumentsElement(new System.Dom.Element(u"arguments"));
1001             for (const UniquePtr<XPathExpr>& argument : arguments)
1002             {
1003                 argumentsElement->AppendChild(argument->ToDom());
1004             }
1005             element->AppendChild(UniquePtr<System.Dom.Node>(argumentsElement.Release()));
1006             return UniquePtr<System.Dom.Node>(element.Release());
1007         }
1008         private ustring functionName;
1009         private List<UniquePtr<XPathExpr>> arguments;
1010     }
1011     public UniquePtr<XPathObject> CompareNodeSets(XPathContext& contextXPathObject* leftXPathObject* rightOperator comparisonOp)
1012     {
1013         if (left->Type() == XPathObjectType.nodeSet && right->Type() == XPathObjectType.nodeSet)
1014         {
1015             XPathNodeSet* leftNodeSet = cast<XPathNodeSet*>(left);
1016             XPathNodeSet* rightNodeSet = cast<XPathNodeSet*>(right);
1017             int n = leftNodeSet->Length();
1018             for (int i = 0; i < n; ++i;)
1019             {
1020                 System.Dom.Node* leftNode = (*leftNodeSet)[i];
1021                 ustring leftStr = StringValue(leftNode);
1022                 int m = rightNodeSet->Length();
1023                 for (int j = 0; j < m; ++j;)
1024                 {
1025                     System.Dom.Node* rightNode = (*rightNodeSet)[j];
1026                     ustring rightStr = StringValue(rightNode);
1027                     switch (comparisonOp)
1028                     {
1029                         case Operator.equal:
1030                         {
1031                             if (leftStr == rightStr)
1032                             {
1033                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1034                                 return result;
1035                             }
1036                             break;
1037                         }
1038                         case Operator.notEqual:
1039                         {
1040                             if (leftStr != rightStr)
1041                             {
1042                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1043                                 return result;
1044                             }
1045                             break;
1046                         }
1047                         case Operator.less:
1048                         {
1049                             if (leftStr < rightStr)
1050                             {
1051                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1052                                 return result;
1053                             }
1054                             break;
1055                         }
1056                         case Operator.greater:
1057                         {
1058                             if (leftStr > rightStr)
1059                             {
1060                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1061                                 return result;
1062                             }
1063                             break;
1064                         }
1065                         case Operator.lessOrEqual:
1066                         {
1067                             if (leftStr <= rightStr)
1068                             {
1069                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1070                                 return result;
1071                             }
1072                             break;
1073                         }
1074                         case Operator.greaterOrEqual:
1075                         {
1076                             if (leftStr >= rightStr)
1077                             {
1078                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1079                                 return result;
1080                             }
1081                             break;
1082                         }
1083                     }
1084                 }
1085             }
1086         }
1087         else if (left->Type() == XPathObjectType.nodeSet)
1088         {
1089             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
1090             XPathFunction* booleanFunction = GetXPathLibraryFunction(u"boolean");
1091             if (right->Type() == XPathObjectType.number)
1092             {
1093                 double rightNumber = cast<XPathNumber*>(right)->Value();
1094                 XPathNodeSet* leftNodeSet = cast<XPathNodeSet*>(left);
1095                 int n = leftNodeSet->Length();
1096                 for (int i = 0; i < n; ++i;)
1097                 {
1098                     System.Dom.Node* leftNode = (*leftNodeSet)[i];
1099                     XPathString leftAsString(StringValue(leftNode));
1100                     List<XPathObject*> leftArgs;
1101                     leftArgs.Add(&leftAsString);
1102                     UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
1103                     if (leftAsNumber->Type() != XPathObjectType.number)
1104                     {
1105                         throw Exception("number result expected");
1106                     }
1107                     double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
1108                     switch (comparisonOp)
1109                     {
1110                         case Operator.equal:
1111                         {
1112                             if (leftNumber == rightNumber)
1113                             {
1114                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1115                                 return result;
1116                             }
1117                             break;
1118                         }
1119                         case Operator.notEqual:
1120                         {
1121                             if (leftNumber != rightNumber)
1122                             {
1123                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1124                                 return result;
1125                             }
1126                             break;
1127                         }
1128                         case Operator.less:
1129                         {
1130                             if (leftNumber < rightNumber)
1131                             {
1132                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1133                                 return result;
1134                             }
1135                             break;
1136                         }
1137                         case Operator.greater:
1138                         {
1139                             if (leftNumber > rightNumber)
1140                             {
1141                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1142                                 return result;
1143                             }
1144                             break;
1145                         }
1146                         case Operator.lessOrEqual:
1147                         {
1148                             if (leftNumber <= rightNumber)
1149                             {
1150                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1151                                 return result;
1152                             }
1153                             break;
1154                         }
1155                         case Operator.greaterOrEqual:
1156                         {
1157                             if (leftNumber >= rightNumber)
1158                             {
1159                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1160                                 return result;
1161                             }
1162                             break;
1163                         }
1164                     }
1165                 }
1166             }
1167             else if (right->Type() == XPathObjectType.string)
1168             {
1169                 ustring rightString = cast<XPathString*>(right)->Value();
1170                 XPathNodeSet* leftNodeSet = cast<XPathNodeSet*>(left);
1171                 int n = leftNodeSet->Length();
1172                 for (int i = 0; i < n; ++i;)
1173                 {
1174                     System.Dom.Node* leftNode = (*leftNodeSet)[i];
1175                     ustring leftString = StringValue(leftNode);
1176                     switch (comparisonOp)
1177                     {
1178                         case Operator.equal:
1179                         {
1180                             if (leftString == rightString)
1181                             {
1182                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1183                                 return result;
1184                             }
1185                             break;
1186                         }
1187                         case Operator.notEqual:
1188                         {
1189                             if (leftString != rightString)
1190                             {
1191                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1192                                 return result;
1193                             }
1194                             break;
1195                         }
1196                         case Operator.less:
1197                         {
1198                             if (leftString < rightString)
1199                             {
1200                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1201                                 return result;
1202                             }
1203                             break;
1204                         }
1205                         case Operator.greater:
1206                         {
1207                             if (leftString > rightString)
1208                             {
1209                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1210                                 return result;
1211                             }
1212                             break;
1213                         }
1214                         case Operator.lessOrEqual:
1215                         {
1216                             if (leftString <= rightString)
1217                             {
1218                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1219                                 return result;
1220                             }
1221                             break;
1222                         }
1223                         case Operator.greaterOrEqual:
1224                         {
1225                             if (leftString >= rightString)
1226                             {
1227                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1228                                 return result;
1229                             }
1230                             break;
1231                         }
1232                     }
1233                 }
1234             }
1235             else if (right->Type() == XPathObjectType.boolean)
1236             {
1237                 bool rightBool = cast<XPathBoolean*>(right)->Value();
1238                 List<XPathObject*> leftArgs;
1239                 leftArgs.Add(left);
1240                 UniquePtr<XPathObject> leftAsBool = booleanFunction->Evaluate(contextleftArgs);
1241                 if (leftAsBool->Type() != XPathObjectType.boolean)
1242                 {
1243                     throw Exception("boolean result expected");
1244                 }
1245                 bool leftBool = cast<XPathBoolean*>(leftAsBool.Get())->Value();
1246                 switch (comparisonOp)
1247                 {
1248                     case Operator.equal:
1249                     {
1250                         if (leftBool == rightBool)
1251                         {
1252                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1253                             return result;
1254                         }
1255                         break;
1256                     }
1257                     case Operator.notEqual:
1258                     {
1259                         if (leftBool != rightBool)
1260                         {
1261                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1262                             return result;
1263                         }
1264                         break;
1265                     }
1266                     case Operator.less:
1267                     {
1268                         if (cast<int>(leftBool) < cast<int>(rightBool))
1269                         {
1270                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1271                             return result;
1272                         }
1273                         break;
1274                     }
1275                     case Operator.greater:
1276                     {
1277                         if (cast<int>(leftBool) > cast<int>(rightBool))
1278                         {
1279                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1280                             return result;
1281                         }
1282                         break;
1283                     }
1284                     case Operator.lessOrEqual:
1285                     {
1286                         if (cast<int>(leftBool) <= cast<int>(rightBool))
1287                         {
1288                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1289                             return result;
1290                         }
1291                         break;
1292                     }
1293                     case Operator.greaterOrEqual:
1294                     {
1295                         if (cast<int>(leftBool) >= cast<int>(rightBool))
1296                         {
1297                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1298                             return result;
1299                         }
1300                         break;
1301                     }
1302                 }
1303             }
1304         }
1305         else if (right->Type() == XPathObjectType.nodeSet)
1306         {
1307             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
1308             XPathFunction* booleanFunction = GetXPathLibraryFunction(u"boolean");
1309             if (left->Type() == XPathObjectType.number)
1310             {
1311                 double leftNumber = cast<XPathNumber*>(left)->Value();
1312                 XPathNodeSet* rightNodeSet = cast<XPathNodeSet*>(right);
1313                 int n = rightNodeSet->Length();
1314                 for (int i = 0; i < n; ++i;)
1315                 {
1316                     System.Dom.Node* rightNode = (*rightNodeSet)[i];
1317                     XPathString rightAsString(StringValue(rightNode));
1318                     List<XPathObject*> rightArgs;
1319                     rightArgs.Add(&rightAsString);
1320                     UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
1321                     if (rightAsNumber->Type() != XPathObjectType.number)
1322                     {
1323                         throw Exception("number result expected");
1324                     }
1325                     double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
1326                     switch (comparisonOp)
1327                     {
1328                         case Operator.equal:
1329                         {
1330                             if (leftNumber == rightNumber)
1331                             {
1332                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1333                                 return result;
1334                             }
1335                             break;
1336                         }
1337                         case Operator.notEqual:
1338                         {
1339                             if (leftNumber != rightNumber)
1340                             {
1341                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1342                                 return result;
1343                             }
1344                             break;
1345                         }
1346                         case Operator.less:
1347                         {
1348                             if (leftNumber < rightNumber)
1349                             {
1350                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1351                                 return result;
1352                             }
1353                             break;
1354                         }
1355                         case Operator.greater:
1356                         {
1357                             if (leftNumber > rightNumber)
1358                             {
1359                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1360                                 return result;
1361                             }
1362                             break;
1363                         }
1364                         case Operator.lessOrEqual:
1365                         {
1366                             if (leftNumber <= rightNumber)
1367                             {
1368                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1369                                 return result;
1370                             }
1371                             break;
1372                         }
1373                         case Operator.greaterOrEqual:
1374                         {
1375                             if (leftNumber >= rightNumber)
1376                             {
1377                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1378                                 return result;
1379                             }
1380                             break;
1381                         }
1382                     }
1383                 }
1384             }
1385             else if (left->Type() == XPathObjectType.string)
1386             {
1387                 ustring leftString = cast<XPathString*>(left)->Value();
1388                 XPathNodeSet* rightNodeSet = cast<XPathNodeSet*>(right);
1389                 int n = rightNodeSet->Length();
1390                 for (int i = 0; i < n; ++i;)
1391                 {
1392                     System.Dom.Node* rightNode = (*rightNodeSet)[i];
1393                     ustring rightString = StringValue(rightNode);
1394                     switch (comparisonOp)
1395                     {
1396                         case Operator.equal:
1397                         {
1398                             if (leftString == rightString)
1399                             {
1400                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1401                                 return result;
1402                             }
1403                             break;
1404                         }
1405                         case Operator.notEqual:
1406                         {
1407                             if (leftString != rightString)
1408                             {
1409                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1410                                 return result;
1411                             }
1412                             break;
1413                         }
1414                         case Operator.less:
1415                         {
1416                             if (leftString < rightString)
1417                             {
1418                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1419                                 return result;
1420                             }
1421                             break;
1422                         }
1423                         case Operator.greater:
1424                         {
1425                             if (leftString > rightString)
1426                             {
1427                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1428                                 return result;
1429                             }
1430                             break;
1431                         }
1432                         case Operator.lessOrEqual:
1433                         {
1434                             if (leftString <= rightString)
1435                             {
1436                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1437                                 return result;
1438                             }
1439                             break;
1440                         }
1441                         case Operator.greaterOrEqual:
1442                         {
1443                             if (leftString >= rightString)
1444                             {
1445                                 UniquePtr<XPathObject> result(new XPathBoolean(true));
1446                                 return result;
1447                             }
1448                             break;
1449                         }
1450                     }
1451                 }
1452             }
1453             else if (left->Type() == XPathObjectType.boolean)
1454             {
1455                 bool leftBool = cast<XPathBoolean*>(left)->Value();
1456                 List<XPathObject*> rightArgs;
1457                 rightArgs.Add(right);
1458                 UniquePtr<XPathObject> rightAsBool = booleanFunction->Evaluate(contextrightArgs);
1459                 if (rightAsBool->Type() != XPathObjectType.boolean)
1460                 {
1461                     throw Exception("boolean result expected");
1462                 }
1463                 bool rightBool = cast<XPathBoolean*>(rightAsBool.Get())->Value();
1464                 switch (comparisonOp)
1465                 {
1466                     case Operator.equal:
1467                     {
1468                         if (leftBool == rightBool)
1469                         {
1470                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1471                             return result;
1472                         }
1473                         break;
1474                     }
1475                     case Operator.notEqual:
1476                     {
1477                         if (leftBool != rightBool)
1478                         {
1479                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1480                             return result;
1481                         }
1482                         break;
1483                     }
1484                     case Operator.less:
1485                     {
1486                         if (cast<int>(leftBool) < cast<int>(rightBool))
1487                         {
1488                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1489                             return result;
1490                         }
1491                         break;
1492                     }
1493                     case Operator.greater:
1494                     {
1495                         if (cast<int>(leftBool) > cast<int>(rightBool))
1496                         {
1497                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1498                             return result;
1499                         }
1500                         break;
1501                     }
1502                     case Operator.lessOrEqual:
1503                     {
1504                         if (cast<int>(leftBool) <= cast<int>(rightBool))
1505                         {
1506                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1507                             return result;
1508                         }
1509                         break;
1510                     }
1511                     case Operator.greaterOrEqual:
1512                     {
1513                         if (cast<int>(leftBool) >= cast<int>(rightBool))
1514                         {
1515                             UniquePtr<XPathObject> result(new XPathBoolean(true));
1516                             return result;
1517                         }
1518                         break;
1519                     }
1520                 }
1521             }
1522         }
1523         UniquePtr<XPathObject> result(new XPathBoolean(false));
1524         return result;
1525     }
1526     public UniquePtr<XPathObject> CompareEquality(XPathContext& contextXPathObject* leftXPathObject* right)
1527     {
1528         if (left->Type() == XPathObjectType.nodeSet || right->Type() == XPathObjectType.nodeSet)
1529         {
1530             return CompareNodeSets(contextleftrightOperator.equal);
1531         }
1532         else
1533         {
1534             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
1535             XPathFunction* booleanFunction = GetXPathLibraryFunction(u"boolean");
1536             XPathFunction* stringFunction = GetXPathLibraryFunction(u"string");
1537             if (left->Type() == XPathObjectType.number || right->Type() == XPathObjectType.number)
1538             {
1539                 List<XPathObject*> leftArgs;
1540                 leftArgs.Add(left);
1541                 UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
1542                 if (leftAsNumber->Type() != XPathObjectType.number)
1543                 {
1544                     throw Exception("number result expected");
1545                 }
1546                 double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
1547                 List<XPathObject*> rightArgs;
1548                 rightArgs.Add(right);
1549                 UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
1550                 if (rightAsNumber->Type() != XPathObjectType.number)
1551                 {
1552                     throw Exception("number result expected");
1553                 }
1554                 double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
1555                 if (leftNumber == rightNumber)
1556                 {
1557                     UniquePtr<XPathObject> result(new XPathBoolean(true));
1558                     return result;
1559                 }
1560                 else
1561                 {
1562                     UniquePtr<XPathObject> result(new XPathBoolean(false));
1563                     return result;
1564                 }
1565             }
1566             else
1567             {
1568                 List<XPathObject*> leftArgs;
1569                 leftArgs.Add(left);
1570                 UniquePtr<XPathObject> leftAsString = stringFunction->Evaluate(contextleftArgs);
1571                 if (leftAsString->Type() != XPathObjectType.string)
1572                 {
1573                     throw Exception("string result expected");
1574                 }
1575                 ustring leftString = cast<XPathString*>(leftAsString.Get())->Value();
1576                 List<XPathObject*> rightArgs;
1577                 rightArgs.Add(right);
1578                 UniquePtr<XPathObject> rightAsString = stringFunction->Evaluate(contextrightArgs);
1579                 if (rightAsString->Type() != XPathObjectType.string)
1580                 {
1581                     throw Exception("string result expected");
1582                 }
1583                 ustring rightString = cast<XPathString*>(rightAsString.Get())->Value();
1584                 if (leftString == rightString)
1585                 {
1586                     UniquePtr<XPathObject> result(new XPathBoolean(true));
1587                     return result;
1588                 }
1589                 else
1590                 {
1591                     UniquePtr<XPathObject> result(new XPathBoolean(false));
1592                     return result;
1593                 }
1594             }
1595         }
1596         UniquePtr<XPathObject> result(new XPathBoolean(false));
1597         return result;
1598     }
1599     public UniquePtr<XPathObject> Compare(XPathContext& contextXPathObject* leftXPathObject* rightOperator comparisonOp)
1600     {
1601         if (left->Type() == XPathObjectType.nodeSet || right->Type() == XPathObjectType.nodeSet)
1602         {
1603             return CompareNodeSets(contextleftrightcomparisonOp);
1604         }
1605         else
1606         {
1607             XPathFunction* numberFunction = GetXPathLibraryFunction(u"number");
1608             List<XPathObject*> leftArgs;
1609             leftArgs.Add(left);
1610             UniquePtr<XPathObject> leftAsNumber = numberFunction->Evaluate(contextleftArgs);
1611             if (leftAsNumber->Type() != XPathObjectType.number)
1612             {
1613                 throw Exception("number result expected");
1614             }
1615             double leftNumber = cast<XPathNumber*>(leftAsNumber.Get())->Value();
1616             List<XPathObject*> rightArgs;
1617             rightArgs.Add(right);
1618             UniquePtr<XPathObject> rightAsNumber = numberFunction->Evaluate(contextrightArgs);
1619             if (rightAsNumber->Type() != XPathObjectType.number)
1620             {
1621                 throw Exception("number result expected");
1622             }
1623             double rightNumber = cast<XPathNumber*>(rightAsNumber.Get())->Value();
1624             switch (comparisonOp)
1625             {
1626                 case Operator.less:
1627                 {
1628                     if (leftNumber < rightNumber)
1629                     {
1630                         UniquePtr<XPathObject> result(new XPathBoolean(true));
1631                         return result;
1632                     }
1633                     else
1634                     {
1635                         UniquePtr<XPathObject> result(new XPathBoolean(false));
1636                         return result;
1637                     }
1638                     break;
1639                 }
1640                 case Operator.greater:
1641                 {
1642                     if (leftNumber > rightNumber)
1643                     {
1644                         UniquePtr<XPathObject> result(new XPathBoolean(true));
1645                         return result;
1646                     }
1647                     else
1648                     {
1649                         UniquePtr<XPathObject> result(new XPathBoolean(false));
1650                         return result;
1651                     }
1652                     break;
1653                 }
1654                 case Operator.lessOrEqual:
1655                 {
1656                     if (leftNumber <= rightNumber)
1657                     {
1658                         UniquePtr<XPathObject> result(new XPathBoolean(true));
1659                         return result;
1660                     }
1661                     else
1662                     {
1663                         UniquePtr<XPathObject> result(new XPathBoolean(false));
1664                         return result;
1665                     }
1666                     break;
1667                 }
1668                 case Operator.greaterOrEqual:
1669                 {
1670                     if (leftNumber >= rightNumber)
1671                     {
1672                         UniquePtr<XPathObject> result(new XPathBoolean(true));
1673                         return result;
1674                     }
1675                     else
1676                     {
1677                         UniquePtr<XPathObject> result(new XPathBoolean(false));
1678                         return result;
1679                     }
1680                     break;
1681                 }
1682             }
1683         }
1684         UniquePtr<XPathObject> result(new XPathBoolean(false));
1685         return result;
1686     }
1687     public class NodeSelectionOp : System.Dom.NodeOp
1688     {
1689         public NodeSelectionOp(XPathNodeTestExpr* nodeTest_XPathNodeSet& nodeSet_System.Dom.Axis axis_) : 
1690             nodeTest(nodeTest_)nodeSet(nodeSet_)axis(axis_)
1691         {
1692         }
1693         public override void Apply(System.Dom.Node* node)
1694         {
1695             if (nodeTest->Select(nodeaxis))
1696             {
1697                 nodeSet.Add(node);
1698             }
1699         }
1700         private XPathNodeTestExpr* nodeTest;
1701         private XPathNodeSet& nodeSet;
1702         private System.Dom.Axis axis;
1703     }
1704     public class AxisMap
1705     {
1706         static AxisMap() : instance(new AxisMap())
1707         {
1708         }
1709         public static AxisMap& Instance()
1710         {
1711             return *instance;
1712         }
1713         public AxisMap()
1714         {
1715             axisMap[u"ancestor"] = Axis.ancestor;
1716             axisMap[u"ancestor-or-self"] = Axis.ancestorOrSelf;
1717             axisMap[u"attribute"] = Axis.attribute;
1718             axisMap[u"child"] = Axis.child;
1719             axisMap[u"descendant"] = Axis.descendant;
1720             axisMap[u"descendant-or-self"] = Axis.descendantOrSelf;
1721             axisMap[u"following"] = Axis.following;
1722             axisMap[u"following-sibling"] = Axis.followingSibling;
1723             axisMap[u"namespace"] = Axis.ns;
1724             axisMap[u"parent"] = Axis.parent;
1725             axisMap[u"preceding"] = Axis.preceding;
1726             axisMap[u"preceding-sibling"] = Axis.precedingSibling;
1727             axisMap[u"self"] = Axis.self;
1728         }
1729         public System.Dom.Axis GetAxis(const ustring& axis) const
1730         {
1731             Map<ustringSystem.Dom.Axis>.ConstIterator it = axisMap.CFind(axis);
1732             if (it != axisMap.CEnd())
1733             {
1734                 return it->second;
1735             }
1736             else
1737             {
1738                 throw Exception("axis \'" + ToUtf8(axis) + "\' not found");
1739             }
1740         }
1741         private static UniquePtr<AxisMap> instance;
1742         private Map<ustringSystem.Dom.Axis> axisMap;
1743     }
1744     public System.Dom.Axis GetAxis(const ustring& axisName)
1745     {
1746         return AxisMap.Instance().GetAxis(axisName);
1747     }
1748 } // namespace System.XPath