[coop] Temporarily restore MonoThreadInfo when TLS destructor runs. Fixes #43099
[mono.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / IlGen / XmlILOptimizerVisitor.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XmlILOptimizerVisitor.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
7 using System.Collections.Generic;
8 using System.Diagnostics;
9 using System.Xml.Schema;
10 using System.Xml.XPath;
11 using System.Xml.Xsl.Qil;
12 using System.Xml.Xsl.Runtime;
13
14 namespace System.Xml.Xsl.IlGen {
15
16     internal class XmlILOptimizerVisitor : QilPatternVisitor {
17         private static readonly QilPatterns PatternsNoOpt, PatternsOpt;
18         private QilExpression qil;
19         private XmlILElementAnalyzer elemAnalyzer;
20         private XmlILStateAnalyzer contentAnalyzer;
21         private XmlILNamespaceAnalyzer nmspAnalyzer;
22         private NodeCounter nodeCounter = new NodeCounter();
23         private SubstitutionList subs = new SubstitutionList();
24
25         static XmlILOptimizerVisitor() {
26             // Enable all normalizations and annotations for Release code
27             // Enable all patterns for Release code
28             PatternsOpt = new QilPatterns((int) XmlILOptimization.Last_, true);
29
30             // Only enable Required and OptimizedConstruction pattern groups
31             // Only enable Required patterns
32             PatternsNoOpt = new QilPatterns((int) XmlILOptimization.Last_, false);
33
34             PatternsNoOpt.Add((int) XmlILOptimization.FoldNone);
35             PatternsNoOpt.Add((int) XmlILOptimization.EliminatePositionOf);
36             PatternsNoOpt.Add((int) XmlILOptimization.EliminateTypeAssert);
37             PatternsNoOpt.Add((int) XmlILOptimization.EliminateIsType);
38             PatternsNoOpt.Add((int) XmlILOptimization.EliminateIsEmpty);
39             PatternsNoOpt.Add((int) XmlILOptimization.EliminateAverage);
40             PatternsNoOpt.Add((int) XmlILOptimization.EliminateSum);
41             PatternsNoOpt.Add((int) XmlILOptimization.EliminateMinimum);
42             PatternsNoOpt.Add((int) XmlILOptimization.EliminateMaximum);
43             PatternsNoOpt.Add((int) XmlILOptimization.EliminateSort);
44             PatternsNoOpt.Add((int) XmlILOptimization.EliminateStrConcatSingle);
45
46             PatternsNoOpt.Add((int) XmlILOptimization.NormalizeUnion);
47             PatternsNoOpt.Add((int) XmlILOptimization.NormalizeIntersect);
48             PatternsNoOpt.Add((int) XmlILOptimization.NormalizeDifference);
49
50             PatternsNoOpt.Add((int) XmlILOptimization.AnnotatePositionalIterator);
51             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateTrackCallers);
52             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateDod);
53             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateConstruction);
54
55             // Enable indexes in debug mode
56             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateIndex1);
57             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateIndex2);
58             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateBarrier);
59             PatternsNoOpt.Add((int) XmlILOptimization.AnnotateFilter);
60         }
61
62         public XmlILOptimizerVisitor(QilExpression qil, bool optimize) : base(optimize ? PatternsOpt : PatternsNoOpt, qil.Factory) {
63             this.qil = qil;
64             this.elemAnalyzer = new XmlILElementAnalyzer(qil.Factory);
65             this.contentAnalyzer = new XmlILStateAnalyzer(qil.Factory);
66             this.nmspAnalyzer = new XmlILNamespaceAnalyzer();
67         }
68
69         /// <summary>
70         /// Perform normalization and annotation.
71         /// </summary>
72         public QilExpression Optimize() {
73             QilExpression qil = (QilExpression) Visit(this.qil);
74
75             // Perform tail-call analysis on all functions within the Qil expression
76             if (this[XmlILOptimization.TailCall])
77                 TailCallAnalyzer.Analyze(qil);
78
79             return qil;
80         }
81
82         /// <summary>
83         /// Override the Visit method in order to scan for redundant namespaces and compute side-effect bit.
84         /// </summary>
85         protected override QilNode Visit(QilNode nd) {
86             if (nd != null) {
87                 if (this[XmlILOptimization.EliminateNamespaceDecl]) {
88                     // Eliminate redundant namespaces in the tree.  Don't perform the scan on an ElementCtor which
89                     // has already been marked as having a redundant namespace.
90                     switch (nd.NodeType) {
91                         case QilNodeType.QilExpression:
92                             // Perform namespace analysis on root expression (xmlns="" is in-scope for this expression)
93                             this.nmspAnalyzer.Analyze(((QilExpression) nd).Root, true);
94                             break;
95
96                         case QilNodeType.ElementCtor:
97                             if (!XmlILConstructInfo.Read(nd).IsNamespaceInScope)
98                                 this.nmspAnalyzer.Analyze(nd, false);
99                             break;
100
101                         case QilNodeType.DocumentCtor:
102                             this.nmspAnalyzer.Analyze(nd, true);
103                             break;
104                     }
105                 }
106             }
107
108             // Continue visitation
109             return base.Visit(nd);
110         }
111
112         /// <summary>
113         /// Override the VisitReference method in order to possibly substitute.
114         /// </summary>
115         protected override QilNode VisitReference(QilNode oldNode) {
116             QilNode newNode = this.subs.FindReplacement(oldNode);
117
118             if (newNode == null)
119                 newNode = oldNode;
120
121             // Fold reference to constant value
122             // This is done here because "p" currently cannot match references
123             if (this[XmlILOptimization.EliminateLiteralVariables] && newNode != null) {
124                 if (newNode.NodeType == QilNodeType.Let || newNode.NodeType == QilNodeType.For) {
125                     QilNode binding = ((QilIterator) oldNode).Binding;
126
127                     if (IsLiteral(binding))
128                         return Replace(XmlILOptimization.EliminateLiteralVariables, newNode, binding.ShallowClone(f));
129                 }
130             }
131             if (this[XmlILOptimization.EliminateUnusedGlobals]) {
132                 if (IsGlobalValue(newNode))
133                     OptimizerPatterns.Write(newNode).AddPattern(OptimizerPatternName.IsReferenced);
134             }
135
136             return base.VisitReference(newNode);
137         }
138
139         /// <summary>
140         /// Strongly-typed AllowReplace.
141         /// </summary>
142         protected bool AllowReplace(XmlILOptimization pattern, QilNode original) {
143             return base.AllowReplace((int) pattern, original);
144         }
145
146         /// <summary>
147         /// Strongly-typed Replace.
148         /// </summary>
149         protected QilNode Replace(XmlILOptimization pattern, QilNode original, QilNode replacement) {
150             return base.Replace((int) pattern, original, replacement);
151         }
152
153         /// <summary>
154         /// Called when all replacements have already been made and all annotations are complete.
155         /// </summary>
156         protected override QilNode NoReplace(QilNode node) {
157             // Calculate MaybeSideEffects pattern.  This is done here rather than using P because every node needs
158             // to compute it and P has no good way of matching every node type.
159             if (node != null) {
160                 switch (node.NodeType) {
161                     case QilNodeType.Error:
162                     case QilNodeType.Warning:
163                     case QilNodeType.XsltInvokeLateBound:
164                         // Error, Warning, and XsltInvokeLateBound are always assumed to have side-effects
165                         OptimizerPatterns.Write(node).AddPattern(OptimizerPatternName.MaybeSideEffects);
166                         break;
167
168                     case QilNodeType.XsltInvokeEarlyBound:
169                         // XsltInvokeEarlyBound is assumed to have side-effects if it is not a built-in function
170                         if (((QilInvokeEarlyBound) node).Name.NamespaceUri.Length != 0)
171                             goto case QilNodeType.XsltInvokeLateBound;
172                         goto default;
173
174                     case QilNodeType.Invoke:
175                         // Invoke is assumed to have side-effects if it invokes a function with its SideEffects flag set
176                         if (((QilInvoke) node).Function.MaybeSideEffects)
177                             goto case QilNodeType.XsltInvokeLateBound;
178
179                         // Otherwise, check children
180                         goto default;
181
182                     default:
183                         // If any of the visited node's children have side effects, then mark the node as also having side effects
184                         for (int i = 0; i < node.Count; i++) {
185                             if (node[i] != null) {
186                                 if (OptimizerPatterns.Read(node[i]).MatchesPattern(OptimizerPatternName.MaybeSideEffects))
187                                     goto case QilNodeType.XsltInvokeLateBound;
188                             }
189                         }
190                         break;
191                 }
192             }
193
194             return node;
195         }
196
197         /// <summary>
198         /// Override the RecalculateType method so that global variable type is not recalculated.
199         /// </summary>
200         protected override void RecalculateType(QilNode node, XmlQueryType oldType) {
201              if (node.NodeType != QilNodeType.Let || !this.qil.GlobalVariableList.Contains(node))
202                 base.RecalculateType(node, oldType);
203         }
204
205         // Do not edit this region
206         // It is auto-generated
207         #region AUTOGENERATED
208
209         #region meta
210         protected override QilNode VisitQilExpression(QilExpression local0) {
211             QilNode local1 = local0[0];
212             if (this[XmlILOptimization.EliminateUnusedGlobals]) {
213                 // PATTERN: [EliminateUnusedGlobals] $qil:(QilExpression *) => { ... }
214                 if (AllowReplace(XmlILOptimization.EliminateUnusedGlobals, local0)) {
215                     EliminateUnusedGlobals(local0.GlobalVariableList);
216                     EliminateUnusedGlobals(local0.GlobalParameterList);
217                     EliminateUnusedGlobals(local0.FunctionList);
218                 }
219             }
220             if (this[XmlILOptimization.AnnotateConstruction]) {
221                 // PATTERN: [AnnotateConstruction] $qil:(QilExpression *) => { ... }
222                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
223                     foreach (QilFunction ndFunc in local0.FunctionList) {
224                         // Functions that construct Xml trees should stream output to writer; otherwise, results should
225                         // be cached and returned.
226                         if (IsConstructedExpression(ndFunc.Definition)) {
227                             // Perform state analysis on function's content
228                             ndFunc.Definition = this.contentAnalyzer.Analyze(ndFunc, ndFunc.Definition);
229                         }
230                     }
231
232                     // Perform state analysis on the root expression
233                     local0.Root = this.contentAnalyzer.Analyze(null, local0.Root);
234
235                     // Make sure that root expression is pushed to writer
236                     XmlILConstructInfo.Write(local0.Root).PushToWriterLast = true;
237                 }
238             }
239             return NoReplace(local0);
240         }
241
242         protected override QilNode VisitOptimizeBarrier(QilUnary local0) {
243             QilNode local1 = local0[0];
244             if (this[XmlILOptimization.AnnotateBarrier]) {
245                 // PATTERN: [AnnotateBarrier] $outer:(OptimizeBarrier $expr:*) => (InheritPattern $outer $expr {IsDocOrderDistinct}) ^ (InheritPattern $outer $expr {SameDepth}) ^ { }
246                 if (AllowReplace(XmlILOptimization.AnnotateBarrier, local0)) {
247                      OptimizerPatterns.Inherit((QilNode) (local1), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local1), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
248             }
249             return NoReplace(local0);
250         }
251
252         #endregion // meta
253
254         #region specials
255         protected override QilNode VisitDataSource(QilDataSource local0) {
256             QilNode local1 = local0[0];
257             QilNode local2 = local0[1];
258             if (this[XmlILOptimization.FoldNone]) {
259                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
260                     // PATTERN: [FoldNone] (DataSource $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
261                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
262                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
263                     }
264                 }
265             }
266             if (this[XmlILOptimization.FoldNone]) {
267                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
268                     // PATTERN: [FoldNone] (DataSource * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
269                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
270                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
271                     }
272                 }
273             }
274             return NoReplace(local0);
275         }
276
277         protected override QilNode VisitNop(QilUnary local0) {
278             QilNode local1 = local0[0];
279             if (this[XmlILOptimization.EliminateNop]) {
280                 // PATTERN: [EliminateNop] (Nop $x:*) => $x
281                 if (AllowReplace(XmlILOptimization.EliminateNop, local0)) {
282                     return Replace(XmlILOptimization.EliminateNop, local0, local1);
283                 }
284             }
285             return NoReplace(local0);
286         }
287
288         protected override QilNode VisitError(QilUnary local0) {
289             QilNode local1 = local0[0];
290             if (this[XmlILOptimization.FoldNone]) {
291                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
292                     // PATTERN: [FoldNone] (Error $x:* ^ (None? (TypeOf $x))) => (Nop $x)
293                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
294                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
295                     }
296                 }
297             }
298             return NoReplace(local0);
299         }
300
301         protected override QilNode VisitWarning(QilUnary local0) {
302             QilNode local1 = local0[0];
303             if (this[XmlILOptimization.FoldNone]) {
304                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
305                     // PATTERN: [FoldNone] (Warning $x:* ^ (None? (TypeOf $x))) => (Nop $x)
306                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
307                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
308                     }
309                 }
310             }
311             return NoReplace(local0);
312         }
313
314         #endregion // specials
315
316         #region variables
317         protected override QilNode VisitLet(QilIterator local0) {
318             QilNode local1 = local0[0];
319             if ((( ( (local0).XmlType ).IsSingleton ) && (!( IsGlobalVariable(local0) ))) && (this[XmlILOptimization.NormalizeSingletonLet])) {
320                 // PATTERN: [NormalizeSingletonLet] $iter:(Let $bind:*) ^ (Single? (TypeOf $iter)) ^ ~((GlobalVariable? $iter)) => { ... }
321                 if (AllowReplace(XmlILOptimization.NormalizeSingletonLet, local0)) {
322                     local0.NodeType = QilNodeType.For;
323                     VisitFor(local0);
324                 }
325             }
326             if (this[XmlILOptimization.AnnotateLet]) {
327                 // PATTERN: [AnnotateLet] $outer:(Let $bind:*) => (InheritPattern $outer $bind {Step}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ (InheritPattern $outer $bind {SameDepth}) ^ { }
328                 if (AllowReplace(XmlILOptimization.AnnotateLet, local0)) {
329                      OptimizerPatterns.Inherit((QilNode) (local1), (QilNode) (local0), OptimizerPatternName.Step);  OptimizerPatterns.Inherit((QilNode) (local1), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local1), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
330             }
331             return NoReplace(local0);
332         }
333
334         protected override QilNode VisitPositionOf(QilUnary local0) {
335             QilNode local1 = local0[0];
336             if (this[XmlILOptimization.EliminatePositionOf]) {
337                 if (!( (local1).NodeType == QilNodeType.For )) {
338                     // PATTERN: [EliminatePositionOf] (PositionOf $x:* ^ ~((NodeType? $x {For}))) => (LiteralInt32 1)
339                     if (AllowReplace(XmlILOptimization.EliminatePositionOf, local0)) {
340                         return Replace(XmlILOptimization.EliminatePositionOf, local0, VisitLiteralInt32(f.LiteralInt32(1)));
341                     }
342                 }
343             }
344             if (this[XmlILOptimization.EliminatePositionOf]) {
345                 if (local1.NodeType == QilNodeType.For) {
346                     QilNode local2 = local1[0];
347                     if ( ( (local2).XmlType ).IsSingleton ) {
348                         // PATTERN: [EliminatePositionOf] (PositionOf (For $x:* ^ (Single? (TypeOf $x)))) => (LiteralInt32 1)
349                         if (AllowReplace(XmlILOptimization.EliminatePositionOf, local0)) {
350                             return Replace(XmlILOptimization.EliminatePositionOf, local0, VisitLiteralInt32(f.LiteralInt32(1)));
351                         }
352                     }
353                 }
354             }
355             if (this[XmlILOptimization.AnnotatePositionalIterator]) {
356                 // PATTERN: [AnnotatePositionalIterator] (PositionOf $iter:*) => (AddPattern $iter {IsPositional}) ^ { }
357                 if (AllowReplace(XmlILOptimization.AnnotatePositionalIterator, local0)) {
358                      OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.IsPositional);  }
359             }
360             return NoReplace(local0);
361         }
362
363         #endregion // variables
364
365         #region literals
366         #endregion // literals
367
368         #region boolean operators
369         protected override QilNode VisitAnd(QilBinary local0) {
370             QilNode local1 = local0[0];
371             QilNode local2 = local0[1];
372             if (this[XmlILOptimization.FoldNone]) {
373                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
374                     // PATTERN: [FoldNone] (And $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
375                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
376                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
377                     }
378                 }
379             }
380             if (this[XmlILOptimization.FoldNone]) {
381                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
382                     // PATTERN: [FoldNone] (And * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
383                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
384                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
385                     }
386                 }
387             }
388             if (this[XmlILOptimization.EliminateAnd]) {
389                 if (local1.NodeType == QilNodeType.True) {
390                     // PATTERN: [EliminateAnd] (And (True) $x:*) => $x
391                     if (AllowReplace(XmlILOptimization.EliminateAnd, local0)) {
392                         return Replace(XmlILOptimization.EliminateAnd, local0, local2);
393                     }
394                 }
395             }
396             if (this[XmlILOptimization.EliminateAnd]) {
397                 if (local1.NodeType == QilNodeType.False) {
398                     // PATTERN: [EliminateAnd] (And $x:(False) *) => $x
399                     if (AllowReplace(XmlILOptimization.EliminateAnd, local0)) {
400                         return Replace(XmlILOptimization.EliminateAnd, local0, local1);
401                     }
402                 }
403             }
404             if (this[XmlILOptimization.EliminateAnd]) {
405                 if (local2.NodeType == QilNodeType.True) {
406                     // PATTERN: [EliminateAnd] (And $x:* (True)) => $x
407                     if (AllowReplace(XmlILOptimization.EliminateAnd, local0)) {
408                         return Replace(XmlILOptimization.EliminateAnd, local0, local1);
409                     }
410                 }
411             }
412             if (this[XmlILOptimization.EliminateAnd]) {
413                 if (local2.NodeType == QilNodeType.False) {
414                     // PATTERN: [EliminateAnd] (And * $x:(False)) => $x
415                     if (AllowReplace(XmlILOptimization.EliminateAnd, local0)) {
416                         return Replace(XmlILOptimization.EliminateAnd, local0, local2);
417                     }
418                 }
419             }
420             return NoReplace(local0);
421         }
422
423         protected override QilNode VisitOr(QilBinary local0) {
424             QilNode local1 = local0[0];
425             QilNode local2 = local0[1];
426             if (this[XmlILOptimization.FoldNone]) {
427                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
428                     // PATTERN: [FoldNone] (Or $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
429                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
430                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
431                     }
432                 }
433             }
434             if (this[XmlILOptimization.FoldNone]) {
435                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
436                     // PATTERN: [FoldNone] (Or * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
437                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
438                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
439                     }
440                 }
441             }
442             if (this[XmlILOptimization.EliminateOr]) {
443                 if (local1.NodeType == QilNodeType.True) {
444                     // PATTERN: [EliminateOr] (Or $x:(True) *) => $x
445                     if (AllowReplace(XmlILOptimization.EliminateOr, local0)) {
446                         return Replace(XmlILOptimization.EliminateOr, local0, local1);
447                     }
448                 }
449             }
450             if (this[XmlILOptimization.EliminateOr]) {
451                 if (local1.NodeType == QilNodeType.False) {
452                     // PATTERN: [EliminateOr] (Or (False) $x:*) => $x
453                     if (AllowReplace(XmlILOptimization.EliminateOr, local0)) {
454                         return Replace(XmlILOptimization.EliminateOr, local0, local2);
455                     }
456                 }
457             }
458             if (this[XmlILOptimization.EliminateOr]) {
459                 if (local2.NodeType == QilNodeType.True) {
460                     // PATTERN: [EliminateOr] (Or * $x:(True)) => $x
461                     if (AllowReplace(XmlILOptimization.EliminateOr, local0)) {
462                         return Replace(XmlILOptimization.EliminateOr, local0, local2);
463                     }
464                 }
465             }
466             if (this[XmlILOptimization.EliminateOr]) {
467                 if (local2.NodeType == QilNodeType.False) {
468                     // PATTERN: [EliminateOr] (Or $x:* (False)) => $x
469                     if (AllowReplace(XmlILOptimization.EliminateOr, local0)) {
470                         return Replace(XmlILOptimization.EliminateOr, local0, local1);
471                     }
472                 }
473             }
474             return NoReplace(local0);
475         }
476
477         protected override QilNode VisitNot(QilUnary local0) {
478             QilNode local1 = local0[0];
479             if (this[XmlILOptimization.FoldNone]) {
480                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
481                     // PATTERN: [FoldNone] (Not $x:* ^ (None? (TypeOf $x))) => (Nop $x)
482                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
483                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
484                     }
485                 }
486             }
487             if (this[XmlILOptimization.EliminateNot]) {
488                 if (local1.NodeType == QilNodeType.True) {
489                     // PATTERN: [EliminateNot] (Not (True)) => (False)
490                     if (AllowReplace(XmlILOptimization.EliminateNot, local0)) {
491                         return Replace(XmlILOptimization.EliminateNot, local0, VisitFalse(f.False()));
492                     }
493                 }
494             }
495             if (this[XmlILOptimization.EliminateNot]) {
496                 if (local1.NodeType == QilNodeType.False) {
497                     // PATTERN: [EliminateNot] (Not (False)) => (True)
498                     if (AllowReplace(XmlILOptimization.EliminateNot, local0)) {
499                         return Replace(XmlILOptimization.EliminateNot, local0, VisitTrue(f.True()));
500                     }
501                 }
502             }
503             return NoReplace(local0);
504         }
505
506         #endregion // boolean operators
507
508         #region choice
509         protected override QilNode VisitConditional(QilTernary local0) {
510             QilNode local1 = local0[0];
511             QilNode local2 = local0[1];
512             QilNode local3 = local0[2];
513             if (this[XmlILOptimization.FoldNone]) {
514                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
515                     // PATTERN: [FoldNone] (Conditional $x:* ^ (None? (TypeOf $x)) * *) => (Nop $x)
516                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
517                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
518                     }
519                 }
520             }
521             if (this[XmlILOptimization.EliminateConditional]) {
522                 if (local1.NodeType == QilNodeType.True) {
523                     // PATTERN: [EliminateConditional] (Conditional (True) $x:* *) => $x
524                     if (AllowReplace(XmlILOptimization.EliminateConditional, local0)) {
525                         return Replace(XmlILOptimization.EliminateConditional, local0, local2);
526                     }
527                 }
528             }
529             if (this[XmlILOptimization.EliminateConditional]) {
530                 if (local1.NodeType == QilNodeType.False) {
531                     // PATTERN: [EliminateConditional] (Conditional (False) * $x:*) => $x
532                     if (AllowReplace(XmlILOptimization.EliminateConditional, local0)) {
533                         return Replace(XmlILOptimization.EliminateConditional, local0, local3);
534                     }
535                 }
536             }
537             if (this[XmlILOptimization.EliminateConditional]) {
538                 if (local2.NodeType == QilNodeType.True) {
539                     if (local3.NodeType == QilNodeType.False) {
540                         // PATTERN: [EliminateConditional] (Conditional $x:* (True) (False)) => $x
541                         if (AllowReplace(XmlILOptimization.EliminateConditional, local0)) {
542                             return Replace(XmlILOptimization.EliminateConditional, local0, local1);
543                         }
544                     }
545                 }
546             }
547             if (this[XmlILOptimization.EliminateConditional]) {
548                 if (local2.NodeType == QilNodeType.False) {
549                     if (local3.NodeType == QilNodeType.True) {
550                         // PATTERN: [EliminateConditional] (Conditional $x:* (False) (True)) => (Not $x)
551                         if (AllowReplace(XmlILOptimization.EliminateConditional, local0)) {
552                             return Replace(XmlILOptimization.EliminateConditional, local0, VisitNot(f.Not(local1)));
553                         }
554                     }
555                 }
556             }
557             if (this[XmlILOptimization.FoldConditionalNot]) {
558                 if (local1.NodeType == QilNodeType.Not) {
559                     QilNode local4 = local1[0];
560                     // PATTERN: [FoldConditionalNot] (Conditional (Not $x:*) $t:* $f:*) => (Conditional $x $f $t)
561                     if (AllowReplace(XmlILOptimization.FoldConditionalNot, local0)) {
562                         return Replace(XmlILOptimization.FoldConditionalNot, local0, VisitConditional(f.Conditional(local4, local3, local2)));
563                     }
564                 }
565             }
566             if (this[XmlILOptimization.NormalizeConditionalText]) {
567                 if (local2.NodeType == QilNodeType.TextCtor) {
568                     QilNode local4 = local2[0];
569                     if (local3.NodeType == QilNodeType.TextCtor) {
570                         QilNode local5 = local3[0];
571                         // PATTERN: [NormalizeConditionalText] (Conditional $cond:* $left:(TextCtor $leftText:*) $right:(TextCtor $rightText:*)) => (TextCtor (Conditional $cond $leftText $rightText))
572                         if (AllowReplace(XmlILOptimization.NormalizeConditionalText, local0)) {
573                             return Replace(XmlILOptimization.NormalizeConditionalText, local0, VisitTextCtor(f.TextCtor(VisitConditional(f.Conditional(local1, local4, local5)))));
574                         }
575                     }
576                 }
577             }
578             return NoReplace(local0);
579         }
580
581         protected override QilNode VisitChoice(QilChoice local0) {
582             QilNode local1 = local0[0];
583             QilNode local2 = local0[1];
584             if (this[XmlILOptimization.AnnotateConstruction]) {
585                 // PATTERN: [AnnotateConstruction] $ctor:(Choice * *) => { ... }
586                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
587                     this.contentAnalyzer.Analyze(local0, null);
588                 }
589             }
590             return NoReplace(local0);
591         }
592
593         #endregion // choice
594
595         #region collection operators
596         protected override QilNode VisitLength(QilUnary local0) {
597             QilNode local1 = local0[0];
598             if (this[XmlILOptimization.FoldNone]) {
599                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
600                     // PATTERN: [FoldNone] (Length $x:* ^ (None? (TypeOf $x))) => (Nop $x)
601                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
602                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
603                     }
604                 }
605             }
606             if (this[XmlILOptimization.EliminateLength]) {
607                 if (local1.NodeType == QilNodeType.Sequence) {
608                     if ( (local1).Count == (0) ) {
609                         // PATTERN: [EliminateLength] (Length $x:(Sequence) ^ (Count? $x 0)) => (LiteralInt32 0)
610                         if (AllowReplace(XmlILOptimization.EliminateLength, local0)) {
611                             return Replace(XmlILOptimization.EliminateLength, local0, VisitLiteralInt32(f.LiteralInt32(0)));
612                         }
613                     }
614                 }
615             }
616             if (this[XmlILOptimization.EliminateLength]) {
617                 if (( ( (local1).XmlType ).IsSingleton ) && ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
618                     // PATTERN: [EliminateLength] (Length $x:* ^ (Single? (TypeOf $x)) ^ (NoSideEffects? $x)) => (LiteralInt32 1)
619                     if (AllowReplace(XmlILOptimization.EliminateLength, local0)) {
620                         return Replace(XmlILOptimization.EliminateLength, local0, VisitLiteralInt32(f.LiteralInt32(1)));
621                     }
622                 }
623             }
624             if (this[XmlILOptimization.IntroducePrecedingDod]) {
625                 if ((!( IsDocOrderDistinct(local1) )) && (( IsStepPattern(local1, QilNodeType.XPathPreceding) ) || ( IsStepPattern(local1, QilNodeType.PrecedingSibling) ))) {
626                     // PATTERN: [IntroducePrecedingDod] (Length $expr:* ^ ~((DocOrderDistinct? $expr)) ^ (StepPattern? $expr {XPathPreceding}) | (StepPattern? $expr {PrecedingSibling})) => (Length (DocOrderDistinct $expr))
627                     if (AllowReplace(XmlILOptimization.IntroducePrecedingDod, local0)) {
628                         return Replace(XmlILOptimization.IntroducePrecedingDod, local0, VisitLength(f.Length(VisitDocOrderDistinct(f.DocOrderDistinct(local1)))));
629                     }
630                 }
631             }
632             return NoReplace(local0);
633         }
634
635         protected override QilNode VisitSequence(QilList local0) {
636             if (( (local0).Count == (1) ) && (this[XmlILOptimization.EliminateSequence])) {
637                 // PATTERN: [EliminateSequence] $x:(Sequence) ^ (Count? $x 1) => (First $x)
638                 if (AllowReplace(XmlILOptimization.EliminateSequence, local0)) {
639                     return Replace(XmlILOptimization.EliminateSequence, local0,  (QilNode) (local0)[0] );
640                 }
641             }
642             if (( HasNestedSequence(local0) ) && (this[XmlILOptimization.NormalizeNestedSequences])) {
643                 // PATTERN: [NormalizeNestedSequences] $seq:(Sequence) ^ (NestedSequences? $seq) => $result:(Sequence) ^ { ... } ^ $result
644                 if (AllowReplace(XmlILOptimization.NormalizeNestedSequences, local0)) {
645                     QilNode local1 = VisitSequence(f.Sequence());
646                     foreach (QilNode nd in local0) {
647                         if (nd.NodeType == QilNodeType.Sequence)
648                             local1.Add((IList<QilNode>) nd);
649                         else
650                             local1.Add(nd);
651                     }
652
653                     // Match patterns on new sequence
654                     local1= VisitSequence((QilList) local1);
655                     return Replace(XmlILOptimization.NormalizeNestedSequences, local0, local1);
656                 }
657             }
658             return NoReplace(local0);
659         }
660
661         protected override QilNode VisitUnion(QilBinary local0) {
662             QilNode local1 = local0[0];
663             QilNode local2 = local0[1];
664             if (this[XmlILOptimization.FoldNone]) {
665                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
666                     // PATTERN: [FoldNone] (Union $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
667                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
668                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
669                     }
670                 }
671             }
672             if (this[XmlILOptimization.FoldNone]) {
673                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
674                     // PATTERN: [FoldNone] (Union * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
675                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
676                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
677                     }
678                 }
679             }
680             if (this[XmlILOptimization.EliminateUnion]) {
681                 if (local2 == local1) {
682                     // PATTERN: [EliminateUnion] (Union $x:* $x) => (DocOrderDistinct $x)
683                     if (AllowReplace(XmlILOptimization.EliminateUnion, local0)) {
684                         return Replace(XmlILOptimization.EliminateUnion, local0, VisitDocOrderDistinct(f.DocOrderDistinct(local1)));
685                     }
686                 }
687             }
688             if (this[XmlILOptimization.EliminateUnion]) {
689                 if (local1.NodeType == QilNodeType.Sequence) {
690                     if ( (local1).Count == (0) ) {
691                         // PATTERN: [EliminateUnion] (Union $x:(Sequence) ^ (Count? $x 0) $y:*) => (DocOrderDistinct $y)
692                         if (AllowReplace(XmlILOptimization.EliminateUnion, local0)) {
693                             return Replace(XmlILOptimization.EliminateUnion, local0, VisitDocOrderDistinct(f.DocOrderDistinct(local2)));
694                         }
695                     }
696                 }
697             }
698             if (this[XmlILOptimization.EliminateUnion]) {
699                 if (local2.NodeType == QilNodeType.Sequence) {
700                     if ( (local2).Count == (0) ) {
701                         // PATTERN: [EliminateUnion] (Union $x:* $y:(Sequence) ^ (Count? $y 0)) => (DocOrderDistinct $x)
702                         if (AllowReplace(XmlILOptimization.EliminateUnion, local0)) {
703                             return Replace(XmlILOptimization.EliminateUnion, local0, VisitDocOrderDistinct(f.DocOrderDistinct(local1)));
704                         }
705                     }
706                 }
707             }
708             if (this[XmlILOptimization.EliminateUnion]) {
709                 if (local1.NodeType == QilNodeType.XmlContext) {
710                     if (local2.NodeType == QilNodeType.XmlContext) {
711                         // PATTERN: [EliminateUnion] (Union $x:XmlContext XmlContext) => $x
712                         if (AllowReplace(XmlILOptimization.EliminateUnion, local0)) {
713                             return Replace(XmlILOptimization.EliminateUnion, local0, local1);
714                         }
715                     }
716                 }
717             }
718             if (this[XmlILOptimization.NormalizeUnion]) {
719                 if ((!( IsDocOrderDistinct(local1) )) || (!( IsDocOrderDistinct(local2) ))) {
720                     // PATTERN: [NormalizeUnion] (Union $left:* $right:* ^ ~((DocOrderDistinct? $left)) | ~((DocOrderDistinct? $right))) => (Union (DocOrderDistinct $left) (DocOrderDistinct $right))
721                     if (AllowReplace(XmlILOptimization.NormalizeUnion, local0)) {
722                         return Replace(XmlILOptimization.NormalizeUnion, local0, VisitUnion(f.Union(VisitDocOrderDistinct(f.DocOrderDistinct(local1)), VisitDocOrderDistinct(f.DocOrderDistinct(local2)))));
723                     }
724                 }
725             }
726             if (this[XmlILOptimization.AnnotateUnion]) {
727                 // PATTERN: [AnnotateUnion] $outer:(Union * *) => (AddPattern $outer {IsDocOrderDistinct}) ^ { }
728                 if (AllowReplace(XmlILOptimization.AnnotateUnion, local0)) {
729                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
730             }
731             if (this[XmlILOptimization.AnnotateUnionContent]) {
732                 if (( IsStepPattern(local1, QilNodeType.Content) ) || ( IsStepPattern(local1, QilNodeType.Union) )) {
733                     if ((( IsStepPattern(local2, QilNodeType.Content) ) || ( IsStepPattern(local2, QilNodeType.Union) )) && ( ( OptimizerPatterns.Read((QilNode) (local1)).GetArgument(OptimizerPatternArgument.StepInput) ) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
734                         // PATTERN: [AnnotateUnionContent] $outer:(Union $left:* ^ (StepPattern? $left {Content}) | (StepPattern? $left {Union}) $right:* ^ (StepPattern? $right {Content}) | (StepPattern? $right {Union}) ^ (Equal? (Argument $left {StepInput}) (Argument $right {StepInput}))) => (AddStepPattern $outer (Argument $left {StepInput})) ^ (AddPattern $outer {SameDepth}) ^ { }
735                         if (AllowReplace(XmlILOptimization.AnnotateUnionContent, local0)) {
736                              AddStepPattern((QilNode) (local0), (QilNode) ( OptimizerPatterns.Read((QilNode) (local1)).GetArgument(OptimizerPatternArgument.StepInput) ));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
737                     }
738                 }
739             }
740             return NoReplace(local0);
741         }
742
743         protected override QilNode VisitIntersection(QilBinary local0) {
744             QilNode local1 = local0[0];
745             QilNode local2 = local0[1];
746             if (this[XmlILOptimization.FoldNone]) {
747                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
748                     // PATTERN: [FoldNone] (Intersection $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
749                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
750                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
751                     }
752                 }
753             }
754             if (this[XmlILOptimization.FoldNone]) {
755                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
756                     // PATTERN: [FoldNone] (Intersection * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
757                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
758                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
759                     }
760                 }
761             }
762             if (this[XmlILOptimization.EliminateIntersection]) {
763                 if (local2 == local1) {
764                     // PATTERN: [EliminateIntersection] (Intersection $x:* $x) => (DocOrderDistinct $x)
765                     if (AllowReplace(XmlILOptimization.EliminateIntersection, local0)) {
766                         return Replace(XmlILOptimization.EliminateIntersection, local0, VisitDocOrderDistinct(f.DocOrderDistinct(local1)));
767                     }
768                 }
769             }
770             if (this[XmlILOptimization.EliminateIntersection]) {
771                 if (local1.NodeType == QilNodeType.Sequence) {
772                     if ( (local1).Count == (0) ) {
773                         // PATTERN: [EliminateIntersection] (Intersection $x:(Sequence) ^ (Count? $x 0) *) => $x
774                         if (AllowReplace(XmlILOptimization.EliminateIntersection, local0)) {
775                             return Replace(XmlILOptimization.EliminateIntersection, local0, local1);
776                         }
777                     }
778                 }
779             }
780             if (this[XmlILOptimization.EliminateIntersection]) {
781                 if (local2.NodeType == QilNodeType.Sequence) {
782                     if ( (local2).Count == (0) ) {
783                         // PATTERN: [EliminateIntersection] (Intersection * $y:(Sequence) ^ (Count? $y 0)) => $y
784                         if (AllowReplace(XmlILOptimization.EliminateIntersection, local0)) {
785                             return Replace(XmlILOptimization.EliminateIntersection, local0, local2);
786                         }
787                     }
788                 }
789             }
790             if (this[XmlILOptimization.EliminateIntersection]) {
791                 if (local1.NodeType == QilNodeType.XmlContext) {
792                     if (local2.NodeType == QilNodeType.XmlContext) {
793                         // PATTERN: [EliminateIntersection] (Intersection $x:XmlContext XmlContext) => $x
794                         if (AllowReplace(XmlILOptimization.EliminateIntersection, local0)) {
795                             return Replace(XmlILOptimization.EliminateIntersection, local0, local1);
796                         }
797                     }
798                 }
799             }
800             if (this[XmlILOptimization.NormalizeIntersect]) {
801                 if ((!( IsDocOrderDistinct(local1) )) || (!( IsDocOrderDistinct(local2) ))) {
802                     // PATTERN: [NormalizeIntersect] (Intersection $left:* $right:* ^ ~((DocOrderDistinct? $left)) | ~((DocOrderDistinct? $right))) => (Intersection (DocOrderDistinct $left) (DocOrderDistinct $right))
803                     if (AllowReplace(XmlILOptimization.NormalizeIntersect, local0)) {
804                         return Replace(XmlILOptimization.NormalizeIntersect, local0, VisitIntersection(f.Intersection(VisitDocOrderDistinct(f.DocOrderDistinct(local1)), VisitDocOrderDistinct(f.DocOrderDistinct(local2)))));
805                     }
806                 }
807             }
808             if (this[XmlILOptimization.AnnotateIntersect]) {
809                 // PATTERN: [AnnotateIntersect] $outer:(Intersection * *) => (AddPattern $outer {IsDocOrderDistinct}) ^ { }
810                 if (AllowReplace(XmlILOptimization.AnnotateIntersect, local0)) {
811                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
812             }
813             return NoReplace(local0);
814         }
815
816         protected override QilNode VisitDifference(QilBinary local0) {
817             QilNode local1 = local0[0];
818             QilNode local2 = local0[1];
819             if (this[XmlILOptimization.FoldNone]) {
820                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
821                     // PATTERN: [FoldNone] (Difference $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
822                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
823                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
824                     }
825                 }
826             }
827             if (this[XmlILOptimization.FoldNone]) {
828                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
829                     // PATTERN: [FoldNone] (Difference * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
830                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
831                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
832                     }
833                 }
834             }
835             if (this[XmlILOptimization.EliminateDifference]) {
836                 if (local1.NodeType == QilNodeType.Sequence) {
837                     if ( (local1).Count == (0) ) {
838                         // PATTERN: [EliminateDifference] (Difference $x:(Sequence) ^ (Count? $x 0) $y:*) => $x
839                         if (AllowReplace(XmlILOptimization.EliminateDifference, local0)) {
840                             return Replace(XmlILOptimization.EliminateDifference, local0, local1);
841                         }
842                     }
843                 }
844             }
845             if (this[XmlILOptimization.EliminateDifference]) {
846                 if (local2.NodeType == QilNodeType.Sequence) {
847                     if ( (local2).Count == (0) ) {
848                         // PATTERN: [EliminateDifference] (Difference $x:* $y:(Sequence) ^ (Count? $y 0)) => (DocOrderDistinct $x)
849                         if (AllowReplace(XmlILOptimization.EliminateDifference, local0)) {
850                             return Replace(XmlILOptimization.EliminateDifference, local0, VisitDocOrderDistinct(f.DocOrderDistinct(local1)));
851                         }
852                     }
853                 }
854             }
855             if (this[XmlILOptimization.EliminateDifference]) {
856                 if (local2 == local1) {
857                     // PATTERN: [EliminateDifference] (Difference $x:* $x) => (Sequence)
858                     if (AllowReplace(XmlILOptimization.EliminateDifference, local0)) {
859                         return Replace(XmlILOptimization.EliminateDifference, local0, VisitSequence(f.Sequence()));
860                     }
861                 }
862             }
863             if (this[XmlILOptimization.EliminateDifference]) {
864                 if (local1.NodeType == QilNodeType.XmlContext) {
865                     if (local2.NodeType == QilNodeType.XmlContext) {
866                         // PATTERN: [EliminateDifference] (Difference XmlContext XmlContext) => (Sequence)
867                         if (AllowReplace(XmlILOptimization.EliminateDifference, local0)) {
868                             return Replace(XmlILOptimization.EliminateDifference, local0, VisitSequence(f.Sequence()));
869                         }
870                     }
871                 }
872             }
873             if (this[XmlILOptimization.NormalizeDifference]) {
874                 if ((!( IsDocOrderDistinct(local1) )) || (!( IsDocOrderDistinct(local2) ))) {
875                     // PATTERN: [NormalizeDifference] (Difference $left:* $right:* ^ ~((DocOrderDistinct? $left)) | ~((DocOrderDistinct? $right))) => (Difference (DocOrderDistinct $left) (DocOrderDistinct $right))
876                     if (AllowReplace(XmlILOptimization.NormalizeDifference, local0)) {
877                         return Replace(XmlILOptimization.NormalizeDifference, local0, VisitDifference(f.Difference(VisitDocOrderDistinct(f.DocOrderDistinct(local1)), VisitDocOrderDistinct(f.DocOrderDistinct(local2)))));
878                     }
879                 }
880             }
881             if (this[XmlILOptimization.AnnotateDifference]) {
882                 // PATTERN: [AnnotateDifference] $outer:(Difference * *) => (AddPattern $outer {IsDocOrderDistinct}) ^ { }
883                 if (AllowReplace(XmlILOptimization.AnnotateDifference, local0)) {
884                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
885             }
886             return NoReplace(local0);
887         }
888
889         protected override QilNode VisitAverage(QilUnary local0) {
890             QilNode local1 = local0[0];
891             if (this[XmlILOptimization.FoldNone]) {
892                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
893                     // PATTERN: [FoldNone] (Average $x:* ^ (None? (TypeOf $x))) => (Nop $x)
894                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
895                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
896                     }
897                 }
898             }
899             if (this[XmlILOptimization.EliminateAverage]) {
900                 if ( ( (local1).XmlType ).Cardinality == XmlQueryCardinality.Zero ) {
901                     // PATTERN: [EliminateAverage] (Average $x:* ^ (Empty? (TypeOf $x))) => (Nop $x)
902                     if (AllowReplace(XmlILOptimization.EliminateAverage, local0)) {
903                         return Replace(XmlILOptimization.EliminateAverage, local0, VisitNop(f.Nop(local1)));
904                     }
905                 }
906             }
907             return NoReplace(local0);
908         }
909
910         protected override QilNode VisitSum(QilUnary local0) {
911             QilNode local1 = local0[0];
912             if (this[XmlILOptimization.FoldNone]) {
913                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
914                     // PATTERN: [FoldNone] (Sum $x:* ^ (None? (TypeOf $x))) => (Nop $x)
915                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
916                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
917                     }
918                 }
919             }
920             if (this[XmlILOptimization.EliminateSum]) {
921                 if ( ( (local1).XmlType ).Cardinality == XmlQueryCardinality.Zero ) {
922                     // PATTERN: [EliminateSum] (Sum $x:* ^ (Empty? (TypeOf $x))) => (Nop $x)
923                     if (AllowReplace(XmlILOptimization.EliminateSum, local0)) {
924                         return Replace(XmlILOptimization.EliminateSum, local0, VisitNop(f.Nop(local1)));
925                     }
926                 }
927             }
928             return NoReplace(local0);
929         }
930
931         protected override QilNode VisitMinimum(QilUnary local0) {
932             QilNode local1 = local0[0];
933             if (this[XmlILOptimization.FoldNone]) {
934                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
935                     // PATTERN: [FoldNone] (Minimum $x:* ^ (None? (TypeOf $x))) => (Nop $x)
936                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
937                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
938                     }
939                 }
940             }
941             if (this[XmlILOptimization.EliminateMinimum]) {
942                 if ( ( (local1).XmlType ).Cardinality == XmlQueryCardinality.Zero ) {
943                     // PATTERN: [EliminateMinimum] (Minimum $x:* ^ (Empty? (TypeOf $x))) => (Nop $x)
944                     if (AllowReplace(XmlILOptimization.EliminateMinimum, local0)) {
945                         return Replace(XmlILOptimization.EliminateMinimum, local0, VisitNop(f.Nop(local1)));
946                     }
947                 }
948             }
949             return NoReplace(local0);
950         }
951
952         protected override QilNode VisitMaximum(QilUnary local0) {
953             QilNode local1 = local0[0];
954             if (this[XmlILOptimization.FoldNone]) {
955                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
956                     // PATTERN: [FoldNone] (Maximum $x:* ^ (None? (TypeOf $x))) => (Nop $x)
957                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
958                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
959                     }
960                 }
961             }
962             if (this[XmlILOptimization.EliminateMaximum]) {
963                 if ( ( (local1).XmlType ).Cardinality == XmlQueryCardinality.Zero ) {
964                     // PATTERN: [EliminateMaximum] (Maximum $x:* ^ (Empty? (TypeOf $x))) => (Nop $x)
965                     if (AllowReplace(XmlILOptimization.EliminateMaximum, local0)) {
966                         return Replace(XmlILOptimization.EliminateMaximum, local0, VisitNop(f.Nop(local1)));
967                     }
968                 }
969             }
970             return NoReplace(local0);
971         }
972
973         #endregion // collection operators
974
975         #region arithmetic operators
976         protected override QilNode VisitNegate(QilUnary local0) {
977             QilNode local1 = local0[0];
978             if (this[XmlILOptimization.FoldNone]) {
979                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
980                     // PATTERN: [FoldNone] (Negate $x:* ^ (None? (TypeOf $x))) => (Nop $x)
981                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
982                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
983                     }
984                 }
985             }
986             if (this[XmlILOptimization.EliminateNegate]) {
987                 if (local1.NodeType == QilNodeType.LiteralDecimal) {
988                     decimal local2 = (decimal)((QilLiteral)local1).Value;
989                     // PATTERN: [EliminateNegate] (Negate (LiteralDecimal $x:*)) => (LiteralDecimal { -{$x} })
990                     if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) {
991                         return Replace(XmlILOptimization.EliminateNegate, local0, VisitLiteralDecimal(f.LiteralDecimal( -local2 )));
992                     }
993                 }
994             }
995             if (this[XmlILOptimization.EliminateNegate]) {
996                 if (local1.NodeType == QilNodeType.LiteralDouble) {
997                     double local2 = (double)((QilLiteral)local1).Value;
998                     // PATTERN: [EliminateNegate] (Negate (LiteralDouble $x:*)) => (LiteralDouble { -{$x} })
999                     if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) {
1000                         return Replace(XmlILOptimization.EliminateNegate, local0, VisitLiteralDouble(f.LiteralDouble( -local2 )));
1001                     }
1002                 }
1003             }
1004             if (this[XmlILOptimization.EliminateNegate]) {
1005                 if (local1.NodeType == QilNodeType.LiteralInt32) {
1006                     int local2 = (int)((QilLiteral)local1).Value;
1007                     // PATTERN: [EliminateNegate] (Negate (LiteralInt32 $x:*)) => (LiteralInt32 { -{$x} })
1008                     if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) {
1009                         return Replace(XmlILOptimization.EliminateNegate, local0, VisitLiteralInt32(f.LiteralInt32( -local2 )));
1010                     }
1011                 }
1012             }
1013             if (this[XmlILOptimization.EliminateNegate]) {
1014                 if (local1.NodeType == QilNodeType.LiteralInt64) {
1015                     long local2 = (long)((QilLiteral)local1).Value;
1016                     // PATTERN: [EliminateNegate] (Negate (LiteralInt64 $x:*)) => (LiteralInt64 { -{$x} })
1017                     if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) {
1018                         return Replace(XmlILOptimization.EliminateNegate, local0, VisitLiteralInt64(f.LiteralInt64( -local2 )));
1019                     }
1020                 }
1021             }
1022             return NoReplace(local0);
1023         }
1024
1025         protected override QilNode VisitAdd(QilBinary local0) {
1026             QilNode local1 = local0[0];
1027             QilNode local2 = local0[1];
1028             if (this[XmlILOptimization.FoldNone]) {
1029                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1030                     // PATTERN: [FoldNone] (Add $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1031                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1032                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1033                     }
1034                 }
1035             }
1036             if (this[XmlILOptimization.FoldNone]) {
1037                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1038                     // PATTERN: [FoldNone] (Add * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1039                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1040                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1041                     }
1042                 }
1043             }
1044             if (this[XmlILOptimization.EliminateAdd]) {
1045                 if ( IsLiteral((local1)) ) {
1046                     if (( IsLiteral((local2)) ) && ( CanFoldArithmetic(QilNodeType.Add, (QilLiteral) local1, (QilLiteral) local2) )) {
1047                         // PATTERN: [EliminateAdd] (Add $x:* ^ (Literal? $x) $y:* ^ (Literal? $y) ^ (CanFoldAdd? $x $y)) => (Add! $x $y)
1048                         if (AllowReplace(XmlILOptimization.EliminateAdd, local0)) {
1049                             return Replace(XmlILOptimization.EliminateAdd, local0,  FoldArithmetic(QilNodeType.Add, (QilLiteral) local1, (QilLiteral) local2) );
1050                         }
1051                     }
1052                 }
1053             }
1054             if (this[XmlILOptimization.NormalizeAddLiteral]) {
1055                 if ( IsLiteral((local1)) ) {
1056                     if (!( IsLiteral((local2)) )) {
1057                         // PATTERN: [NormalizeAddLiteral] (Add $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Add $right $left)
1058                         if (AllowReplace(XmlILOptimization.NormalizeAddLiteral, local0)) {
1059                             return Replace(XmlILOptimization.NormalizeAddLiteral, local0, VisitAdd(f.Add(local2, local1)));
1060                         }
1061                     }
1062                 }
1063             }
1064             return NoReplace(local0);
1065         }
1066
1067         protected override QilNode VisitSubtract(QilBinary local0) {
1068             QilNode local1 = local0[0];
1069             QilNode local2 = local0[1];
1070             if (this[XmlILOptimization.FoldNone]) {
1071                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1072                     // PATTERN: [FoldNone] (Subtract $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1073                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1074                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1075                     }
1076                 }
1077             }
1078             if (this[XmlILOptimization.FoldNone]) {
1079                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1080                     // PATTERN: [FoldNone] (Subtract * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1081                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1082                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1083                     }
1084                 }
1085             }
1086             if (this[XmlILOptimization.EliminateSubtract]) {
1087                 if ( IsLiteral((local1)) ) {
1088                     if (( IsLiteral((local2)) ) && ( CanFoldArithmetic(QilNodeType.Subtract, (QilLiteral) local1, (QilLiteral) local2) )) {
1089                         // PATTERN: [EliminateSubtract] (Subtract $x:* ^ (Literal? $x) $y:* ^ (Literal? $y) ^ (CanFoldSub? $x $y)) => (Sub! $x $y)
1090                         if (AllowReplace(XmlILOptimization.EliminateSubtract, local0)) {
1091                             return Replace(XmlILOptimization.EliminateSubtract, local0,  FoldArithmetic(QilNodeType.Subtract, (QilLiteral) local1, (QilLiteral) local2) );
1092                         }
1093                     }
1094                 }
1095             }
1096             return NoReplace(local0);
1097         }
1098
1099         protected override QilNode VisitMultiply(QilBinary local0) {
1100             QilNode local1 = local0[0];
1101             QilNode local2 = local0[1];
1102             if (this[XmlILOptimization.FoldNone]) {
1103                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1104                     // PATTERN: [FoldNone] (Multiply $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1105                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1106                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1107                     }
1108                 }
1109             }
1110             if (this[XmlILOptimization.FoldNone]) {
1111                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1112                     // PATTERN: [FoldNone] (Multiply * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1113                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1114                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1115                     }
1116                 }
1117             }
1118             if (this[XmlILOptimization.EliminateMultiply]) {
1119                 if ( IsLiteral((local1)) ) {
1120                     if (( IsLiteral((local2)) ) && ( CanFoldArithmetic(QilNodeType.Multiply, (QilLiteral) local1, (QilLiteral) local2) )) {
1121                         // PATTERN: [EliminateMultiply] (Multiply $x:* ^ (Literal? $x) $y:* ^ (Literal? $y) ^ (CanFoldMul? $x $y)) => (Mul! $x $y)
1122                         if (AllowReplace(XmlILOptimization.EliminateMultiply, local0)) {
1123                             return Replace(XmlILOptimization.EliminateMultiply, local0,  FoldArithmetic(QilNodeType.Multiply, (QilLiteral) local1, (QilLiteral) local2) );
1124                         }
1125                     }
1126                 }
1127             }
1128             if (this[XmlILOptimization.NormalizeMultiplyLiteral]) {
1129                 if ( IsLiteral((local1)) ) {
1130                     if (!( IsLiteral((local2)) )) {
1131                         // PATTERN: [NormalizeMultiplyLiteral] (Multiply $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Multiply $right $left)
1132                         if (AllowReplace(XmlILOptimization.NormalizeMultiplyLiteral, local0)) {
1133                             return Replace(XmlILOptimization.NormalizeMultiplyLiteral, local0, VisitMultiply(f.Multiply(local2, local1)));
1134                         }
1135                     }
1136                 }
1137             }
1138             return NoReplace(local0);
1139         }
1140
1141         protected override QilNode VisitDivide(QilBinary local0) {
1142             QilNode local1 = local0[0];
1143             QilNode local2 = local0[1];
1144             if (this[XmlILOptimization.FoldNone]) {
1145                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1146                     // PATTERN: [FoldNone] (Divide $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1147                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1148                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1149                     }
1150                 }
1151             }
1152             if (this[XmlILOptimization.FoldNone]) {
1153                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1154                     // PATTERN: [FoldNone] (Divide * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1155                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1156                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1157                     }
1158                 }
1159             }
1160             if (this[XmlILOptimization.EliminateDivide]) {
1161                 if ( IsLiteral((local1)) ) {
1162                     if (( IsLiteral((local2)) ) && ( CanFoldArithmetic(QilNodeType.Divide, (QilLiteral) local1, (QilLiteral) local2) )) {
1163                         // PATTERN: [EliminateDivide] (Divide $x:* ^ (Literal? $x) $y:* ^ (Literal? $y) ^ (CanFoldDiv? $x $y)) => (Div! $x $y)
1164                         if (AllowReplace(XmlILOptimization.EliminateDivide, local0)) {
1165                             return Replace(XmlILOptimization.EliminateDivide, local0,  FoldArithmetic(QilNodeType.Divide, (QilLiteral) local1, (QilLiteral) local2) );
1166                         }
1167                     }
1168                 }
1169             }
1170             return NoReplace(local0);
1171         }
1172
1173         protected override QilNode VisitModulo(QilBinary local0) {
1174             QilNode local1 = local0[0];
1175             QilNode local2 = local0[1];
1176             if (this[XmlILOptimization.FoldNone]) {
1177                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1178                     // PATTERN: [FoldNone] (Modulo $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1179                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1180                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1181                     }
1182                 }
1183             }
1184             if (this[XmlILOptimization.FoldNone]) {
1185                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1186                     // PATTERN: [FoldNone] (Modulo * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1187                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1188                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1189                     }
1190                 }
1191             }
1192             if (this[XmlILOptimization.EliminateModulo]) {
1193                 if ( IsLiteral((local1)) ) {
1194                     if (( IsLiteral((local2)) ) && ( CanFoldArithmetic(QilNodeType.Modulo, (QilLiteral) local1, (QilLiteral) local2) )) {
1195                         // PATTERN: [EliminateModulo] (Modulo $x:* ^ (Literal? $x) $y:* ^ (Literal? $y) ^ (CanFoldMod? $x $y)) => (Mod! $x $y)
1196                         if (AllowReplace(XmlILOptimization.EliminateModulo, local0)) {
1197                             return Replace(XmlILOptimization.EliminateModulo, local0,  FoldArithmetic(QilNodeType.Modulo, (QilLiteral) local1, (QilLiteral) local2) );
1198                         }
1199                     }
1200                 }
1201             }
1202             return NoReplace(local0);
1203         }
1204
1205         #endregion // arithmetic operators
1206
1207         #region string operators
1208         protected override QilNode VisitStrLength(QilUnary local0) {
1209             QilNode local1 = local0[0];
1210             if (this[XmlILOptimization.FoldNone]) {
1211                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1212                     // PATTERN: [FoldNone] (StrLength $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1213                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1214                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1215                     }
1216                 }
1217             }
1218             if (this[XmlILOptimization.EliminateStrLength]) {
1219                 if (local1.NodeType == QilNodeType.LiteralString) {
1220                     string local2 = (string)((QilLiteral)local1).Value;
1221                     // PATTERN: [EliminateStrLength] (StrLength (LiteralString $x:*)) => (LiteralInt32 { {$x}.Length })
1222                     if (AllowReplace(XmlILOptimization.EliminateStrLength, local0)) {
1223                         return Replace(XmlILOptimization.EliminateStrLength, local0, VisitLiteralInt32(f.LiteralInt32( local2.Length )));
1224                     }
1225                 }
1226             }
1227             return NoReplace(local0);
1228         }
1229
1230         protected override QilNode VisitStrConcat(QilStrConcat local0) {
1231             QilNode local1 = local0[0];
1232             QilNode local2 = local0[1];
1233             if (this[XmlILOptimization.FoldNone]) {
1234                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1235                     // PATTERN: [FoldNone] (StrConcat $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1236                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1237                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1238                     }
1239                 }
1240             }
1241             if (this[XmlILOptimization.FoldNone]) {
1242                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1243                     // PATTERN: [FoldNone] (StrConcat * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1244                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1245                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1246                     }
1247                 }
1248             }
1249             if (( ( (local2).XmlType ).IsSingleton ) && (this[XmlILOptimization.EliminateStrConcatSingle])) {
1250                 // PATTERN: [EliminateStrConcatSingle] (StrConcat * $x:*) ^ (Single? (TypeOf $x)) => (Nop $x)
1251                 if (AllowReplace(XmlILOptimization.EliminateStrConcatSingle, local0)) {
1252                     return Replace(XmlILOptimization.EliminateStrConcatSingle, local0, VisitNop(f.Nop(local2)));
1253                 }
1254             }
1255             if (this[XmlILOptimization.EliminateStrConcat]) {
1256                 if (local1.NodeType == QilNodeType.LiteralString) {
1257                     string local3 = (string)((QilLiteral)local1).Value;
1258                     if (local2.NodeType == QilNodeType.Sequence) {
1259                         if ( AreLiteralArgs(local2) ) {
1260                             // PATTERN: [EliminateStrConcat] (StrConcat (LiteralString $delim:*) $values:(Sequence) ^ (LiteralArgs? $values)) => { ... } ^ (LiteralString { concat.GetResult() })
1261                             if (AllowReplace(XmlILOptimization.EliminateStrConcat, local0)) {
1262                                 // Concatenate all constant arguments
1263                                 StringConcat concat = new StringConcat();
1264                                 concat.Delimiter = local3;
1265
1266                                 foreach (QilLiteral lit in local2)
1267                                     concat.Concat((string) lit);
1268                                 return Replace(XmlILOptimization.EliminateStrConcat, local0, VisitLiteralString(f.LiteralString( concat.GetResult() )));
1269                             }
1270                         }
1271                     }
1272                 }
1273             }
1274             return NoReplace(local0);
1275         }
1276
1277         protected override QilNode VisitStrParseQName(QilBinary local0) {
1278             QilNode local1 = local0[0];
1279             QilNode local2 = local0[1];
1280             if (this[XmlILOptimization.FoldNone]) {
1281                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1282                     // PATTERN: [FoldNone] (StrParseQName $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1283                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1284                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1285                     }
1286                 }
1287             }
1288             if (this[XmlILOptimization.FoldNone]) {
1289                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1290                     // PATTERN: [FoldNone] (StrParseQName * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1291                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1292                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1293                     }
1294                 }
1295             }
1296             return NoReplace(local0);
1297         }
1298
1299         #endregion // string operators
1300
1301         #region value comparison operators
1302         protected override QilNode VisitNe(QilBinary local0) {
1303             QilNode local1 = local0[0];
1304             QilNode local2 = local0[1];
1305             if (this[XmlILOptimization.FoldNone]) {
1306                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1307                     // PATTERN: [FoldNone] (Ne $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1308                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1309                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1310                     }
1311                 }
1312             }
1313             if (this[XmlILOptimization.FoldNone]) {
1314                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1315                     // PATTERN: [FoldNone] (Ne * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1316                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1317                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1318                     }
1319                 }
1320             }
1321             if (this[XmlILOptimization.EliminateNe]) {
1322                 if ( IsLiteral((local1)) ) {
1323                     if ( IsLiteral((local2)) ) {
1324                         // PATTERN: [EliminateNe] (Ne $x:* ^ (Literal? $x) $y:* ^ (Literal? $y)) => (Ne! $x $y)
1325                         if (AllowReplace(XmlILOptimization.EliminateNe, local0)) {
1326                             return Replace(XmlILOptimization.EliminateNe, local0,  FoldComparison(QilNodeType.Ne, local1, local2) );
1327                         }
1328                     }
1329                 }
1330             }
1331             if (this[XmlILOptimization.NormalizeNeLiteral]) {
1332                 if ( IsLiteral((local1)) ) {
1333                     if (!( IsLiteral((local2)) )) {
1334                         // PATTERN: [NormalizeNeLiteral] (Ne $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Ne $right $left)
1335                         if (AllowReplace(XmlILOptimization.NormalizeNeLiteral, local0)) {
1336                             return Replace(XmlILOptimization.NormalizeNeLiteral, local0, VisitNe(f.Ne(local2, local1)));
1337                         }
1338                     }
1339                 }
1340             }
1341             if (this[XmlILOptimization.NormalizeXsltConvertNe]) {
1342                 if (local1.NodeType == QilNodeType.XsltConvert) {
1343                     QilNode local3 = local1[0];
1344                     QilNode local4 = local1[1];
1345                     if (local4.NodeType == QilNodeType.LiteralType) {
1346                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
1347                         if (( IsPrimitiveNumeric( (local3).XmlType ) ) && ( IsPrimitiveNumeric(local5) )) {
1348                             if (( IsLiteral((local2)) ) && ( CanFoldXsltConvertNonLossy(local2,  (local3).XmlType ) )) {
1349                                 // PATTERN: [NormalizeXsltConvertNe] (Ne (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Ne $expr (FoldXsltConvert $lit (TypeOf $expr)))
1350                                 if (AllowReplace(XmlILOptimization.NormalizeXsltConvertNe, local0)) {
1351                                     return Replace(XmlILOptimization.NormalizeXsltConvertNe, local0, VisitNe(f.Ne(local3,  FoldXsltConvert(local2,  (local3).XmlType ) )));
1352                                 }
1353                             }
1354                         }
1355                     }
1356                 }
1357             }
1358             if (this[XmlILOptimization.NormalizeIdNe]) {
1359                 if (local1.NodeType == QilNodeType.XsltGenerateId) {
1360                     QilNode local3 = local1[0];
1361                     if ( ( (local3).XmlType ).IsSingleton ) {
1362                         if (local2.NodeType == QilNodeType.XsltGenerateId) {
1363                             QilNode local4 = local2[0];
1364                             if ( ( (local4).XmlType ).IsSingleton ) {
1365                                 // PATTERN: [NormalizeIdNe] (Ne (XsltGenerateId $arg1:*) ^ (Single? (TypeOf $arg1)) (XsltGenerateId $arg2:*) ^ (Single? (TypeOf $arg2))) => (Not (Is $arg1 $arg2))
1366                                 if (AllowReplace(XmlILOptimization.NormalizeIdNe, local0)) {
1367                                     return Replace(XmlILOptimization.NormalizeIdNe, local0, VisitNot(f.Not(VisitIs(f.Is(local3, local4)))));
1368                                 }
1369                             }
1370                         }
1371                     }
1372                 }
1373             }
1374             if (this[XmlILOptimization.NormalizeLengthNe]) {
1375                 if (local1.NodeType == QilNodeType.Length) {
1376                     QilNode local3 = local1[0];
1377                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1378                         int local4 = (int)((QilLiteral)local2).Value;
1379                         if (local4 == 0) {
1380                             // PATTERN: [NormalizeLengthNe] (Ne (Length $expr:*) (LiteralInt32 0)) => (Not (IsEmpty $expr))
1381                             if (AllowReplace(XmlILOptimization.NormalizeLengthNe, local0)) {
1382                                 return Replace(XmlILOptimization.NormalizeLengthNe, local0, VisitNot(f.Not(VisitIsEmpty(f.IsEmpty(local3)))));
1383                             }
1384                         }
1385                     }
1386                 }
1387             }
1388             if (this[XmlILOptimization.AnnotateMaxLengthNe]) {
1389                 if (local1.NodeType == QilNodeType.Length) {
1390                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1391                         int local4 = (int)((QilLiteral)local2).Value;
1392                         // PATTERN: [AnnotateMaxLengthNe] (Ne $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { }
1393                         if (AllowReplace(XmlILOptimization.AnnotateMaxLengthNe, local0)) {
1394                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local4);  }
1395                     }
1396                 }
1397             }
1398             return NoReplace(local0);
1399         }
1400
1401         protected override QilNode VisitEq(QilBinary local0) {
1402             QilNode local1 = local0[0];
1403             QilNode local2 = local0[1];
1404             if (this[XmlILOptimization.FoldNone]) {
1405                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1406                     // PATTERN: [FoldNone] (Eq $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1407                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1408                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1409                     }
1410                 }
1411             }
1412             if (this[XmlILOptimization.FoldNone]) {
1413                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1414                     // PATTERN: [FoldNone] (Eq * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1415                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1416                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1417                     }
1418                 }
1419             }
1420             if (this[XmlILOptimization.EliminateEq]) {
1421                 if ( IsLiteral((local1)) ) {
1422                     if ( IsLiteral((local2)) ) {
1423                         // PATTERN: [EliminateEq] (Eq $x:* ^ (Literal? $x) $y:* ^ (Literal? $y)) => (Eq! $x $y)
1424                         if (AllowReplace(XmlILOptimization.EliminateEq, local0)) {
1425                             return Replace(XmlILOptimization.EliminateEq, local0,  FoldComparison(QilNodeType.Eq, local1, local2) );
1426                         }
1427                     }
1428                 }
1429             }
1430             if (this[XmlILOptimization.NormalizeEqLiteral]) {
1431                 if ( IsLiteral((local1)) ) {
1432                     if (!( IsLiteral((local2)) )) {
1433                         // PATTERN: [NormalizeEqLiteral] (Eq $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Eq $right $left)
1434                         if (AllowReplace(XmlILOptimization.NormalizeEqLiteral, local0)) {
1435                             return Replace(XmlILOptimization.NormalizeEqLiteral, local0, VisitEq(f.Eq(local2, local1)));
1436                         }
1437                     }
1438                 }
1439             }
1440             if (this[XmlILOptimization.NormalizeXsltConvertEq]) {
1441                 if (local1.NodeType == QilNodeType.XsltConvert) {
1442                     QilNode local3 = local1[0];
1443                     QilNode local4 = local1[1];
1444                     if (local4.NodeType == QilNodeType.LiteralType) {
1445                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
1446                         if (( IsPrimitiveNumeric( (local3).XmlType ) ) && ( IsPrimitiveNumeric(local5) )) {
1447                             if (( IsLiteral((local2)) ) && ( CanFoldXsltConvertNonLossy(local2,  (local3).XmlType ) )) {
1448                                 // PATTERN: [NormalizeXsltConvertEq] (Eq (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Eq $expr (FoldXsltConvert $lit (TypeOf $expr)))
1449                                 if (AllowReplace(XmlILOptimization.NormalizeXsltConvertEq, local0)) {
1450                                     return Replace(XmlILOptimization.NormalizeXsltConvertEq, local0, VisitEq(f.Eq(local3,  FoldXsltConvert(local2,  (local3).XmlType ) )));
1451                                 }
1452                             }
1453                         }
1454                     }
1455                 }
1456             }
1457             if (this[XmlILOptimization.NormalizeAddEq]) {
1458                 if (local1.NodeType == QilNodeType.Add) {
1459                     QilNode local3 = local1[0];
1460                     QilNode local4 = local1[1];
1461                     if ( IsLiteral((local4)) ) {
1462                         if (( IsLiteral((local2)) ) && ( CanFoldArithmetic(QilNodeType.Subtract, (QilLiteral) local2, (QilLiteral) local4) )) {
1463                             // PATTERN: [NormalizeAddEq] (Eq (Add $exprAdd:* $litAdd:*) ^ (Literal? $litAdd) $litEq:* ^ (Literal? $litEq) ^ (CanFoldSub? $litEq $litAdd)) => (Eq $exprAdd (Sub! $litEq $litAdd))
1464                             if (AllowReplace(XmlILOptimization.NormalizeAddEq, local0)) {
1465                                 return Replace(XmlILOptimization.NormalizeAddEq, local0, VisitEq(f.Eq(local3,  FoldArithmetic(QilNodeType.Subtract, (QilLiteral) local2, (QilLiteral) local4) )));
1466                             }
1467                         }
1468                     }
1469                 }
1470             }
1471             if (this[XmlILOptimization.NormalizeIdEq]) {
1472                 if (local1.NodeType == QilNodeType.XsltGenerateId) {
1473                     QilNode local3 = local1[0];
1474                     if ( ( (local3).XmlType ).IsSingleton ) {
1475                         if (local2.NodeType == QilNodeType.XsltGenerateId) {
1476                             QilNode local4 = local2[0];
1477                             if ( ( (local4).XmlType ).IsSingleton ) {
1478                                 // PATTERN: [NormalizeIdEq] (Eq (XsltGenerateId $arg1:*) ^ (Single? (TypeOf $arg1)) (XsltGenerateId $arg2:*) ^ (Single? (TypeOf $arg2))) => (Is $arg1 $arg2)
1479                                 if (AllowReplace(XmlILOptimization.NormalizeIdEq, local0)) {
1480                                     return Replace(XmlILOptimization.NormalizeIdEq, local0, VisitIs(f.Is(local3, local4)));
1481                                 }
1482                             }
1483                         }
1484                     }
1485                 }
1486             }
1487             if (this[XmlILOptimization.NormalizeIdEq]) {
1488                 if (local1.NodeType == QilNodeType.XsltGenerateId) {
1489                     QilNode local3 = local1[0];
1490                     if ( ( (local3).XmlType ).IsSingleton ) {
1491                         if (local2.NodeType == QilNodeType.StrConcat) {
1492                             QilNode local5 = local2[1];
1493                             if (local5.NodeType == QilNodeType.Loop) {
1494                                 QilNode local6 = local5[0];
1495                                 QilNode local8 = local5[1];
1496                                 if (local6.NodeType == QilNodeType.For) {
1497                                     QilNode local7 = local6[0];
1498                                     if ( !( (local7).XmlType ).MaybeMany ) {
1499                                         if (local8.NodeType == QilNodeType.XsltGenerateId) {
1500                                             QilNode local9 = local8[0];
1501                                             if (local9 == local6) {
1502                                                 // PATTERN: [NormalizeIdEq] (Eq (XsltGenerateId $arg:*) ^ (Single? (TypeOf $arg)) (StrConcat * (Loop $iter:(For $bind:* ^ (AtMostOne? (TypeOf $bind))) (XsltGenerateId $iter)))) => (Not (IsEmpty (Filter $iterNew:(For $bind) (Is $arg $iterNew))))
1503                                                 if (AllowReplace(XmlILOptimization.NormalizeIdEq, local0)) {
1504                                                     QilNode local10 = VisitFor(f.For(local7));
1505                                                     return Replace(XmlILOptimization.NormalizeIdEq, local0, VisitNot(f.Not(VisitIsEmpty(f.IsEmpty(VisitFilter(f.Filter(local10, VisitIs(f.Is(local3, local10)))))))));
1506                                                 }
1507                                             }
1508                                         }
1509                                     }
1510                                 }
1511                             }
1512                         }
1513                     }
1514                 }
1515             }
1516             if (this[XmlILOptimization.NormalizeIdEq]) {
1517                 if (local1.NodeType == QilNodeType.StrConcat) {
1518                     QilNode local4 = local1[1];
1519                     if (local4.NodeType == QilNodeType.Loop) {
1520                         QilNode local5 = local4[0];
1521                         QilNode local7 = local4[1];
1522                         if (local5.NodeType == QilNodeType.For) {
1523                             QilNode local6 = local5[0];
1524                             if ( !( (local6).XmlType ).MaybeMany ) {
1525                                 if (local7.NodeType == QilNodeType.XsltGenerateId) {
1526                                     QilNode local8 = local7[0];
1527                                     if (local8 == local5) {
1528                                         if (local2.NodeType == QilNodeType.XsltGenerateId) {
1529                                             QilNode local9 = local2[0];
1530                                             if ( ( (local9).XmlType ).IsSingleton ) {
1531                                                 // PATTERN: [NormalizeIdEq] (Eq (StrConcat * (Loop $iter:(For $bind:* ^ (AtMostOne? (TypeOf $bind))) (XsltGenerateId $iter))) (XsltGenerateId $arg:*) ^ (Single? (TypeOf $arg))) => (Not (IsEmpty (Filter $iterNew:(For $bind) (Is $arg $iterNew))))
1532                                                 if (AllowReplace(XmlILOptimization.NormalizeIdEq, local0)) {
1533                                                     QilNode local10 = VisitFor(f.For(local6));
1534                                                     return Replace(XmlILOptimization.NormalizeIdEq, local0, VisitNot(f.Not(VisitIsEmpty(f.IsEmpty(VisitFilter(f.Filter(local10, VisitIs(f.Is(local9, local10)))))))));
1535                                                 }
1536                                             }
1537                                         }
1538                                     }
1539                                 }
1540                             }
1541                         }
1542                     }
1543                 }
1544             }
1545             if (this[XmlILOptimization.NormalizeMuenchian]) {
1546                 if (local1.NodeType == QilNodeType.Length) {
1547                     QilNode local3 = local1[0];
1548                     if (local3.NodeType == QilNodeType.Union) {
1549                         QilNode local4 = local3[0];
1550                         QilNode local5 = local3[1];
1551                         if (( ( (local4).XmlType ).IsSingleton ) && ( !( (local5).XmlType ).MaybeMany )) {
1552                             if (local2.NodeType == QilNodeType.LiteralInt32) {
1553                                 int local6 = (int)((QilLiteral)local2).Value;
1554                                 if (local6 == 1) {
1555                                     // PATTERN: [NormalizeMuenchian] (Eq (Length (Union $arg1:* $arg2:*) ^ (Single? (TypeOf $arg1)) ^ (AtMostOne? (TypeOf $arg2))) (LiteralInt32 1)) => (IsEmpty (Filter $iterNew:(For $arg2) (Not (Is $arg1 $iterNew))))
1556                                     if (AllowReplace(XmlILOptimization.NormalizeMuenchian, local0)) {
1557                                         QilNode local7 = VisitFor(f.For(local5));
1558                                         return Replace(XmlILOptimization.NormalizeMuenchian, local0, VisitIsEmpty(f.IsEmpty(VisitFilter(f.Filter(local7, VisitNot(f.Not(VisitIs(f.Is(local4, local7)))))))));
1559                                     }
1560                                 }
1561                             }
1562                         }
1563                     }
1564                 }
1565             }
1566             if (this[XmlILOptimization.NormalizeMuenchian]) {
1567                 if (local1.NodeType == QilNodeType.Length) {
1568                     QilNode local3 = local1[0];
1569                     if (local3.NodeType == QilNodeType.Union) {
1570                         QilNode local4 = local3[0];
1571                         QilNode local5 = local3[1];
1572                         if (( !( (local4).XmlType ).MaybeMany ) && ( ( (local5).XmlType ).IsSingleton )) {
1573                             if (local2.NodeType == QilNodeType.LiteralInt32) {
1574                                 int local6 = (int)((QilLiteral)local2).Value;
1575                                 if (local6 == 1) {
1576                                     // PATTERN: [NormalizeMuenchian] (Eq (Length (Union $arg1:* $arg2:*) ^ (AtMostOne? (TypeOf $arg1)) ^ (Single? (TypeOf $arg2))) (LiteralInt32 1)) => (IsEmpty (Filter $iterNew:(For $arg1) (Not (Is $iterNew $arg2))))
1577                                     if (AllowReplace(XmlILOptimization.NormalizeMuenchian, local0)) {
1578                                         QilNode local7 = VisitFor(f.For(local4));
1579                                         return Replace(XmlILOptimization.NormalizeMuenchian, local0, VisitIsEmpty(f.IsEmpty(VisitFilter(f.Filter(local7, VisitNot(f.Not(VisitIs(f.Is(local7, local5)))))))));
1580                                     }
1581                                 }
1582                             }
1583                         }
1584                     }
1585                 }
1586             }
1587             if (this[XmlILOptimization.AnnotateMaxLengthEq]) {
1588                 if (local1.NodeType == QilNodeType.Length) {
1589                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1590                         int local4 = (int)((QilLiteral)local2).Value;
1591                         // PATTERN: [AnnotateMaxLengthEq] (Eq $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { }
1592                         if (AllowReplace(XmlILOptimization.AnnotateMaxLengthEq, local0)) {
1593                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local4);  }
1594                     }
1595                 }
1596             }
1597             return NoReplace(local0);
1598         }
1599
1600         protected override QilNode VisitGt(QilBinary local0) {
1601             QilNode local1 = local0[0];
1602             QilNode local2 = local0[1];
1603             if (this[XmlILOptimization.FoldNone]) {
1604                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1605                     // PATTERN: [FoldNone] (Gt $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1606                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1607                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1608                     }
1609                 }
1610             }
1611             if (this[XmlILOptimization.FoldNone]) {
1612                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1613                     // PATTERN: [FoldNone] (Gt * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1614                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1615                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1616                     }
1617                 }
1618             }
1619             if (this[XmlILOptimization.EliminateGt]) {
1620                 if ( IsLiteral((local1)) ) {
1621                     if ( IsLiteral((local2)) ) {
1622                         // PATTERN: [EliminateGt] (Gt $x:* ^ (Literal? $x) $y:* ^ (Literal? $y)) => (Gt! $x $y)
1623                         if (AllowReplace(XmlILOptimization.EliminateGt, local0)) {
1624                             return Replace(XmlILOptimization.EliminateGt, local0,  FoldComparison(QilNodeType.Gt, local1, local2) );
1625                         }
1626                     }
1627                 }
1628             }
1629             if (this[XmlILOptimization.NormalizeGtLiteral]) {
1630                 if ( IsLiteral((local1)) ) {
1631                     if (!( IsLiteral((local2)) )) {
1632                         // PATTERN: [NormalizeGtLiteral] (Gt $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Lt $right $left)
1633                         if (AllowReplace(XmlILOptimization.NormalizeGtLiteral, local0)) {
1634                             return Replace(XmlILOptimization.NormalizeGtLiteral, local0, VisitLt(f.Lt(local2, local1)));
1635                         }
1636                     }
1637                 }
1638             }
1639             if (this[XmlILOptimization.NormalizeXsltConvertGt]) {
1640                 if (local1.NodeType == QilNodeType.XsltConvert) {
1641                     QilNode local3 = local1[0];
1642                     QilNode local4 = local1[1];
1643                     if (local4.NodeType == QilNodeType.LiteralType) {
1644                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
1645                         if (( IsPrimitiveNumeric( (local3).XmlType ) ) && ( IsPrimitiveNumeric(local5) )) {
1646                             if (( IsLiteral((local2)) ) && ( CanFoldXsltConvertNonLossy(local2,  (local3).XmlType ) )) {
1647                                 // PATTERN: [NormalizeXsltConvertGt] (Gt (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Gt $expr (FoldXsltConvert $lit (TypeOf $expr)))
1648                                 if (AllowReplace(XmlILOptimization.NormalizeXsltConvertGt, local0)) {
1649                                     return Replace(XmlILOptimization.NormalizeXsltConvertGt, local0, VisitGt(f.Gt(local3,  FoldXsltConvert(local2,  (local3).XmlType ) )));
1650                                 }
1651                             }
1652                         }
1653                     }
1654                 }
1655             }
1656             if (this[XmlILOptimization.NormalizeLengthGt]) {
1657                 if (local1.NodeType == QilNodeType.Length) {
1658                     QilNode local3 = local1[0];
1659                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1660                         int local4 = (int)((QilLiteral)local2).Value;
1661                         if (local4 == 0) {
1662                             // PATTERN: [NormalizeLengthGt] (Gt (Length $expr:*) (LiteralInt32 0)) => (Not (IsEmpty $expr))
1663                             if (AllowReplace(XmlILOptimization.NormalizeLengthGt, local0)) {
1664                                 return Replace(XmlILOptimization.NormalizeLengthGt, local0, VisitNot(f.Not(VisitIsEmpty(f.IsEmpty(local3)))));
1665                             }
1666                         }
1667                     }
1668                 }
1669             }
1670             if (this[XmlILOptimization.AnnotateMaxLengthGt]) {
1671                 if (local1.NodeType == QilNodeType.Length) {
1672                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1673                         int local4 = (int)((QilLiteral)local2).Value;
1674                         // PATTERN: [AnnotateMaxLengthGt] (Gt $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { }
1675                         if (AllowReplace(XmlILOptimization.AnnotateMaxLengthGt, local0)) {
1676                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local4);  }
1677                     }
1678                 }
1679             }
1680             return NoReplace(local0);
1681         }
1682
1683         protected override QilNode VisitGe(QilBinary local0) {
1684             QilNode local1 = local0[0];
1685             QilNode local2 = local0[1];
1686             if (this[XmlILOptimization.FoldNone]) {
1687                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1688                     // PATTERN: [FoldNone] (Ge $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1689                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1690                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1691                     }
1692                 }
1693             }
1694             if (this[XmlILOptimization.FoldNone]) {
1695                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1696                     // PATTERN: [FoldNone] (Ge * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1697                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1698                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1699                     }
1700                 }
1701             }
1702             if (this[XmlILOptimization.EliminateGe]) {
1703                 if ( IsLiteral((local1)) ) {
1704                     if ( IsLiteral((local2)) ) {
1705                         // PATTERN: [EliminateGe] (Ge $x:* ^ (Literal? $x) $y:* ^ (Literal? $y)) => (Ge! $x $y)
1706                         if (AllowReplace(XmlILOptimization.EliminateGe, local0)) {
1707                             return Replace(XmlILOptimization.EliminateGe, local0,  FoldComparison(QilNodeType.Ge, local1, local2) );
1708                         }
1709                     }
1710                 }
1711             }
1712             if (this[XmlILOptimization.NormalizeGeLiteral]) {
1713                 if ( IsLiteral((local1)) ) {
1714                     if (!( IsLiteral((local2)) )) {
1715                         // PATTERN: [NormalizeGeLiteral] (Ge $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Le $right $left)
1716                         if (AllowReplace(XmlILOptimization.NormalizeGeLiteral, local0)) {
1717                             return Replace(XmlILOptimization.NormalizeGeLiteral, local0, VisitLe(f.Le(local2, local1)));
1718                         }
1719                     }
1720                 }
1721             }
1722             if (this[XmlILOptimization.NormalizeXsltConvertGe]) {
1723                 if (local1.NodeType == QilNodeType.XsltConvert) {
1724                     QilNode local3 = local1[0];
1725                     QilNode local4 = local1[1];
1726                     if (local4.NodeType == QilNodeType.LiteralType) {
1727                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
1728                         if (( IsPrimitiveNumeric( (local3).XmlType ) ) && ( IsPrimitiveNumeric(local5) )) {
1729                             if (( IsLiteral((local2)) ) && ( CanFoldXsltConvertNonLossy(local2,  (local3).XmlType ) )) {
1730                                 // PATTERN: [NormalizeXsltConvertGe] (Ge (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Ge $expr (FoldXsltConvert $lit (TypeOf $expr)))
1731                                 if (AllowReplace(XmlILOptimization.NormalizeXsltConvertGe, local0)) {
1732                                     return Replace(XmlILOptimization.NormalizeXsltConvertGe, local0, VisitGe(f.Ge(local3,  FoldXsltConvert(local2,  (local3).XmlType ) )));
1733                                 }
1734                             }
1735                         }
1736                     }
1737                 }
1738             }
1739             if (this[XmlILOptimization.AnnotateMaxLengthGe]) {
1740                 if (local1.NodeType == QilNodeType.Length) {
1741                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1742                         int local4 = (int)((QilLiteral)local2).Value;
1743                         // PATTERN: [AnnotateMaxLengthGe] (Ge $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { }
1744                         if (AllowReplace(XmlILOptimization.AnnotateMaxLengthGe, local0)) {
1745                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local4);  }
1746                     }
1747                 }
1748             }
1749             return NoReplace(local0);
1750         }
1751
1752         protected override QilNode VisitLt(QilBinary local0) {
1753             QilNode local1 = local0[0];
1754             QilNode local2 = local0[1];
1755             if (this[XmlILOptimization.FoldNone]) {
1756                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1757                     // PATTERN: [FoldNone] (Lt $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1758                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1759                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1760                     }
1761                 }
1762             }
1763             if (this[XmlILOptimization.FoldNone]) {
1764                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1765                     // PATTERN: [FoldNone] (Lt * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1766                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1767                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1768                     }
1769                 }
1770             }
1771             if (this[XmlILOptimization.EliminateLt]) {
1772                 if ( IsLiteral((local1)) ) {
1773                     if ( IsLiteral((local2)) ) {
1774                         // PATTERN: [EliminateLt] (Lt $x:* ^ (Literal? $x) $y:* ^ (Literal? $y)) => (Lt! $x $y)
1775                         if (AllowReplace(XmlILOptimization.EliminateLt, local0)) {
1776                             return Replace(XmlILOptimization.EliminateLt, local0,  FoldComparison(QilNodeType.Lt, local1, local2) );
1777                         }
1778                     }
1779                 }
1780             }
1781             if (this[XmlILOptimization.NormalizeLtLiteral]) {
1782                 if ( IsLiteral((local1)) ) {
1783                     if (!( IsLiteral((local2)) )) {
1784                         // PATTERN: [NormalizeLtLiteral] (Lt $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Gt $right $left)
1785                         if (AllowReplace(XmlILOptimization.NormalizeLtLiteral, local0)) {
1786                             return Replace(XmlILOptimization.NormalizeLtLiteral, local0, VisitGt(f.Gt(local2, local1)));
1787                         }
1788                     }
1789                 }
1790             }
1791             if (this[XmlILOptimization.NormalizeXsltConvertLt]) {
1792                 if (local1.NodeType == QilNodeType.XsltConvert) {
1793                     QilNode local3 = local1[0];
1794                     QilNode local4 = local1[1];
1795                     if (local4.NodeType == QilNodeType.LiteralType) {
1796                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
1797                         if (( IsPrimitiveNumeric( (local3).XmlType ) ) && ( IsPrimitiveNumeric(local5) )) {
1798                             if (( IsLiteral((local2)) ) && ( CanFoldXsltConvertNonLossy(local2,  (local3).XmlType ) )) {
1799                                 // PATTERN: [NormalizeXsltConvertLt] (Lt (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Lt $expr (FoldXsltConvert $lit (TypeOf $expr)))
1800                                 if (AllowReplace(XmlILOptimization.NormalizeXsltConvertLt, local0)) {
1801                                     return Replace(XmlILOptimization.NormalizeXsltConvertLt, local0, VisitLt(f.Lt(local3,  FoldXsltConvert(local2,  (local3).XmlType ) )));
1802                                 }
1803                             }
1804                         }
1805                     }
1806                 }
1807             }
1808             if (this[XmlILOptimization.AnnotateMaxLengthLt]) {
1809                 if (local1.NodeType == QilNodeType.Length) {
1810                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1811                         int local4 = (int)((QilLiteral)local2).Value;
1812                         // PATTERN: [AnnotateMaxLengthLt] (Lt $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { }
1813                         if (AllowReplace(XmlILOptimization.AnnotateMaxLengthLt, local0)) {
1814                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local4);  }
1815                     }
1816                 }
1817             }
1818             return NoReplace(local0);
1819         }
1820
1821         protected override QilNode VisitLe(QilBinary local0) {
1822             QilNode local1 = local0[0];
1823             QilNode local2 = local0[1];
1824             if (this[XmlILOptimization.FoldNone]) {
1825                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1826                     // PATTERN: [FoldNone] (Le $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1827                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1828                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1829                     }
1830                 }
1831             }
1832             if (this[XmlILOptimization.FoldNone]) {
1833                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1834                     // PATTERN: [FoldNone] (Le * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1835                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1836                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1837                     }
1838                 }
1839             }
1840             if (this[XmlILOptimization.EliminateLe]) {
1841                 if ( IsLiteral((local1)) ) {
1842                     if ( IsLiteral((local2)) ) {
1843                         // PATTERN: [EliminateLe] (Le $x:* ^ (Literal? $x) $y:* ^ (Literal? $y)) => (Le! $x $y)
1844                         if (AllowReplace(XmlILOptimization.EliminateLe, local0)) {
1845                             return Replace(XmlILOptimization.EliminateLe, local0,  FoldComparison(QilNodeType.Le, local1, local2) );
1846                         }
1847                     }
1848                 }
1849             }
1850             if (this[XmlILOptimization.NormalizeLeLiteral]) {
1851                 if ( IsLiteral((local1)) ) {
1852                     if (!( IsLiteral((local2)) )) {
1853                         // PATTERN: [NormalizeLeLiteral] (Le $left:* ^ (Literal? $left) $right:* ^ ~((Literal? $right))) => (Ge $right $left)
1854                         if (AllowReplace(XmlILOptimization.NormalizeLeLiteral, local0)) {
1855                             return Replace(XmlILOptimization.NormalizeLeLiteral, local0, VisitGe(f.Ge(local2, local1)));
1856                         }
1857                     }
1858                 }
1859             }
1860             if (this[XmlILOptimization.NormalizeXsltConvertLe]) {
1861                 if (local1.NodeType == QilNodeType.XsltConvert) {
1862                     QilNode local3 = local1[0];
1863                     QilNode local4 = local1[1];
1864                     if (local4.NodeType == QilNodeType.LiteralType) {
1865                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
1866                         if (( IsPrimitiveNumeric( (local3).XmlType ) ) && ( IsPrimitiveNumeric(local5) )) {
1867                             if (( IsLiteral((local2)) ) && ( CanFoldXsltConvertNonLossy(local2,  (local3).XmlType ) )) {
1868                                 // PATTERN: [NormalizeXsltConvertLe] (Le (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Le $expr (FoldXsltConvert $lit (TypeOf $expr)))
1869                                 if (AllowReplace(XmlILOptimization.NormalizeXsltConvertLe, local0)) {
1870                                     return Replace(XmlILOptimization.NormalizeXsltConvertLe, local0, VisitLe(f.Le(local3,  FoldXsltConvert(local2,  (local3).XmlType ) )));
1871                                 }
1872                             }
1873                         }
1874                     }
1875                 }
1876             }
1877             if (this[XmlILOptimization.AnnotateMaxLengthLe]) {
1878                 if (local1.NodeType == QilNodeType.Length) {
1879                     if (local2.NodeType == QilNodeType.LiteralInt32) {
1880                         int local4 = (int)((QilLiteral)local2).Value;
1881                         // PATTERN: [AnnotateMaxLengthLe] (Le $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { }
1882                         if (AllowReplace(XmlILOptimization.AnnotateMaxLengthLe, local0)) {
1883                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local4);  }
1884                     }
1885                 }
1886             }
1887             return NoReplace(local0);
1888         }
1889
1890         #endregion // value comparison operators
1891
1892         #region node comparison operators
1893         protected override QilNode VisitIs(QilBinary local0) {
1894             QilNode local1 = local0[0];
1895             QilNode local2 = local0[1];
1896             if (this[XmlILOptimization.FoldNone]) {
1897                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1898                     // PATTERN: [FoldNone] (Is $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1899                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1900                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1901                     }
1902                 }
1903             }
1904             if (this[XmlILOptimization.FoldNone]) {
1905                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1906                     // PATTERN: [FoldNone] (Is * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1907                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1908                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1909                     }
1910                 }
1911             }
1912             if (this[XmlILOptimization.EliminateIs]) {
1913                 if (local2 == local1) {
1914                     // PATTERN: [EliminateIs] (Is $x:* $x) => (True)
1915                     if (AllowReplace(XmlILOptimization.EliminateIs, local0)) {
1916                         return Replace(XmlILOptimization.EliminateIs, local0, VisitTrue(f.True()));
1917                     }
1918                 }
1919             }
1920             return NoReplace(local0);
1921         }
1922
1923         protected override QilNode VisitAfter(QilBinary local0) {
1924             QilNode local1 = local0[0];
1925             QilNode local2 = local0[1];
1926             if (this[XmlILOptimization.FoldNone]) {
1927                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1928                     // PATTERN: [FoldNone] (After $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1929                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1930                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1931                     }
1932                 }
1933             }
1934             if (this[XmlILOptimization.FoldNone]) {
1935                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1936                     // PATTERN: [FoldNone] (After * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1937                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1938                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1939                     }
1940                 }
1941             }
1942             if (this[XmlILOptimization.EliminateAfter]) {
1943                 if (local2 == local1) {
1944                     // PATTERN: [EliminateAfter] (After $x:* $x) => (False)
1945                     if (AllowReplace(XmlILOptimization.EliminateAfter, local0)) {
1946                         return Replace(XmlILOptimization.EliminateAfter, local0, VisitFalse(f.False()));
1947                     }
1948                 }
1949             }
1950             return NoReplace(local0);
1951         }
1952
1953         protected override QilNode VisitBefore(QilBinary local0) {
1954             QilNode local1 = local0[0];
1955             QilNode local2 = local0[1];
1956             if (this[XmlILOptimization.FoldNone]) {
1957                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1958                     // PATTERN: [FoldNone] (Before $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
1959                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1960                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
1961                     }
1962                 }
1963             }
1964             if (this[XmlILOptimization.FoldNone]) {
1965                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1966                     // PATTERN: [FoldNone] (Before * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
1967                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1968                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
1969                     }
1970                 }
1971             }
1972             if (this[XmlILOptimization.EliminateBefore]) {
1973                 if (local2 == local1) {
1974                     // PATTERN: [EliminateBefore] (Before $x:* $x) => (False)
1975                     if (AllowReplace(XmlILOptimization.EliminateBefore, local0)) {
1976                         return Replace(XmlILOptimization.EliminateBefore, local0, VisitFalse(f.False()));
1977                     }
1978                 }
1979             }
1980             return NoReplace(local0);
1981         }
1982
1983         #endregion // node comparison operators
1984
1985         #region loops
1986         protected override QilNode VisitLoop(QilLoop local0) {
1987             QilNode local1 = local0[0];
1988             QilNode local2 = local0[1];
1989             if (this[XmlILOptimization.FoldNone]) {
1990                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
1991                     // PATTERN: [FoldNone] (Loop $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i))
1992                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
1993                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop( (QilNode) (local1)[0] )));
1994                     }
1995                 }
1996             }
1997             if (this[XmlILOptimization.EliminateIterator]) {
1998                 if (local1.NodeType == QilNodeType.For) {
1999                     QilNode local3 = local1[0];
2000                     if (local3.NodeType == QilNodeType.For) {
2001                         if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.IsPositional) ) {
2002                             // PATTERN: [EliminateIterator] $outer:(Loop $iter:(For $iterRef:(For *)) ^ (NonPositionalIterator? $iter) $ret:*) => (Subs $ret $iter $iterRef)
2003                             if (AllowReplace(XmlILOptimization.EliminateIterator, local0)) {
2004                                 return Replace(XmlILOptimization.EliminateIterator, local0,  Subs(local2, local1, local3) );
2005                             }
2006                         }
2007                     }
2008                 }
2009             }
2010             if (this[XmlILOptimization.EliminateLoop]) {
2011                 if (local1.NodeType == QilNodeType.For) {
2012                     QilNode local3 = local1[0];
2013                     if (local3.NodeType == QilNodeType.Sequence) {
2014                         if ( (local3).Count == (0) ) {
2015                             // PATTERN: [EliminateLoop] (Loop (For $x:(Sequence) ^ (Count? $x 0)) *) => (Sequence)
2016                             if (AllowReplace(XmlILOptimization.EliminateLoop, local0)) {
2017                                 return Replace(XmlILOptimization.EliminateLoop, local0, VisitSequence(f.Sequence()));
2018                             }
2019                         }
2020                     }
2021                 }
2022             }
2023             if (this[XmlILOptimization.EliminateLoop]) {
2024                 if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
2025                     if (local2.NodeType == QilNodeType.Sequence) {
2026                         if ( (local2).Count == (0) ) {
2027                             // PATTERN: [EliminateLoop] (Loop $i:* ^ (NoSideEffects? $i) $x:(Sequence) ^ (Count? $x 0)) => (Sequence)
2028                             if (AllowReplace(XmlILOptimization.EliminateLoop, local0)) {
2029                                 return Replace(XmlILOptimization.EliminateLoop, local0, VisitSequence(f.Sequence()));
2030                             }
2031                         }
2032                     }
2033                 }
2034             }
2035             if (this[XmlILOptimization.EliminateLoop]) {
2036                 if (local2 == local1) {
2037                     // PATTERN: [EliminateLoop] (Loop $iter:* $iter) => (First $iter)
2038                     if (AllowReplace(XmlILOptimization.EliminateLoop, local0)) {
2039                         return Replace(XmlILOptimization.EliminateLoop, local0,  (QilNode) (local1)[0] );
2040                     }
2041                 }
2042             }
2043             if (this[XmlILOptimization.NormalizeLoopText]) {
2044                 if (local1.NodeType == QilNodeType.For) {
2045                     QilNode local3 = local1[0];
2046                     if ( ( (local3).XmlType ).IsSingleton ) {
2047                         if (local2.NodeType == QilNodeType.TextCtor) {
2048                             QilNode local4 = local2[0];
2049                             // PATTERN: [NormalizeLoopText] (Loop $iter:(For $bind:* ^ (Single? (TypeOf $bind))) $ctor:(TextCtor $text:*)) => (TextCtor (Loop $iter $text))
2050                             if (AllowReplace(XmlILOptimization.NormalizeLoopText, local0)) {
2051                                 return Replace(XmlILOptimization.NormalizeLoopText, local0, VisitTextCtor(f.TextCtor(VisitLoop(f.Loop(local1, local4)))));
2052                             }
2053                         }
2054                     }
2055                 }
2056             }
2057             if (this[XmlILOptimization.EliminateIteratorUsedAtMostOnce]) {
2058                 if ((( (local1).NodeType == QilNodeType.Let ) || ( ( ( (QilNode) (local1)[0] ).XmlType ).IsSingleton )) && ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
2059                     if ( nodeCounter.Count(local2, local1) <= 1 ) {
2060                         // PATTERN: [EliminateIteratorUsedAtMostOnce] (Loop $iter:* ^ (NodeType? $iter {Let}) | (Single? (TypeOf (First $iter))) ^ (NoSideEffects? $iter) $ret:* ^ (RefCountZeroOrOne? $ret $iter)) => (Subs $ret $iter (First $iter))
2061                         if (AllowReplace(XmlILOptimization.EliminateIteratorUsedAtMostOnce, local0)) {
2062                             return Replace(XmlILOptimization.EliminateIteratorUsedAtMostOnce, local0,  Subs(local2, local1,  (QilNode) (local1)[0] ) );
2063                         }
2064                     }
2065                 }
2066             }
2067             if (this[XmlILOptimization.NormalizeLoopConditional]) {
2068                 if (local2.NodeType == QilNodeType.Conditional) {
2069                     QilNode local3 = local2[0];
2070                     QilNode local4 = local2[1];
2071                     QilNode local5 = local2[2];
2072                     if (local4.NodeType == QilNodeType.Sequence) {
2073                         if ( (local4).Count == (0) ) {
2074                             if (local5 == local1) {
2075                                 // PATTERN: [NormalizeLoopConditional] (Loop $iter:* (Conditional $cond:* $left:(Sequence) ^ (Count? $left 0) $iter)) => (Filter $iter (Not $cond))
2076                                 if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
2077                                     return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitFilter(f.Filter(local1, VisitNot(f.Not(local3)))));
2078                                 }
2079                             }
2080                         }
2081                     }
2082                 }
2083             }
2084             if (this[XmlILOptimization.NormalizeLoopConditional]) {
2085                 if (local2.NodeType == QilNodeType.Conditional) {
2086                     QilNode local3 = local2[0];
2087                     QilNode local4 = local2[1];
2088                     QilNode local5 = local2[2];
2089                     if (local4 == local1) {
2090                         if (local5.NodeType == QilNodeType.Sequence) {
2091                             if ( (local5).Count == (0) ) {
2092                                 // PATTERN: [NormalizeLoopConditional] (Loop $iter:* (Conditional $cond:* $iter $right:(Sequence) ^ (Count? $right 0))) => (Filter $iter $cond)
2093                                 if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
2094                                     return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitFilter(f.Filter(local1, local3)));
2095                                 }
2096                             }
2097                         }
2098                     }
2099                 }
2100             }
2101             if (this[XmlILOptimization.NormalizeLoopConditional]) {
2102                 if (local1.NodeType == QilNodeType.For) {
2103                     if (local2.NodeType == QilNodeType.Conditional) {
2104                         QilNode local4 = local2[0];
2105                         QilNode local5 = local2[1];
2106                         QilNode local6 = local2[2];
2107                         if (local5.NodeType == QilNodeType.Sequence) {
2108                             if ( (local5).Count == (0) ) {
2109                                 if ( NonPositional(local6, local1) ) {
2110                                     // PATTERN: [NormalizeLoopConditional] (Loop $iter:(For *) (Conditional $cond:* $left:(Sequence) ^ (Count? $left 0) $right:* ^ (NonPositional? $right $iter))) => (Loop $iter2:(For (Filter $iter (Not $cond))) (Subs $right $iter $iter2))
2111                                     if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
2112                                         QilNode local7 = VisitFor(f.For(VisitFilter(f.Filter(local1, VisitNot(f.Not(local4))))));
2113                                         return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitLoop(f.Loop(local7,  Subs(local6, local1, local7) )));
2114                                     }
2115                                 }
2116                             }
2117                         }
2118                     }
2119                 }
2120             }
2121             if (this[XmlILOptimization.NormalizeLoopConditional]) {
2122                 if (local1.NodeType == QilNodeType.For) {
2123                     if (local2.NodeType == QilNodeType.Conditional) {
2124                         QilNode local4 = local2[0];
2125                         QilNode local5 = local2[1];
2126                         QilNode local6 = local2[2];
2127                         if ( NonPositional(local5, local1) ) {
2128                             if (local6.NodeType == QilNodeType.Sequence) {
2129                                 if ( (local6).Count == (0) ) {
2130                                     // PATTERN: [NormalizeLoopConditional] (Loop $iter:(For *) (Conditional $cond:* $left:* ^ (NonPositional? $left $iter) $right:(Sequence) ^ (Count? $right 0))) => (Loop $iter2:(For (Filter $iter $cond)) (Subs $left $iter $iter2))
2131                                     if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
2132                                         QilNode local7 = VisitFor(f.For(VisitFilter(f.Filter(local1, local4))));
2133                                         return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitLoop(f.Loop(local7,  Subs(local5, local1, local7) )));
2134                                     }
2135                                 }
2136                             }
2137                         }
2138                     }
2139                 }
2140             }
2141             if (this[XmlILOptimization.NormalizeLoopLoop]) {
2142                 if (local2.NodeType == QilNodeType.Loop) {
2143                     QilNode local3 = local2[0];
2144                     QilNode local5 = local2[1];
2145                     if (local3.NodeType == QilNodeType.For) {
2146                         QilNode local4 = local3[0];
2147                         if ((!(DependsOn(local5,local1))) && ( NonPositional(local5, local3) )) {
2148                             // PATTERN: [NormalizeLoopLoop] (Loop $iter:* $ret:(Loop $iter2:(For $bind2:*) $ret2:* ^ ~($ret2 >> $iter) ^ (NonPositional? $ret2 $iter2))) => (Loop $iter3:(For (Loop $iter $bind2)) (Subs $ret2 $iter2 $iter3))
2149                             if (AllowReplace(XmlILOptimization.NormalizeLoopLoop, local0)) {
2150                                 QilNode local6 = VisitFor(f.For(VisitLoop(f.Loop(local1, local4))));
2151                                 return Replace(XmlILOptimization.NormalizeLoopLoop, local0, VisitLoop(f.Loop(local6,  Subs(local5, local3, local6) )));
2152                             }
2153                         }
2154                     }
2155                 }
2156             }
2157             if (this[XmlILOptimization.AnnotateSingletonLoop]) {
2158                 if (local1.NodeType == QilNodeType.For) {
2159                     QilNode local3 = local1[0];
2160                     if ( !( (local3).XmlType ).MaybeMany ) {
2161                         // PATTERN: [AnnotateSingletonLoop] $outer:(Loop (For $bind:* ^ (AtMostOne? (TypeOf $bind))) $ret:*) => (InheritPattern $outer $ret {IsDocOrderDistinct}) ^ (InheritPattern $outer $ret {SameDepth}) ^ { }
2162                         if (AllowReplace(XmlILOptimization.AnnotateSingletonLoop, local0)) {
2163                              OptimizerPatterns.Inherit((QilNode) (local2), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local2), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
2164                     }
2165                 }
2166             }
2167             if (this[XmlILOptimization.AnnotateRootLoop]) {
2168                 if ( IsStepPattern(local2, QilNodeType.Root) ) {
2169                     // PATTERN: [AnnotateRootLoop] $outer:(Loop * $ret:* ^ (StepPattern? $ret {Root})) => (AddPattern $outer {SameDepth}) ^ { }
2170                     if (AllowReplace(XmlILOptimization.AnnotateRootLoop, local0)) {
2171                          OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
2172                 }
2173             }
2174             if (this[XmlILOptimization.AnnotateContentLoop]) {
2175                 if (local1.NodeType == QilNodeType.For) {
2176                     QilNode local3 = local1[0];
2177                     if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.SameDepth) ) {
2178                         if ((( IsStepPattern(local2, QilNodeType.Content) ) || ( IsStepPattern(local2, QilNodeType.Union) )) && ( (local1) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
2179                             // PATTERN: [AnnotateContentLoop] $outer:(Loop $iter:(For $bind:* ^ (Pattern? $bind {SameDepth})) $ret:* ^ (StepPattern? $ret {Content}) | (StepPattern? $ret {Union}) ^ (Equal? $iter (Argument $ret {StepInput}))) => (AddPattern $outer {SameDepth}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ { }
2180                             if (AllowReplace(XmlILOptimization.AnnotateContentLoop, local0)) {
2181                                  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  }
2182                         }
2183                     }
2184                 }
2185             }
2186             if (this[XmlILOptimization.AnnotateAttrNmspLoop]) {
2187                 if (local1.NodeType == QilNodeType.For) {
2188                     QilNode local3 = local1[0];
2189                     if (((( IsStepPattern(local2, QilNodeType.Attribute) ) || ( IsStepPattern(local2, QilNodeType.XPathNamespace) )) || ( OptimizerPatterns.Read((QilNode) (local2)).MatchesPattern(OptimizerPatternName.FilterAttributeKind) )) && ( (local1) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
2190                         // PATTERN: [AnnotateAttrNmspLoop] $outer:(Loop $iter:(For $bind:*) $ret:* ^ (StepPattern? $ret {Attribute}) | (StepPattern? $ret {XPathNamespace}) | (Pattern? $ret {FilterAttributeKind}) ^ (Equal? $iter (Argument $ret {StepInput}))) => (InheritPattern $outer $bind {SameDepth}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ { }
2191                         if (AllowReplace(XmlILOptimization.AnnotateAttrNmspLoop, local0)) {
2192                              OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.SameDepth);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  }
2193                     }
2194                 }
2195             }
2196             if (this[XmlILOptimization.AnnotateDescendantLoop]) {
2197                 if (local1.NodeType == QilNodeType.For) {
2198                     QilNode local3 = local1[0];
2199                     if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.SameDepth) ) {
2200                         if ((( IsStepPattern(local2, QilNodeType.Descendant) ) || ( IsStepPattern(local2, QilNodeType.DescendantOrSelf) )) && ( (local1) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
2201                             // PATTERN: [AnnotateDescendantLoop] $outer:(Loop $iter:(For $bind:* ^ (Pattern? $bind {SameDepth})) $ret:* ^ (StepPattern? $ret {Descendant}) | (StepPattern? $ret {DescendantOrSelf}) ^ (Equal? $iter (Argument $ret {StepInput}))) => (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ { }
2202                             if (AllowReplace(XmlILOptimization.AnnotateDescendantLoop, local0)) {
2203                                  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  }
2204                         }
2205                     }
2206                 }
2207             }
2208             return NoReplace(local0);
2209         }
2210
2211         protected override QilNode VisitFilter(QilLoop local0) {
2212             QilNode local1 = local0[0];
2213             QilNode local2 = local0[1];
2214             if (this[XmlILOptimization.FoldNone]) {
2215                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2216                     // PATTERN: [FoldNone] (Filter $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i))
2217                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2218                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop( (QilNode) (local1)[0] )));
2219                     }
2220                 }
2221             }
2222             if (this[XmlILOptimization.FoldNone]) {
2223                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2224                     // PATTERN: [FoldNone] (Filter $i:* $w:* ^ (None? (TypeOf $w))) => (Loop $i $w)
2225                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2226                         return Replace(XmlILOptimization.FoldNone, local0, VisitLoop(f.Loop(local1, local2)));
2227                     }
2228                 }
2229             }
2230             if (this[XmlILOptimization.EliminateFilter]) {
2231                 if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
2232                     if (local2.NodeType == QilNodeType.False) {
2233                         // PATTERN: [EliminateFilter] (Filter $i:* ^ (NoSideEffects? $i) (False)) => (Sequence)
2234                         if (AllowReplace(XmlILOptimization.EliminateFilter, local0)) {
2235                             return Replace(XmlILOptimization.EliminateFilter, local0, VisitSequence(f.Sequence()));
2236                         }
2237                     }
2238                 }
2239             }
2240             if (this[XmlILOptimization.EliminateFilter]) {
2241                 if (local2.NodeType == QilNodeType.True) {
2242                     // PATTERN: [EliminateFilter] (Filter $i:* (True)) => (First $i)
2243                     if (AllowReplace(XmlILOptimization.EliminateFilter, local0)) {
2244                         return Replace(XmlILOptimization.EliminateFilter, local0,  (QilNode) (local1)[0] );
2245                     }
2246                 }
2247             }
2248             if (this[XmlILOptimization.NormalizeAttribute]) {
2249                 if (local1.NodeType == QilNodeType.For) {
2250                     QilNode local3 = local1[0];
2251                     if (local3.NodeType == QilNodeType.Content) {
2252                         QilNode local4 = local3[0];
2253                         if (local2.NodeType == QilNodeType.And) {
2254                             QilNode local5 = local2[0];
2255                             QilNode local9 = local2[1];
2256                             if (local5.NodeType == QilNodeType.IsType) {
2257                                 QilNode local6 = local5[0];
2258                                 QilNode local7 = local5[1];
2259                                 if (local6 == local1) {
2260                                     if (local7.NodeType == QilNodeType.LiteralType) {
2261                                         XmlQueryType local8 = (XmlQueryType)((QilLiteral)local7).Value;
2262                                         if ( (local8) == ( XmlQueryTypeFactory.Attribute ) ) {
2263                                             if (local9.NodeType == QilNodeType.Eq) {
2264                                                 QilNode local10 = local9[0];
2265                                                 QilNode local12 = local9[1];
2266                                                 if (local10.NodeType == QilNodeType.NameOf) {
2267                                                     QilNode local11 = local10[0];
2268                                                     if (local11 == local1) {
2269                                                         if (local12.NodeType == QilNodeType.LiteralQName) {
2270                                                             // PATTERN: [NormalizeAttribute] (Filter $iter:(For (Content $input:*)) (And (IsType $iter (LiteralType $typ:* ^ (Equal? $typ (ConstructType {Attribute})))) (Eq (NameOf $iter) $qname:(LiteralQName * * *)))) => (Attribute $input $qname)
2271                                                             if (AllowReplace(XmlILOptimization.NormalizeAttribute, local0)) {
2272                                                                 return Replace(XmlILOptimization.NormalizeAttribute, local0, VisitAttribute(f.Attribute(local4, local12)));
2273                                                             }
2274                                                         }
2275                                                     }
2276                                                 }
2277                                             }
2278                                         }
2279                                     }
2280                                 }
2281                             }
2282                         }
2283                     }
2284                 }
2285             }
2286             if (this[XmlILOptimization.CommuteFilterLoop]) {
2287                 if (local1.NodeType == QilNodeType.For) {
2288                     QilNode local3 = local1[0];
2289                     if (local3.NodeType == QilNodeType.Loop) {
2290                         QilNode local4 = local3[0];
2291                         QilNode local5 = local3[1];
2292                         if ( NonPositional(local2, local1) ) {
2293                             // PATTERN: [CommuteFilterLoop] (Filter $iter:(For (Loop $iter2:* $ret2:*)) $cond:* ^ (NonPositional? $cond $iter)) => (Loop $iter2 (Filter $iter3:(For $ret2) (Subs $cond $iter $iter3)))
2294                             if (AllowReplace(XmlILOptimization.CommuteFilterLoop, local0)) {
2295                                 QilNode local6 = VisitFor(f.For(local5));
2296                                 return Replace(XmlILOptimization.CommuteFilterLoop, local0, VisitLoop(f.Loop(local4, VisitFilter(f.Filter(local6,  Subs(local2, local1, local6) )))));
2297                             }
2298                         }
2299                     }
2300                 }
2301             }
2302             if (this[XmlILOptimization.NormalizeLoopInvariant]) {
2303                 if (( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) && (!( ( (QilNode) (local1)[0] ).NodeType == QilNodeType.OptimizeBarrier ))) {
2304                     if ((!(DependsOn(local2,local1))) && ( !OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
2305                         // PATTERN: [NormalizeLoopInvariant] (Filter $iter:* ^ (NoSideEffects? $iter) ^ ~((NodeType? (First $iter) {OptimizeBarrier})) $cond:* ^ ~($cond >> $iter) ^ (NoSideEffects? $cond)) => (Conditional $cond (First $iter) (Sequence))
2306                         if (AllowReplace(XmlILOptimization.NormalizeLoopInvariant, local0)) {
2307                             return Replace(XmlILOptimization.NormalizeLoopInvariant, local0, VisitConditional(f.Conditional(local2,  (QilNode) (local1)[0] , VisitSequence(f.Sequence()))));
2308                         }
2309                     }
2310                 }
2311             }
2312             if (this[XmlILOptimization.AnnotateMaxPositionEq]) {
2313                 if (local2.NodeType == QilNodeType.Eq) {
2314                     QilNode local3 = local2[0];
2315                     QilNode local5 = local2[1];
2316                     if (local3.NodeType == QilNodeType.PositionOf) {
2317                         QilNode local4 = local3[0];
2318                         if (local4 == local1) {
2319                             if (local5.NodeType == QilNodeType.LiteralInt32) {
2320                                 int local6 = (int)((QilLiteral)local5).Value;
2321                                 // PATTERN: [AnnotateMaxPositionEq] $outer:(Filter $iter:* (Eq (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} $num) ^ { }
2322                                 if (AllowReplace(XmlILOptimization.AnnotateMaxPositionEq, local0)) {
2323                                      OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6);  }
2324                             }
2325                         }
2326                     }
2327                 }
2328             }
2329             if (this[XmlILOptimization.AnnotateMaxPositionLe]) {
2330                 if (local2.NodeType == QilNodeType.Le) {
2331                     QilNode local3 = local2[0];
2332                     QilNode local5 = local2[1];
2333                     if (local3.NodeType == QilNodeType.PositionOf) {
2334                         QilNode local4 = local3[0];
2335                         if (local4 == local1) {
2336                             if (local5.NodeType == QilNodeType.LiteralInt32) {
2337                                 int local6 = (int)((QilLiteral)local5).Value;
2338                                 // PATTERN: [AnnotateMaxPositionLe] $outer:(Filter $iter:* (Le (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} $num) ^ { }
2339                                 if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLe, local0)) {
2340                                      OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6);  }
2341                             }
2342                         }
2343                     }
2344                 }
2345             }
2346             if (this[XmlILOptimization.AnnotateMaxPositionLt]) {
2347                 if (local2.NodeType == QilNodeType.Lt) {
2348                     QilNode local3 = local2[0];
2349                     QilNode local5 = local2[1];
2350                     if (local3.NodeType == QilNodeType.PositionOf) {
2351                         QilNode local4 = local3[0];
2352                         if (local4 == local1) {
2353                             if (local5.NodeType == QilNodeType.LiteralInt32) {
2354                                 int local6 = (int)((QilLiteral)local5).Value;
2355                                 // PATTERN: [AnnotateMaxPositionLt] $outer:(Filter $iter:* (Lt (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} { {$num} - 1 }) ^ { }
2356                                 if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLt, local0)) {
2357                                      OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition,  local6 - 1 );  }
2358                             }
2359                         }
2360                     }
2361                 }
2362             }
2363             if (this[XmlILOptimization.AnnotateFilter]) {
2364                 if (local1.NodeType == QilNodeType.For) {
2365                     QilNode local3 = local1[0];
2366                     // PATTERN: [AnnotateFilter] $outer:(Filter $iter:(For $bind:*) *) => (InheritPattern $outer $bind {Step}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ (InheritPattern $outer $bind {SameDepth}) ^ { }
2367                     if (AllowReplace(XmlILOptimization.AnnotateFilter, local0)) {
2368                          OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.Step);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
2369                 }
2370             }
2371             if (this[XmlILOptimization.AnnotateFilterElements]) {
2372                 if (local1.NodeType == QilNodeType.For) {
2373                     QilNode local3 = local1[0];
2374                     if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.Axis) ) {
2375                         if (local2.NodeType == QilNodeType.And) {
2376                             QilNode local4 = local2[0];
2377                             QilNode local8 = local2[1];
2378                             if (local4.NodeType == QilNodeType.IsType) {
2379                                 QilNode local5 = local4[0];
2380                                 QilNode local6 = local4[1];
2381                                 if (local5 == local1) {
2382                                     if (local6.NodeType == QilNodeType.LiteralType) {
2383                                         XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value;
2384                                         if ( (local7) == ( XmlQueryTypeFactory.Element ) ) {
2385                                             if (local8.NodeType == QilNodeType.Eq) {
2386                                                 QilNode local9 = local8[0];
2387                                                 QilNode local11 = local8[1];
2388                                                 if (local9.NodeType == QilNodeType.NameOf) {
2389                                                     QilNode local10 = local9[0];
2390                                                     if (local10 == local1) {
2391                                                         if (local11.NodeType == QilNodeType.LiteralQName) {
2392                                                             // PATTERN: [AnnotateFilterElements] $outer:(Filter $iter:(For $bind:* ^ (Pattern? $bind {Axis})) (And (IsType $iter (LiteralType $typ:* ^ (Equal? $typ (ConstructType {Element})))) (Eq (NameOf $iter) $qname:(LiteralQName * * *)))) => (AddPattern $outer {FilterElements}) ^ (AddArgument $outer {ElementQName} $qname) ^ { }
2393                                                             if (AllowReplace(XmlILOptimization.AnnotateFilterElements, local0)) {
2394                                                                  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.FilterElements);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.ElementQName, local11);  }
2395                                                         }
2396                                                     }
2397                                                 }
2398                                             }
2399                                         }
2400                                     }
2401                                 }
2402                             }
2403                         }
2404                     }
2405                 }
2406             }
2407             if (this[XmlILOptimization.AnnotateFilterContentKind]) {
2408                 if (local1.NodeType == QilNodeType.For) {
2409                     QilNode local3 = local1[0];
2410                     if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.Axis) ) {
2411                         if (local2.NodeType == QilNodeType.IsType) {
2412                             QilNode local4 = local2[0];
2413                             QilNode local5 = local2[1];
2414                             if (local4 == local1) {
2415                                 if (local5.NodeType == QilNodeType.LiteralType) {
2416                                     XmlQueryType local6 = (XmlQueryType)((QilLiteral)local5).Value;
2417                                     if ( MatchesContentTest(local6) ) {
2418                                         // PATTERN: [AnnotateFilterContentKind] $outer:(Filter $iter:(For $bind:* ^ (Pattern? $bind {Axis})) (IsType $iter (LiteralType $kind:* ^ (ContentTest? $kind)))) => (AddPattern $outer {FilterContentKind}) ^ (AddArgument $outer {KindTestType} $kind) ^ { }
2419                                         if (AllowReplace(XmlILOptimization.AnnotateFilterContentKind, local0)) {
2420                                              OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.FilterContentKind);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.KindTestType, local6);  }
2421                                     }
2422                                 }
2423                             }
2424                         }
2425                     }
2426                 }
2427             }
2428             if (this[XmlILOptimization.AnnotateFilterAttributeKind]) {
2429                 if (local1.NodeType == QilNodeType.For) {
2430                     QilNode local3 = local1[0];
2431                     if (local3.NodeType == QilNodeType.Content) {
2432                         if (local2.NodeType == QilNodeType.IsType) {
2433                             QilNode local5 = local2[0];
2434                             QilNode local6 = local2[1];
2435                             if (local5 == local1) {
2436                                 if (local6.NodeType == QilNodeType.LiteralType) {
2437                                     XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value;
2438                                     if ( (local7) == ( XmlQueryTypeFactory.Attribute ) ) {
2439                                         // PATTERN: [AnnotateFilterAttributeKind] $outer:(Filter $iter:(For (Content *)) (IsType $iter (LiteralType $kind:*) ^ (Equal? $kind (ConstructType {Attribute})))) => (AddPattern $outer {FilterAttributeKind}) ^ { }
2440                                         if (AllowReplace(XmlILOptimization.AnnotateFilterAttributeKind, local0)) {
2441                                              OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.FilterAttributeKind);  }
2442                                     }
2443                                 }
2444                             }
2445                         }
2446                     }
2447                 }
2448             }
2449             return NoReplace(local0);
2450         }
2451
2452         #endregion // loops
2453
2454         #region sorting
2455         protected override QilNode VisitSort(QilLoop local0) {
2456             QilNode local1 = local0[0];
2457             QilNode local2 = local0[1];
2458             if (this[XmlILOptimization.FoldNone]) {
2459                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2460                     // PATTERN: [FoldNone] (Sort $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i))
2461                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2462                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop( (QilNode) (local1)[0] )));
2463                     }
2464                 }
2465             }
2466             if (this[XmlILOptimization.EliminateSort]) {
2467                 if (local1.NodeType == QilNodeType.For) {
2468                     QilNode local3 = local1[0];
2469                     if ( ( (local3).XmlType ).IsSingleton ) {
2470                         // PATTERN: [EliminateSort] (Sort (For $bind:* ^ (Single? (TypeOf $bind))) *) => (Nop $bind)
2471                         if (AllowReplace(XmlILOptimization.EliminateSort, local0)) {
2472                             return Replace(XmlILOptimization.EliminateSort, local0, VisitNop(f.Nop(local3)));
2473                         }
2474                     }
2475                 }
2476             }
2477             return NoReplace(local0);
2478         }
2479
2480         protected override QilNode VisitSortKey(QilSortKey local0) {
2481             QilNode local1 = local0[0];
2482             QilNode local2 = local0[1];
2483             if (this[XmlILOptimization.NormalizeSortXsltConvert]) {
2484                 if (local1.NodeType == QilNodeType.XsltConvert) {
2485                     QilNode local3 = local1[0];
2486                     QilNode local4 = local1[1];
2487                     if (local4.NodeType == QilNodeType.LiteralType) {
2488                         XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value;
2489                         if (( ( (local3).XmlType ) == ( XmlQueryTypeFactory.IntX ) ) && ( (local5) == ( XmlQueryTypeFactory.DoubleX ) )) {
2490                             // PATTERN: [NormalizeSortXsltConvert] (SortKey (XsltConvert $expr:* (LiteralType $typ:*)) ^ (Equal? (TypeOf $expr) (ConstructType {IntX})) ^ (Equal? $typ (ConstructType {DoubleX})) $coll:*) => (SortKey $expr $coll)
2491                             if (AllowReplace(XmlILOptimization.NormalizeSortXsltConvert, local0)) {
2492                                 return Replace(XmlILOptimization.NormalizeSortXsltConvert, local0, VisitSortKey(f.SortKey(local3, local2)));
2493                             }
2494                         }
2495                     }
2496                 }
2497             }
2498             return NoReplace(local0);
2499         }
2500
2501         protected override QilNode VisitDocOrderDistinct(QilUnary local0) {
2502             QilNode local1 = local0[0];
2503             if (this[XmlILOptimization.FoldNone]) {
2504                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2505                     // PATTERN: [FoldNone] (DocOrderDistinct $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2506                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2507                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2508                     }
2509                 }
2510             }
2511             if (this[XmlILOptimization.EliminateDod]) {
2512                 if ( IsDocOrderDistinct(local1) ) {
2513                     // PATTERN: [EliminateDod] (DocOrderDistinct $arg:* ^ (DocOrderDistinct? $arg)) => $arg
2514                     if (AllowReplace(XmlILOptimization.EliminateDod, local0)) {
2515                         return Replace(XmlILOptimization.EliminateDod, local0, local1);
2516                     }
2517                 }
2518             }
2519             if (this[XmlILOptimization.FoldNamedDescendants]) {
2520                 if (local1.NodeType == QilNodeType.Loop) {
2521                     QilNode local2 = local1[0];
2522                     QilNode local7 = local1[1];
2523                     if (local2.NodeType == QilNodeType.For) {
2524                         QilNode local3 = local2[0];
2525                         if (local3.NodeType == QilNodeType.Loop) {
2526                             QilNode local4 = local3[0];
2527                             QilNode local5 = local3[1];
2528                             if (local5.NodeType == QilNodeType.DescendantOrSelf) {
2529                                 QilNode local6 = local5[0];
2530                                 if (local7.NodeType == QilNodeType.Filter) {
2531                                     QilNode local8 = local7[0];
2532                                     QilNode local9 = local7[1];
2533                                     if ((( OptimizerPatterns.Read((QilNode) (local7)).MatchesPattern(OptimizerPatternName.FilterElements) ) || ( OptimizerPatterns.Read((QilNode) (local7)).MatchesPattern(OptimizerPatternName.FilterContentKind) )) && ( IsStepPattern(local7, QilNodeType.Content) )) {
2534                                         // PATTERN: [FoldNamedDescendants] (DocOrderDistinct $path:(Loop $iter1:(For (Loop $iter2:* $ret2:(DescendantOrSelf $input:*))) $ret1:(Filter $iter3:* $cond3:*) ^ (Pattern? $ret1 {FilterElements}) | (Pattern? $ret1 {FilterContentKind}) ^ (StepPattern? $ret1 {Content}))) => (DocOrderDistinct (Loop $iter2 (Filter $iterNew:(For (Descendant $input)) (Subs $cond3 $iter3 $iterNew))))
2535                                         if (AllowReplace(XmlILOptimization.FoldNamedDescendants, local0)) {
2536                                             QilNode local10 = VisitFor(f.For(VisitDescendant(f.Descendant(local6))));
2537                                             return Replace(XmlILOptimization.FoldNamedDescendants, local0, VisitDocOrderDistinct(f.DocOrderDistinct(VisitLoop(f.Loop(local4, VisitFilter(f.Filter(local10,  Subs(local9, local8, local10) )))))));
2538                                         }
2539                                     }
2540                                 }
2541                             }
2542                         }
2543                     }
2544                 }
2545             }
2546             if (this[XmlILOptimization.FoldNamedDescendants]) {
2547                 if (local1.NodeType == QilNodeType.Loop) {
2548                     QilNode local2 = local1[0];
2549                     QilNode local5 = local1[1];
2550                     if (local2.NodeType == QilNodeType.For) {
2551                         QilNode local3 = local2[0];
2552                         if (local3.NodeType == QilNodeType.DescendantOrSelf) {
2553                             QilNode local4 = local3[0];
2554                             if (local5.NodeType == QilNodeType.Filter) {
2555                                 QilNode local6 = local5[0];
2556                                 QilNode local7 = local5[1];
2557                                 if ((( OptimizerPatterns.Read((QilNode) (local5)).MatchesPattern(OptimizerPatternName.FilterElements) ) || ( OptimizerPatterns.Read((QilNode) (local5)).MatchesPattern(OptimizerPatternName.FilterContentKind) )) && ( IsStepPattern(local5, QilNodeType.Content) )) {
2558                                     // PATTERN: [FoldNamedDescendants] (DocOrderDistinct $path:(Loop $iter1:(For (DescendantOrSelf $input:*)) $ret1:(Filter $iter2:* $cond2:*) ^ (Pattern? $ret1 {FilterElements}) | (Pattern? $ret1 {FilterContentKind}) ^ (StepPattern? $ret1 {Content}))) => (Filter $iterNew:(For (Descendant $input)) (Subs $cond2 $iter2 $iterNew))
2559                                     if (AllowReplace(XmlILOptimization.FoldNamedDescendants, local0)) {
2560                                         QilNode local8 = VisitFor(f.For(VisitDescendant(f.Descendant(local4))));
2561                                         return Replace(XmlILOptimization.FoldNamedDescendants, local0, VisitFilter(f.Filter(local8,  Subs(local7, local6, local8) )));
2562                                     }
2563                                 }
2564                             }
2565                         }
2566                     }
2567                 }
2568             }
2569             if (this[XmlILOptimization.CommuteDodFilter]) {
2570                 if (local1.NodeType == QilNodeType.Filter) {
2571                     QilNode local2 = local1[0];
2572                     QilNode local4 = local1[1];
2573                     if (local2.NodeType == QilNodeType.For) {
2574                         QilNode local3 = local2[0];
2575                         if ( !OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.IsPositional) ) {
2576                             if (((!( OptimizerPatterns.Read((QilNode) (local1)).MatchesPattern(OptimizerPatternName.FilterElements) )) && (!( OptimizerPatterns.Read((QilNode) (local1)).MatchesPattern(OptimizerPatternName.FilterContentKind) ))) && (!( OptimizerPatterns.Read((QilNode) (local1)).MatchesPattern(OptimizerPatternName.FilterAttributeKind) ))) {
2577                                 // PATTERN: [CommuteDodFilter] (DocOrderDistinct $filter:(Filter $iter:(For $bind:*) ^ (NonPositionalIterator? $iter) $cond:*) ^ ~((Pattern? $filter {FilterElements})) ^ ~((Pattern? $filter {FilterContentKind})) ^ ~((Pattern? $filter {FilterAttributeKind}))) => (Filter $iterNew:(For (DocOrderDistinct $bind)) (Subs $cond $iter $iterNew))
2578                                 if (AllowReplace(XmlILOptimization.CommuteDodFilter, local0)) {
2579                                     QilNode local5 = VisitFor(f.For(VisitDocOrderDistinct(f.DocOrderDistinct(local3))));
2580                                     return Replace(XmlILOptimization.CommuteDodFilter, local0, VisitFilter(f.Filter(local5,  Subs(local4, local2, local5) )));
2581                                 }
2582                             }
2583                         }
2584                     }
2585                 }
2586             }
2587             if (this[XmlILOptimization.CommuteDodFilter]) {
2588                 if (local1.NodeType == QilNodeType.Loop) {
2589                     QilNode local2 = local1[0];
2590                     QilNode local3 = local1[1];
2591                     if (local3.NodeType == QilNodeType.Filter) {
2592                         QilNode local4 = local3[0];
2593                         QilNode local6 = local3[1];
2594                         if (local4.NodeType == QilNodeType.For) {
2595                             QilNode local5 = local4[0];
2596                             if ( !OptimizerPatterns.Read(local4).MatchesPattern(OptimizerPatternName.IsPositional) ) {
2597                                 if (!(DependsOn(local6,local2))) {
2598                                     if (((!( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.FilterElements) )) && (!( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.FilterContentKind) ))) && (!( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.FilterAttributeKind) ))) {
2599                                         // PATTERN: [CommuteDodFilter] (DocOrderDistinct (Loop $iter1:* $ret1:(Filter $iter2:(For $bind2:*) ^ (NonPositionalIterator? $iter2) $cond2:* ^ ~($cond2 >> $iter1)) ^ ~((Pattern? $ret1 {FilterElements})) ^ ~((Pattern? $ret1 {FilterContentKind})) ^ ~((Pattern? $ret1 {FilterAttributeKind})))) => (Filter $iterNew:(For (DocOrderDistinct (Loop $iter1 $bind2))) (Subs $cond2 $iter2 $iterNew))
2600                                         if (AllowReplace(XmlILOptimization.CommuteDodFilter, local0)) {
2601                                             QilNode local7 = VisitFor(f.For(VisitDocOrderDistinct(f.DocOrderDistinct(VisitLoop(f.Loop(local2, local5))))));
2602                                             return Replace(XmlILOptimization.CommuteDodFilter, local0, VisitFilter(f.Filter(local7,  Subs(local6, local4, local7) )));
2603                                         }
2604                                     }
2605                                 }
2606                             }
2607                         }
2608                     }
2609                 }
2610             }
2611             if (this[XmlILOptimization.IntroduceDod]) {
2612                 if (local1.NodeType == QilNodeType.Loop) {
2613                     QilNode local2 = local1[0];
2614                     QilNode local4 = local1[1];
2615                     if (local2.NodeType == QilNodeType.For) {
2616                         QilNode local3 = local2[0];
2617                         if (!( IsDocOrderDistinct(local3) )) {
2618                             if (( !OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.IsPositional) ) && (  (local3).XmlType .IsSubtypeOf( XmlQueryTypeFactory.NodeNotRtfS ) )) {
2619                                 if (((!( OptimizerPatterns.Read((QilNode) (local1)).MatchesPattern(OptimizerPatternName.FilterElements) )) && (!( OptimizerPatterns.Read((QilNode) (local1)).MatchesPattern(OptimizerPatternName.FilterContentKind) ))) && (!( OptimizerPatterns.Read((QilNode) (local1)).MatchesPattern(OptimizerPatternName.FilterAttributeKind) ))) {
2620                                     // PATTERN: [IntroduceDod] (DocOrderDistinct $loop:(Loop $iter:(For $bind:* ^ ~((DocOrderDistinct? $bind))) ^ (NonPositionalIterator? $iter) ^ (SubtypeOf? (TypeOf $bind) (ConstructType {NodeNotRtfS})) $ret:*) ^ ~((Pattern? $loop {FilterElements})) ^ ~((Pattern? $loop {FilterContentKind})) ^ ~((Pattern? $loop {FilterAttributeKind}))) => (DocOrderDistinct (Loop $iterNew:(For (DocOrderDistinct $bind)) (Subs $ret $iter $iterNew)))
2621                                     if (AllowReplace(XmlILOptimization.IntroduceDod, local0)) {
2622                                         QilNode local5 = VisitFor(f.For(VisitDocOrderDistinct(f.DocOrderDistinct(local3))));
2623                                         return Replace(XmlILOptimization.IntroduceDod, local0, VisitDocOrderDistinct(f.DocOrderDistinct(VisitLoop(f.Loop(local5,  Subs(local4, local2, local5) )))));
2624                                     }
2625                                 }
2626                             }
2627                         }
2628                     }
2629                 }
2630             }
2631             if (this[XmlILOptimization.IntroducePrecedingDod]) {
2632                 if (local1.NodeType == QilNodeType.Loop) {
2633                     QilNode local2 = local1[0];
2634                     QilNode local3 = local1[1];
2635                     if ((!( IsDocOrderDistinct(local3) )) && ( IsStepPattern(local3, QilNodeType.PrecedingSibling) )) {
2636                         // PATTERN: [IntroducePrecedingDod] (DocOrderDistinct (Loop $iter:* $ret:* ^ ~((DocOrderDistinct? $ret)) ^ (StepPattern? $ret {PrecedingSibling}))) => (DocOrderDistinct (Loop $iter (DocOrderDistinct $ret)))
2637                         if (AllowReplace(XmlILOptimization.IntroducePrecedingDod, local0)) {
2638                             return Replace(XmlILOptimization.IntroducePrecedingDod, local0, VisitDocOrderDistinct(f.DocOrderDistinct(VisitLoop(f.Loop(local2, VisitDocOrderDistinct(f.DocOrderDistinct(local3)))))));
2639                         }
2640                     }
2641                 }
2642             }
2643             if (this[XmlILOptimization.EliminateReturnDod]) {
2644                 if (local1.NodeType == QilNodeType.Loop) {
2645                     QilNode local2 = local1[0];
2646                     QilNode local3 = local1[1];
2647                     if (local3.NodeType == QilNodeType.DocOrderDistinct) {
2648                         QilNode local4 = local3[0];
2649                         if (!( IsStepPattern(local4, QilNodeType.PrecedingSibling) )) {
2650                             // PATTERN: [EliminateReturnDod] (DocOrderDistinct (Loop $iter:* $ret:(DocOrderDistinct $opnd:*) ^ ~((StepPattern? $opnd {PrecedingSibling})))) => (DocOrderDistinct (Loop $iter $opnd))
2651                             if (AllowReplace(XmlILOptimization.EliminateReturnDod, local0)) {
2652                                 return Replace(XmlILOptimization.EliminateReturnDod, local0, VisitDocOrderDistinct(f.DocOrderDistinct(VisitLoop(f.Loop(local2, local4)))));
2653                             }
2654                         }
2655                     }
2656                 }
2657             }
2658             if (this[XmlILOptimization.AnnotateDod]) {
2659                 // PATTERN: [AnnotateDod] $outer:(DocOrderDistinct $inner:*) => (AddPattern $outer {IsDocOrderDistinct}) ^ (InheritPattern $outer $inner {SameDepth}) ^ { }
2660                 if (AllowReplace(XmlILOptimization.AnnotateDod, local0)) {
2661                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local1), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
2662             }
2663             if (this[XmlILOptimization.AnnotateDodReverse]) {
2664                 if ( AllowDodReverse(local1) ) {
2665                     // PATTERN: [AnnotateDodReverse] $outer:(DocOrderDistinct $inner:* ^ (DodReverse? $inner)) => (AddPattern $outer {DodReverse}) ^ (AddArgument $outer {DodStep} $inner) ^ { }
2666                     if (AllowReplace(XmlILOptimization.AnnotateDodReverse, local0)) {
2667                          OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.DodReverse);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.DodStep, local1);  }
2668                 }
2669             }
2670             if (this[XmlILOptimization.AnnotateJoinAndDod]) {
2671                 if (local1.NodeType == QilNodeType.Loop) {
2672                     QilNode local2 = local1[0];
2673                     QilNode local4 = local1[1];
2674                     if (local2.NodeType == QilNodeType.For) {
2675                         QilNode local3 = local2[0];
2676                         if ( IsDocOrderDistinct(local3) ) {
2677                             if (( AllowJoinAndDod(local4) ) && ( (local2) == ( OptimizerPatterns.Read((QilNode) (local4)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
2678                                 // PATTERN: [AnnotateJoinAndDod] $outer:(DocOrderDistinct $join:(Loop $iter:(For $bind:*) ^ (DocOrderDistinct? $bind) $ret:* ^ (JoinAndDod? $ret) ^ (Equal? $iter (Argument $ret {StepInput})))) => (AddPattern $outer {JoinAndDod}) ^ (AddArgument $outer {DodStep} $ret) ^ { }
2679                                 if (AllowReplace(XmlILOptimization.AnnotateJoinAndDod, local0)) {
2680                                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.JoinAndDod);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.DodStep, local4);  }
2681                             }
2682                         }
2683                     }
2684                 }
2685             }
2686             if (this[XmlILOptimization.AnnotateDodMerge]) {
2687                 if (local1.NodeType == QilNodeType.Loop) {
2688                     QilNode local3 = local1[1];
2689                     if (local3.NodeType == QilNodeType.Invoke) {
2690                         if ( IsDocOrderDistinct(local3) ) {
2691                             // PATTERN: [AnnotateDodMerge] $outer:(DocOrderDistinct (Loop * $ret:(Invoke * *) ^ (DocOrderDistinct? $ret))) => (AddPattern $outer {DodMerge}) ^ { }
2692                             if (AllowReplace(XmlILOptimization.AnnotateDodMerge, local0)) {
2693                                  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.DodMerge);  }
2694                         }
2695                     }
2696                 }
2697             }
2698             return NoReplace(local0);
2699         }
2700
2701         #endregion // sorting
2702
2703         #region function definition and invocation
2704         protected override QilNode VisitFunction(QilFunction local0) {
2705             QilNode local1 = local0[0];
2706             QilNode local2 = local0[1];
2707             QilNode local3 = local0[2];
2708             XmlQueryType local4 = (XmlQueryType)((QilFunction)local0).XmlType;
2709             if ((  (local0).XmlType .IsSubtypeOf( XmlQueryTypeFactory.NodeS ) ) && (this[XmlILOptimization.AnnotateIndex1])) {
2710                 if ((( local1.Count == 2 ) && (  ( (QilNode) (local1)[0] ).XmlType .IsSubtypeOf( XmlQueryTypeFactory.Node ) )) && ( ( ( (QilNode) (local1)[1] ).XmlType ) == ( XmlQueryTypeFactory.StringX ) )) {
2711                     if (local2.NodeType == QilNodeType.Filter) {
2712                         QilNode local5 = local2[0];
2713                         QilNode local7 = local2[1];
2714                         if (local5.NodeType == QilNodeType.For) {
2715                             QilNode local6 = local5[0];
2716                             if (local7.NodeType == QilNodeType.Not) {
2717                                 QilNode local8 = local7[0];
2718                                 if (local8.NodeType == QilNodeType.IsEmpty) {
2719                                     QilNode local9 = local8[0];
2720                                     if (local9.NodeType == QilNodeType.Filter) {
2721                                         QilNode local10 = local9[0];
2722                                         QilNode local12 = local9[1];
2723                                         if (local10.NodeType == QilNodeType.For) {
2724                                             QilNode local11 = local10[0];
2725                                             if (local12.NodeType == QilNodeType.Eq) {
2726                                                 QilNode local13 = local12[0];
2727                                                 QilNode local14 = local12[1];
2728                                                 if (local13 == local10) {
2729                                                     if (local14.NodeType == QilNodeType.Parameter) {
2730                                                         if ( (local14) == ( (QilNode) (local1)[1] ) ) {
2731                                                             if ( IsDocOrderDistinct(local2) ) {
2732                                                                 // PATTERN: [AnnotateIndex1] $outer:(Function $args:* ^ { {$args}.Count == 2 } ^ (SubtypeOf? (TypeOf (Nth $args 0)) (ConstructType {Node})) ^ (Equal? (TypeOf (Nth $args 1)) (ConstructType {StringX})) $def:(Filter $iterNodes:(For $bindingNodes:*) (Not (IsEmpty (Filter $iterKeys:(For $bindingKeys:*) (Eq $iterKeys $keyParam:(Parameter * * *) ^ (Equal? $keyParam (Nth $args 1))))))) ^ (DocOrderDistinct? $def) * *) ^ (SubtypeOf? (TypeOf $outer) (ConstructType {NodeS})) => { ... }
2733                                                                 if (AllowReplace(XmlILOptimization.AnnotateIndex1, local0)) {
2734                                                                     // The following conditions must be true for this pattern to match:
2735                                                                     //   1. The function must have exactly two arguments
2736                                                                     //   2. The type of the first argument must be a subtype of Node
2737                                                                     //   3. The type of the second argument must be String
2738                                                                     //   4. The return type must be a subtype of Node*
2739                                                                     //   5. The function must return nodes in document order
2740                                                                     //   6. Every reference to $args[0] (context document) must be wrapped in an (Root *) function
2741                                                                     //   7. $keyParam cannot be used with the $bindingNodes and $bindingKeys expressions
2742
2743                                                                     EqualityIndexVisitor visitor = new EqualityIndexVisitor();
2744                                                                     if (visitor.Scan(local6, local1[0], local14) && visitor.Scan(local11, local1[0], local14)) {
2745                                                                         // All conditions were true, so annotate Filter with the EqualityIndex pattern
2746                                                                         OptimizerPatterns patt = OptimizerPatterns.Write(local2);
2747                                                                         patt.AddPattern(OptimizerPatternName.EqualityIndex);
2748                                                                         patt.AddArgument(OptimizerPatternArgument.IndexedNodes, local5);
2749                                                                         patt.AddArgument(OptimizerPatternArgument.KeyExpression, local11);
2750                                                                     }
2751                                                                 }
2752                                                             }
2753                                                         }
2754                                                     }
2755                                                 }
2756                                             }
2757                                         }
2758                                     }
2759                                 }
2760                             }
2761                         }
2762                     }
2763                 }
2764             }
2765             if ((  (local0).XmlType .IsSubtypeOf( XmlQueryTypeFactory.NodeS ) ) && (this[XmlILOptimization.AnnotateIndex2])) {
2766                 if ((( local1.Count == 2 ) && ( ( ( (QilNode) (local1)[0] ).XmlType ) == ( XmlQueryTypeFactory.Node ) )) && ( ( ( (QilNode) (local1)[1] ).XmlType ) == ( XmlQueryTypeFactory.StringX ) )) {
2767                     if (local2.NodeType == QilNodeType.Filter) {
2768                         QilNode local5 = local2[0];
2769                         QilNode local7 = local2[1];
2770                         if (local5.NodeType == QilNodeType.For) {
2771                             QilNode local6 = local5[0];
2772                             if (local7.NodeType == QilNodeType.Eq) {
2773                                 QilNode local8 = local7[0];
2774                                 QilNode local9 = local7[1];
2775                                 if (local9.NodeType == QilNodeType.Parameter) {
2776                                     if ( (local9) == ( (QilNode) (local1)[1] ) ) {
2777                                         if ( IsDocOrderDistinct(local2) ) {
2778                                             // PATTERN: [AnnotateIndex2] $outer:(Function $args:* ^ { {$args}.Count == 2 } ^ (Equal? (TypeOf (Nth $args 0)) (ConstructType {Node})) ^ (Equal? (TypeOf (Nth $args 1)) (ConstructType {StringX})) $def:(Filter $iterNodes:(For $bindingNodes:*) (Eq $keyExpr:* $keyParam:(Parameter * * *) ^ (Equal? $keyParam (Nth $args 1)))) ^ (DocOrderDistinct? $def) * *) ^ (SubtypeOf? (TypeOf $outer) (ConstructType {NodeS})) => { ... }
2779                                             if (AllowReplace(XmlILOptimization.AnnotateIndex2, local0)) {
2780                                                 // Same as EqualityIndex1, except that each nodes has at most one key value
2781
2782                                                 EqualityIndexVisitor visitor = new EqualityIndexVisitor();
2783                                                 if (visitor.Scan(local6, local1[0], local9) && visitor.Scan(local8, local1[0], local9)) {
2784                                                     // All conditions were true, so annotate Filter with the EqualityIndex pattern
2785                                                     OptimizerPatterns patt = OptimizerPatterns.Write(local2);
2786                                                     patt.AddPattern(OptimizerPatternName.EqualityIndex);
2787                                                     patt.AddArgument(OptimizerPatternArgument.IndexedNodes, local5);
2788                                                     patt.AddArgument(OptimizerPatternArgument.KeyExpression, local8);
2789                                                 }
2790                                             }
2791                                         }
2792                                     }
2793                                 }
2794                             }
2795                         }
2796                     }
2797                 }
2798             }
2799             return NoReplace(local0);
2800         }
2801
2802         protected override QilNode VisitInvoke(QilInvoke local0) {
2803             QilNode local1 = local0[0];
2804             QilNode local2 = local0[1];
2805             if (this[XmlILOptimization.NormalizeInvokeEmpty]) {
2806                 if (local1.NodeType == QilNodeType.Function) {
2807                     QilNode local4 = local1[1];
2808                     if (local4.NodeType == QilNodeType.Sequence) {
2809                         if ( (local4).Count == (0) ) {
2810                             // PATTERN: [NormalizeInvokeEmpty] (Invoke (Function * $seq:(Sequence) ^ (Count? $seq 0) * *) *) => (Sequence)
2811                             if (AllowReplace(XmlILOptimization.NormalizeInvokeEmpty, local0)) {
2812                                 return Replace(XmlILOptimization.NormalizeInvokeEmpty, local0, VisitSequence(f.Sequence()));
2813                             }
2814                         }
2815                     }
2816                 }
2817             }
2818             if (this[XmlILOptimization.AnnotateTrackCallers]) {
2819                 // PATTERN: [AnnotateTrackCallers] $caller:(Invoke $func:* *) => (AddCaller $func $caller) ^ { }
2820                 if (AllowReplace(XmlILOptimization.AnnotateTrackCallers, local0)) {
2821                      XmlILConstructInfo.Write(local1).CallersInfo.Add(XmlILConstructInfo.Write(local0));  }
2822             }
2823             if (this[XmlILOptimization.AnnotateInvoke]) {
2824                 if (local1.NodeType == QilNodeType.Function) {
2825                     QilNode local4 = local1[1];
2826                     // PATTERN: [AnnotateInvoke] $outer:(Invoke (Function * $defn:* * *) *) => (InheritPattern $outer $defn {IsDocOrderDistinct}) ^ (InheritPattern $outer $defn {SameDepth}) ^ { }
2827                     if (AllowReplace(XmlILOptimization.AnnotateInvoke, local0)) {
2828                          OptimizerPatterns.Inherit((QilNode) (local4), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local4), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
2829                 }
2830             }
2831             return NoReplace(local0);
2832         }
2833
2834         #endregion // function definition and invocation
2835
2836         #region XML navigation
2837         protected override QilNode VisitContent(QilUnary local0) {
2838             QilNode local1 = local0[0];
2839             if (this[XmlILOptimization.FoldNone]) {
2840                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2841                     // PATTERN: [FoldNone] (Content $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2842                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2843                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2844                     }
2845                 }
2846             }
2847             if (this[XmlILOptimization.AnnotateContent]) {
2848                 // PATTERN: [AnnotateContent] $outer:(Content $input:*) => (AddStepPattern $outer $input) ^ (AddPattern $outer {Axis}) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ (AddPattern $outer {SameDepth}) ^ { }
2849                 if (AllowReplace(XmlILOptimization.AnnotateContent, local0)) {
2850                      AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
2851             }
2852             return NoReplace(local0);
2853         }
2854
2855         protected override QilNode VisitAttribute(QilBinary local0) {
2856             QilNode local1 = local0[0];
2857             QilNode local2 = local0[1];
2858             if (this[XmlILOptimization.FoldNone]) {
2859                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2860                     // PATTERN: [FoldNone] (Attribute $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
2861                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2862                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2863                     }
2864                 }
2865             }
2866             if (this[XmlILOptimization.FoldNone]) {
2867                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2868                     // PATTERN: [FoldNone] (Attribute * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2869                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2870                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
2871                     }
2872                 }
2873             }
2874             if (this[XmlILOptimization.AnnotateAttribute]) {
2875                 // PATTERN: [AnnotateAttribute] $outer:(Attribute $input:* *) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ (AddPattern $outer {SameDepth}) ^ { }
2876                 if (AllowReplace(XmlILOptimization.AnnotateAttribute, local0)) {
2877                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
2878             }
2879             return NoReplace(local0);
2880         }
2881
2882         protected override QilNode VisitParent(QilUnary local0) {
2883             QilNode local1 = local0[0];
2884             if (this[XmlILOptimization.FoldNone]) {
2885                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2886                     // PATTERN: [FoldNone] (Parent $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2887                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2888                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2889                     }
2890                 }
2891             }
2892             if (this[XmlILOptimization.AnnotateParent]) {
2893                 // PATTERN: [AnnotateParent] $outer:(Parent $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ (AddPattern $outer {SameDepth}) ^ { }
2894                 if (AllowReplace(XmlILOptimization.AnnotateParent, local0)) {
2895                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
2896             }
2897             return NoReplace(local0);
2898         }
2899
2900         protected override QilNode VisitRoot(QilUnary local0) {
2901             QilNode local1 = local0[0];
2902             if (this[XmlILOptimization.FoldNone]) {
2903                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2904                     // PATTERN: [FoldNone] (Root $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2905                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2906                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2907                     }
2908                 }
2909             }
2910             if (this[XmlILOptimization.AnnotateRoot]) {
2911                 // PATTERN: [AnnotateRoot] $outer:(Root $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ (AddPattern $outer {SameDepth}) ^ { }
2912                 if (AllowReplace(XmlILOptimization.AnnotateRoot, local0)) {
2913                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
2914             }
2915             return NoReplace(local0);
2916         }
2917
2918         protected override QilNode VisitDescendant(QilUnary local0) {
2919             QilNode local1 = local0[0];
2920             if (this[XmlILOptimization.FoldNone]) {
2921                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2922                     // PATTERN: [FoldNone] (Descendant $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2923                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2924                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2925                     }
2926                 }
2927             }
2928             if (this[XmlILOptimization.AnnotateDescendant]) {
2929                 // PATTERN: [AnnotateDescendant] $outer:(Descendant $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ { }
2930                 if (AllowReplace(XmlILOptimization.AnnotateDescendant, local0)) {
2931                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
2932             }
2933             return NoReplace(local0);
2934         }
2935
2936         protected override QilNode VisitDescendantOrSelf(QilUnary local0) {
2937             QilNode local1 = local0[0];
2938             if (this[XmlILOptimization.FoldNone]) {
2939                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2940                     // PATTERN: [FoldNone] (DescendantOrSelf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2941                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2942                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2943                     }
2944                 }
2945             }
2946             if (this[XmlILOptimization.AnnotateDescendantSelf]) {
2947                 // PATTERN: [AnnotateDescendantSelf] $outer:(DescendantOrSelf $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ { }
2948                 if (AllowReplace(XmlILOptimization.AnnotateDescendantSelf, local0)) {
2949                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
2950             }
2951             return NoReplace(local0);
2952         }
2953
2954         protected override QilNode VisitAncestor(QilUnary local0) {
2955             QilNode local1 = local0[0];
2956             if (this[XmlILOptimization.FoldNone]) {
2957                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2958                     // PATTERN: [FoldNone] (Ancestor $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2959                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2960                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2961                     }
2962                 }
2963             }
2964             if (this[XmlILOptimization.AnnotateAncestor]) {
2965                 // PATTERN: [AnnotateAncestor] $outer:(Ancestor $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ { }
2966                 if (AllowReplace(XmlILOptimization.AnnotateAncestor, local0)) {
2967                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  }
2968             }
2969             return NoReplace(local0);
2970         }
2971
2972         protected override QilNode VisitAncestorOrSelf(QilUnary local0) {
2973             QilNode local1 = local0[0];
2974             if (this[XmlILOptimization.FoldNone]) {
2975                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2976                     // PATTERN: [FoldNone] (AncestorOrSelf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2977                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2978                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2979                     }
2980                 }
2981             }
2982             if (this[XmlILOptimization.AnnotateAncestorSelf]) {
2983                 // PATTERN: [AnnotateAncestorSelf] $outer:(AncestorOrSelf $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ { }
2984                 if (AllowReplace(XmlILOptimization.AnnotateAncestorSelf, local0)) {
2985                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  }
2986             }
2987             return NoReplace(local0);
2988         }
2989
2990         protected override QilNode VisitPreceding(QilUnary local0) {
2991             QilNode local1 = local0[0];
2992             if (this[XmlILOptimization.FoldNone]) {
2993                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
2994                     // PATTERN: [FoldNone] (Preceding $x:* ^ (None? (TypeOf $x))) => (Nop $x)
2995                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
2996                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
2997                     }
2998                 }
2999             }
3000             if (this[XmlILOptimization.AnnotatePreceding]) {
3001                 // PATTERN: [AnnotatePreceding] $outer:(Preceding $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ { }
3002                 if (AllowReplace(XmlILOptimization.AnnotatePreceding, local0)) {
3003                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  }
3004             }
3005             return NoReplace(local0);
3006         }
3007
3008         protected override QilNode VisitFollowingSibling(QilUnary local0) {
3009             QilNode local1 = local0[0];
3010             if (this[XmlILOptimization.FoldNone]) {
3011                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3012                     // PATTERN: [FoldNone] (FollowingSibling $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3013                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3014                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3015                     }
3016                 }
3017             }
3018             if (this[XmlILOptimization.AnnotateFollowingSibling]) {
3019                 // PATTERN: [AnnotateFollowingSibling] $outer:(FollowingSibling $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ (AddPattern $outer {SameDepth}) ^ { }
3020                 if (AllowReplace(XmlILOptimization.AnnotateFollowingSibling, local0)) {
3021                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
3022             }
3023             return NoReplace(local0);
3024         }
3025
3026         protected override QilNode VisitPrecedingSibling(QilUnary local0) {
3027             QilNode local1 = local0[0];
3028             if (this[XmlILOptimization.FoldNone]) {
3029                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3030                     // PATTERN: [FoldNone] (PrecedingSibling $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3031                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3032                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3033                     }
3034                 }
3035             }
3036             if (this[XmlILOptimization.AnnotatePrecedingSibling]) {
3037                 // PATTERN: [AnnotatePrecedingSibling] $outer:(PrecedingSibling $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {SameDepth}) ^ { }
3038                 if (AllowReplace(XmlILOptimization.AnnotatePrecedingSibling, local0)) {
3039                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
3040             }
3041             return NoReplace(local0);
3042         }
3043
3044         protected override QilNode VisitNodeRange(QilBinary local0) {
3045             QilNode local1 = local0[0];
3046             QilNode local2 = local0[1];
3047             if (this[XmlILOptimization.FoldNone]) {
3048                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3049                     // PATTERN: [FoldNone] (NodeRange $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3050                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3051                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3052                     }
3053                 }
3054             }
3055             if (this[XmlILOptimization.FoldNone]) {
3056                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3057                     // PATTERN: [FoldNone] (NodeRange * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3058                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3059                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3060                     }
3061                 }
3062             }
3063             if (this[XmlILOptimization.AnnotateNodeRange]) {
3064                 // PATTERN: [AnnotateNodeRange] $outer:(NodeRange $start:* *) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $start) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ { }
3065                 if (AllowReplace(XmlILOptimization.AnnotateNodeRange, local0)) {
3066                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
3067             }
3068             return NoReplace(local0);
3069         }
3070
3071         protected override QilNode VisitDeref(QilBinary local0) {
3072             QilNode local1 = local0[0];
3073             QilNode local2 = local0[1];
3074             if (this[XmlILOptimization.FoldNone]) {
3075                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3076                     // PATTERN: [FoldNone] (Deref $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3077                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3078                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3079                     }
3080                 }
3081             }
3082             if (this[XmlILOptimization.FoldNone]) {
3083                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3084                     // PATTERN: [FoldNone] (Deref * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3085                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3086                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3087                     }
3088                 }
3089             }
3090             return NoReplace(local0);
3091         }
3092
3093         #endregion // XML navigation
3094
3095         #region XML construction
3096         protected override QilNode VisitElementCtor(QilBinary local0) {
3097             QilNode local1 = local0[0];
3098             QilNode local2 = local0[1];
3099             if (this[XmlILOptimization.FoldNone]) {
3100                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3101                     // PATTERN: [FoldNone] (ElementCtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3102                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3103                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3104                     }
3105                 }
3106             }
3107             if (this[XmlILOptimization.FoldNone]) {
3108                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3109                     // PATTERN: [FoldNone] (ElementCtor * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3110                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3111                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3112                     }
3113                 }
3114             }
3115             if (this[XmlILOptimization.AnnotateConstruction]) {
3116                 // PATTERN: [AnnotateConstruction] $ctor:(ElementCtor * $content:*) => { ... }
3117                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3118                     // The analysis occasionally makes small changes to the content of constructors, which is
3119                     // why the result of Analyze is assigned to $ctor.Right.
3120                     local0.Right = this.elemAnalyzer.Analyze(local0, local2);
3121                 }
3122             }
3123             return NoReplace(local0);
3124         }
3125
3126         protected override QilNode VisitAttributeCtor(QilBinary local0) {
3127             QilNode local1 = local0[0];
3128             QilNode local2 = local0[1];
3129             if (this[XmlILOptimization.FoldNone]) {
3130                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3131                     // PATTERN: [FoldNone] (AttributeCtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3132                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3133                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3134                     }
3135                 }
3136             }
3137             if (this[XmlILOptimization.FoldNone]) {
3138                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3139                     // PATTERN: [FoldNone] (AttributeCtor * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3140                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3141                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3142                     }
3143                 }
3144             }
3145             if (this[XmlILOptimization.AnnotateConstruction]) {
3146                 // PATTERN: [AnnotateConstruction] $ctor:(AttributeCtor * $content:*) => { ... }
3147                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3148                     local0.Right = this.contentAnalyzer.Analyze(local0, local2);
3149                 }
3150             }
3151             return NoReplace(local0);
3152         }
3153
3154         protected override QilNode VisitCommentCtor(QilUnary local0) {
3155             QilNode local1 = local0[0];
3156             if (this[XmlILOptimization.FoldNone]) {
3157                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3158                     // PATTERN: [FoldNone] (CommentCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3159                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3160                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3161                     }
3162                 }
3163             }
3164             if (this[XmlILOptimization.AnnotateConstruction]) {
3165                 // PATTERN: [AnnotateConstruction] $ctor:(CommentCtor $content:*) => { ... }
3166                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3167                     local0.Child = this.contentAnalyzer.Analyze(local0, local1);
3168                 }
3169             }
3170             return NoReplace(local0);
3171         }
3172
3173         protected override QilNode VisitPICtor(QilBinary local0) {
3174             QilNode local1 = local0[0];
3175             QilNode local2 = local0[1];
3176             if (this[XmlILOptimization.FoldNone]) {
3177                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3178                     // PATTERN: [FoldNone] (PICtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3179                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3180                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3181                     }
3182                 }
3183             }
3184             if (this[XmlILOptimization.FoldNone]) {
3185                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3186                     // PATTERN: [FoldNone] (PICtor * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3187                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3188                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3189                     }
3190                 }
3191             }
3192             if (this[XmlILOptimization.AnnotateConstruction]) {
3193                 // PATTERN: [AnnotateConstruction] $ctor:(PICtor * $content:*) => { ... }
3194                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3195                     local0.Right = this.contentAnalyzer.Analyze(local0, local2);
3196                 }
3197             }
3198             return NoReplace(local0);
3199         }
3200
3201         protected override QilNode VisitTextCtor(QilUnary local0) {
3202             QilNode local1 = local0[0];
3203             if (this[XmlILOptimization.FoldNone]) {
3204                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3205                     // PATTERN: [FoldNone] (TextCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3206                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3207                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3208                     }
3209                 }
3210             }
3211             if (this[XmlILOptimization.AnnotateConstruction]) {
3212                 // PATTERN: [AnnotateConstruction] $ctor:(TextCtor *) => { ... }
3213                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3214                     this.contentAnalyzer.Analyze(local0, null);
3215                 }
3216             }
3217             return NoReplace(local0);
3218         }
3219
3220         protected override QilNode VisitRawTextCtor(QilUnary local0) {
3221             QilNode local1 = local0[0];
3222             if (this[XmlILOptimization.FoldNone]) {
3223                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3224                     // PATTERN: [FoldNone] (RawTextCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3225                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3226                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3227                     }
3228                 }
3229             }
3230             if (this[XmlILOptimization.AnnotateConstruction]) {
3231                 // PATTERN: [AnnotateConstruction] $ctor:(RawTextCtor *) => { ... }
3232                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3233                     this.contentAnalyzer.Analyze(local0, null);
3234                 }
3235             }
3236             return NoReplace(local0);
3237         }
3238
3239         protected override QilNode VisitDocumentCtor(QilUnary local0) {
3240             QilNode local1 = local0[0];
3241             if (this[XmlILOptimization.FoldNone]) {
3242                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3243                     // PATTERN: [FoldNone] (DocumentCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3244                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3245                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3246                     }
3247                 }
3248             }
3249             if (this[XmlILOptimization.AnnotateConstruction]) {
3250                 // PATTERN: [AnnotateConstruction] $ctor:(DocumentCtor $content:*) => { ... }
3251                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3252                     local0.Child = this.contentAnalyzer.Analyze(local0, local1);
3253                 }
3254             }
3255             return NoReplace(local0);
3256         }
3257
3258         protected override QilNode VisitNamespaceDecl(QilBinary local0) {
3259             QilNode local1 = local0[0];
3260             QilNode local2 = local0[1];
3261             if (this[XmlILOptimization.FoldNone]) {
3262                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3263                     // PATTERN: [FoldNone] (NamespaceDecl $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3264                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3265                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3266                     }
3267                 }
3268             }
3269             if (this[XmlILOptimization.FoldNone]) {
3270                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3271                     // PATTERN: [FoldNone] (NamespaceDecl * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3272                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3273                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3274                     }
3275                 }
3276             }
3277             if (( XmlILConstructInfo.Read(local0).IsNamespaceInScope ) && (this[XmlILOptimization.EliminateNamespaceDecl])) {
3278                 // PATTERN: [EliminateNamespaceDecl] $nmsp:(NamespaceDecl * *) ^ (NamespaceInScope? $nmsp) => (Sequence)
3279                 if (AllowReplace(XmlILOptimization.EliminateNamespaceDecl, local0)) {
3280                     return Replace(XmlILOptimization.EliminateNamespaceDecl, local0, VisitSequence(f.Sequence()));
3281                 }
3282             }
3283             if (this[XmlILOptimization.AnnotateConstruction]) {
3284                 // PATTERN: [AnnotateConstruction] $ctor:(NamespaceDecl * *) => { ... }
3285                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3286                     this.contentAnalyzer.Analyze(local0, null);
3287                 }
3288             }
3289             return NoReplace(local0);
3290         }
3291
3292         protected override QilNode VisitRtfCtor(QilBinary local0) {
3293             QilNode local1 = local0[0];
3294             QilNode local2 = local0[1];
3295             if (this[XmlILOptimization.FoldNone]) {
3296                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3297                     // PATTERN: [FoldNone] (RtfCtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3298                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3299                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3300                     }
3301                 }
3302             }
3303             if (this[XmlILOptimization.AnnotateConstruction]) {
3304                 // PATTERN: [AnnotateConstruction] $ctor:(RtfCtor $content:* *) => { ... }
3305                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3306                     local0.Left = this.contentAnalyzer.Analyze(local0, local1);
3307                 }
3308             }
3309             if (this[XmlILOptimization.AnnotateSingleTextRtf]) {
3310                 if (local1.NodeType == QilNodeType.TextCtor) {
3311                     QilNode local3 = local1[0];
3312                     // PATTERN: [AnnotateSingleTextRtf] $outer:(RtfCtor $ctor:(TextCtor $text:*) *) => (AddPattern $outer {SingleTextRtf}) ^ (AddArgument $outer {RtfText} $text) ^ { ... }
3313                     if (AllowReplace(XmlILOptimization.AnnotateSingleTextRtf, local0)) {
3314                          OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SingleTextRtf);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.RtfText, local3); 
3315                         // In this case, Rtf will be pushed onto the stack rather than pushed to the writer
3316                         XmlILConstructInfo.Write(local0).PullFromIteratorFirst = true;
3317                     }
3318                 }
3319             }
3320             return NoReplace(local0);
3321         }
3322
3323         #endregion // XML construction
3324
3325         #region Node properties
3326         protected override QilNode VisitNameOf(QilUnary local0) {
3327             QilNode local1 = local0[0];
3328             if (this[XmlILOptimization.FoldNone]) {
3329                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3330                     // PATTERN: [FoldNone] (NameOf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3331                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3332                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3333                     }
3334                 }
3335             }
3336             return NoReplace(local0);
3337         }
3338
3339         protected override QilNode VisitLocalNameOf(QilUnary local0) {
3340             QilNode local1 = local0[0];
3341             if (this[XmlILOptimization.FoldNone]) {
3342                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3343                     // PATTERN: [FoldNone] (LocalNameOf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3344                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3345                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3346                     }
3347                 }
3348             }
3349             return NoReplace(local0);
3350         }
3351
3352         protected override QilNode VisitNamespaceUriOf(QilUnary local0) {
3353             QilNode local1 = local0[0];
3354             if (this[XmlILOptimization.FoldNone]) {
3355                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3356                     // PATTERN: [FoldNone] (NamespaceUriOf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3357                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3358                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3359                     }
3360                 }
3361             }
3362             return NoReplace(local0);
3363         }
3364
3365         protected override QilNode VisitPrefixOf(QilUnary local0) {
3366             QilNode local1 = local0[0];
3367             if (this[XmlILOptimization.FoldNone]) {
3368                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3369                     // PATTERN: [FoldNone] (PrefixOf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3370                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3371                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3372                     }
3373                 }
3374             }
3375             return NoReplace(local0);
3376         }
3377
3378         #endregion // Node properties
3379
3380         #region Type operators
3381         protected override QilNode VisitTypeAssert(QilTargetType local0) {
3382             QilNode local1 = local0[0];
3383             QilNode local2 = local0[1];
3384             if (this[XmlILOptimization.FoldNone]) {
3385                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3386                     // PATTERN: [FoldNone] (TypeAssert $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3387                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3388                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3389                     }
3390                 }
3391             }
3392             if (this[XmlILOptimization.EliminateTypeAssert]) {
3393                 if (local2.NodeType == QilNodeType.LiteralType) {
3394                     XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3395                     if (  (local1).XmlType .NeverSubtypeOf(local3) ) {
3396                         // PATTERN: [EliminateTypeAssert] (TypeAssert $opnd:* (LiteralType $typ:*) ^ (NeverSubtypeOf? (TypeOf $opnd) $typ)) => (Error (LiteralString ""))
3397                         if (AllowReplace(XmlILOptimization.EliminateTypeAssert, local0)) {
3398                             return Replace(XmlILOptimization.EliminateTypeAssert, local0, VisitError(f.Error(VisitLiteralString(f.LiteralString(string.Empty)))));
3399                         }
3400                     }
3401                 }
3402             }
3403             if (this[XmlILOptimization.EliminateTypeAssert]) {
3404                 if (local2.NodeType == QilNodeType.LiteralType) {
3405                     XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3406                     if (   (local1).XmlType .Prime .NeverSubtypeOf( local3.Prime ) ) {
3407                         // PATTERN: [EliminateTypeAssert] (TypeAssert $opnd:* (LiteralType $typ:*) ^ (NeverSubtypeOf? (Prime (TypeOf $opnd)) (Prime $typ))) => (Conditional (IsEmpty $opnd) (Sequence) (Error (LiteralString "")))
3408                         if (AllowReplace(XmlILOptimization.EliminateTypeAssert, local0)) {
3409                             return Replace(XmlILOptimization.EliminateTypeAssert, local0, VisitConditional(f.Conditional(VisitIsEmpty(f.IsEmpty(local1)), VisitSequence(f.Sequence()), VisitError(f.Error(VisitLiteralString(f.LiteralString(string.Empty)))))));
3410                         }
3411                     }
3412                 }
3413             }
3414             if (this[XmlILOptimization.EliminateTypeAssertOptional]) {
3415                 if (local2.NodeType == QilNodeType.LiteralType) {
3416                     XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3417                     if (  (local1).XmlType .IsSubtypeOf(local3) ) {
3418                         // PATTERN: [EliminateTypeAssertOptional] (TypeAssert $opnd:* (LiteralType $base:*) ^ (SubtypeOf? (TypeOf $opnd) $base)) => $opnd
3419                         if (AllowReplace(XmlILOptimization.EliminateTypeAssertOptional, local0)) {
3420                             return Replace(XmlILOptimization.EliminateTypeAssertOptional, local0, local1);
3421                         }
3422                     }
3423                 }
3424             }
3425             return NoReplace(local0);
3426         }
3427
3428         protected override QilNode VisitIsType(QilTargetType local0) {
3429             QilNode local1 = local0[0];
3430             QilNode local2 = local0[1];
3431             if (this[XmlILOptimization.FoldNone]) {
3432                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3433                     // PATTERN: [FoldNone] (IsType $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3434                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3435                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3436                     }
3437                 }
3438             }
3439             if (this[XmlILOptimization.EliminateIsType]) {
3440                 if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
3441                     if (local2.NodeType == QilNodeType.LiteralType) {
3442                         XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3443                         if (  (local1).XmlType .IsSubtypeOf(local3) ) {
3444                             // PATTERN: [EliminateIsType] (IsType $opnd:* ^ (NoSideEffects? $opnd) (LiteralType $base:*) ^ (SubtypeOf? (TypeOf $opnd) $base)) => (True)
3445                             if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) {
3446                                 return Replace(XmlILOptimization.EliminateIsType, local0, VisitTrue(f.True()));
3447                             }
3448                         }
3449                     }
3450                 }
3451             }
3452             if (this[XmlILOptimization.EliminateIsType]) {
3453                 if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
3454                     if (local2.NodeType == QilNodeType.LiteralType) {
3455                         XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3456                         if (  (local1).XmlType .NeverSubtypeOf(local3) ) {
3457                             // PATTERN: [EliminateIsType] (IsType $opnd:* ^ (NoSideEffects? $opnd) (LiteralType $typ:*) ^ (NeverSubtypeOf? (TypeOf $opnd) $typ)) => (False)
3458                             if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) {
3459                                 return Replace(XmlILOptimization.EliminateIsType, local0, VisitFalse(f.False()));
3460                             }
3461                         }
3462                     }
3463                 }
3464             }
3465             if (this[XmlILOptimization.EliminateIsType]) {
3466                 if (local2.NodeType == QilNodeType.LiteralType) {
3467                     XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3468                     if (   (local1).XmlType .Prime .NeverSubtypeOf( local3.Prime ) ) {
3469                         // PATTERN: [EliminateIsType] (IsType $opnd:* (LiteralType $typ:*) ^ (NeverSubtypeOf? (Prime (TypeOf $opnd)) (Prime $typ))) => (IsEmpty $opnd)
3470                         if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) {
3471                             return Replace(XmlILOptimization.EliminateIsType, local0, VisitIsEmpty(f.IsEmpty(local1)));
3472                         }
3473                     }
3474                 }
3475             }
3476             if (this[XmlILOptimization.EliminateIsType]) {
3477                 if (!( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
3478                     if (local2.NodeType == QilNodeType.LiteralType) {
3479                         XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3480                         if (  (local1).XmlType .IsSubtypeOf(local3) ) {
3481                             // PATTERN: [EliminateIsType] (IsType $opnd:* ^ ~((NoSideEffects? $opnd)) (LiteralType $base:*) ^ (SubtypeOf? (TypeOf $opnd) $base)) => (Loop (Let $opnd) (True))
3482                             if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) {
3483                                 return Replace(XmlILOptimization.EliminateIsType, local0, VisitLoop(f.Loop(VisitLet(f.Let(local1)), VisitTrue(f.True()))));
3484                             }
3485                         }
3486                     }
3487                 }
3488             }
3489             if (this[XmlILOptimization.EliminateIsType]) {
3490                 if (!( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
3491                     if (local2.NodeType == QilNodeType.LiteralType) {
3492                         XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3493                         if (  (local1).XmlType .NeverSubtypeOf(local3) ) {
3494                             // PATTERN: [EliminateIsType] (IsType $opnd:* ^ ~((NoSideEffects? $opnd)) (LiteralType $typ:*) ^ (NeverSubtypeOf? (TypeOf $opnd) $typ)) => (Loop (Let $opnd) (False))
3495                             if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) {
3496                                 return Replace(XmlILOptimization.EliminateIsType, local0, VisitLoop(f.Loop(VisitLet(f.Let(local1)), VisitFalse(f.False()))));
3497                             }
3498                         }
3499                     }
3500                 }
3501             }
3502             return NoReplace(local0);
3503         }
3504
3505         protected override QilNode VisitIsEmpty(QilUnary local0) {
3506             QilNode local1 = local0[0];
3507             if (this[XmlILOptimization.FoldNone]) {
3508                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3509                     // PATTERN: [FoldNone] (IsEmpty $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3510                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3511                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3512                     }
3513                 }
3514             }
3515             if (this[XmlILOptimization.EliminateIsEmpty]) {
3516                 if (local1.NodeType == QilNodeType.Sequence) {
3517                     if ( (local1).Count == (0) ) {
3518                         // PATTERN: [EliminateIsEmpty] (IsEmpty $expr:(Sequence) ^ (Count? $expr 0)) => (True)
3519                         if (AllowReplace(XmlILOptimization.EliminateIsEmpty, local0)) {
3520                             return Replace(XmlILOptimization.EliminateIsEmpty, local0, VisitTrue(f.True()));
3521                         }
3522                     }
3523                 }
3524             }
3525             if (this[XmlILOptimization.EliminateIsEmpty]) {
3526                 if (( !( (local1).XmlType ).MaybeEmpty ) && ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
3527                     // PATTERN: [EliminateIsEmpty] (IsEmpty $expr:* ^ (NonEmpty? (TypeOf $expr)) ^ (NoSideEffects? $expr)) => (False)
3528                     if (AllowReplace(XmlILOptimization.EliminateIsEmpty, local0)) {
3529                         return Replace(XmlILOptimization.EliminateIsEmpty, local0, VisitFalse(f.False()));
3530                     }
3531                 }
3532             }
3533             if (this[XmlILOptimization.EliminateIsEmpty]) {
3534                 if ( !( (local1).XmlType ).MaybeEmpty ) {
3535                     // PATTERN: [EliminateIsEmpty] (IsEmpty $expr:* ^ (NonEmpty? (TypeOf $expr))) => (Loop (Let $expr) (False))
3536                     if (AllowReplace(XmlILOptimization.EliminateIsEmpty, local0)) {
3537                         return Replace(XmlILOptimization.EliminateIsEmpty, local0, VisitLoop(f.Loop(VisitLet(f.Let(local1)), VisitFalse(f.False()))));
3538                     }
3539                 }
3540             }
3541             return NoReplace(local0);
3542         }
3543
3544         #endregion // Type operators
3545
3546         #region XPath operators
3547         protected override QilNode VisitXPathNodeValue(QilUnary local0) {
3548             QilNode local1 = local0[0];
3549             if (this[XmlILOptimization.FoldNone]) {
3550                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3551                     // PATTERN: [FoldNone] (XPathNodeValue $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3552                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3553                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3554                     }
3555                 }
3556             }
3557             return NoReplace(local0);
3558         }
3559
3560         protected override QilNode VisitXPathFollowing(QilUnary local0) {
3561             QilNode local1 = local0[0];
3562             if (this[XmlILOptimization.FoldNone]) {
3563                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3564                     // PATTERN: [FoldNone] (XPathFollowing $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3565                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3566                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3567                     }
3568                 }
3569             }
3570             if (this[XmlILOptimization.AnnotateXPathFollowing]) {
3571                 // PATTERN: [AnnotateXPathFollowing] $outer:(XPathFollowing $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ { }
3572                 if (AllowReplace(XmlILOptimization.AnnotateXPathFollowing, local0)) {
3573                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  }
3574             }
3575             return NoReplace(local0);
3576         }
3577
3578         protected override QilNode VisitXPathPreceding(QilUnary local0) {
3579             QilNode local1 = local0[0];
3580             if (this[XmlILOptimization.FoldNone]) {
3581                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3582                     // PATTERN: [FoldNone] (XPathPreceding $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3583                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3584                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3585                     }
3586                 }
3587             }
3588             if (this[XmlILOptimization.AnnotateXPathPreceding]) {
3589                 // PATTERN: [AnnotateXPathPreceding] $outer:(XPathPreceding $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ { }
3590                 if (AllowReplace(XmlILOptimization.AnnotateXPathPreceding, local0)) {
3591                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  }
3592             }
3593             return NoReplace(local0);
3594         }
3595
3596         protected override QilNode VisitXPathNamespace(QilUnary local0) {
3597             QilNode local1 = local0[0];
3598             if (this[XmlILOptimization.FoldNone]) {
3599                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3600                     // PATTERN: [FoldNone] (XPathNamespace $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3601                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3602                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3603                     }
3604                 }
3605             }
3606             if (this[XmlILOptimization.AnnotateNamespace]) {
3607                 // PATTERN: [AnnotateNamespace] $outer:(XPathNamespace $input:*) => (AddPattern $outer {Axis}) ^ (AddStepPattern $outer $input) ^ (AddPattern $outer {IsDocOrderDistinct}) ^ (AddPattern $outer {SameDepth}) ^ { }
3608                 if (AllowReplace(XmlILOptimization.AnnotateNamespace, local0)) {
3609                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.Axis);  AddStepPattern((QilNode) (local0), (QilNode) (local1));  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
3610             }
3611             return NoReplace(local0);
3612         }
3613
3614         #endregion // XPath operators
3615
3616         #region XSLT
3617         protected override QilNode VisitXsltGenerateId(QilUnary local0) {
3618             QilNode local1 = local0[0];
3619             if (this[XmlILOptimization.FoldNone]) {
3620                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3621                     // PATTERN: [FoldNone] (XsltGenerateId $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3622                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3623                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3624                     }
3625                 }
3626             }
3627             return NoReplace(local0);
3628         }
3629
3630         protected override QilNode VisitXsltCopy(QilBinary local0) {
3631             QilNode local1 = local0[0];
3632             QilNode local2 = local0[1];
3633             if (this[XmlILOptimization.FoldNone]) {
3634                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3635                     // PATTERN: [FoldNone] (XsltCopy $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3636                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3637                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3638                     }
3639                 }
3640             }
3641             if (this[XmlILOptimization.FoldNone]) {
3642                 if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3643                     // PATTERN: [FoldNone] (XsltCopy * $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3644                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3645                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local2)));
3646                     }
3647                 }
3648             }
3649             if (this[XmlILOptimization.AnnotateConstruction]) {
3650                 // PATTERN: [AnnotateConstruction] $ctor:(XsltCopy * $content:*) => { ... }
3651                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3652                     local0.Right = this.contentAnalyzer.Analyze(local0, local2);
3653                 }
3654             }
3655             return NoReplace(local0);
3656         }
3657
3658         protected override QilNode VisitXsltCopyOf(QilUnary local0) {
3659             QilNode local1 = local0[0];
3660             if (this[XmlILOptimization.FoldNone]) {
3661                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3662                     // PATTERN: [FoldNone] (XsltCopyOf $x:* ^ (None? (TypeOf $x))) => (Nop $x)
3663                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3664                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3665                     }
3666                 }
3667             }
3668             if (this[XmlILOptimization.AnnotateConstruction]) {
3669                 // PATTERN: [AnnotateConstruction] $ctor:(XsltCopyOf *) => { ... }
3670                 if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
3671                     this.contentAnalyzer.Analyze(local0, null);
3672                 }
3673             }
3674             return NoReplace(local0);
3675         }
3676
3677         protected override QilNode VisitXsltConvert(QilTargetType local0) {
3678             QilNode local1 = local0[0];
3679             QilNode local2 = local0[1];
3680             if (this[XmlILOptimization.FoldNone]) {
3681                 if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
3682                     // PATTERN: [FoldNone] (XsltConvert $x:* ^ (None? (TypeOf $x)) *) => (Nop $x)
3683                     if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
3684                         return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop(local1)));
3685                     }
3686                 }
3687             }
3688             if (this[XmlILOptimization.FoldXsltConvertLiteral]) {
3689                 if ( IsLiteral((local1)) ) {
3690                     if (local2.NodeType == QilNodeType.LiteralType) {
3691                         XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3692                         if ( CanFoldXsltConvert(local1, local3) ) {
3693                             // PATTERN: [FoldXsltConvertLiteral] (XsltConvert $lit:* ^ (Literal? $lit) (LiteralType $typ:*) ^ (CanFoldXsltConvert? $lit $typ)) => (FoldXsltConvert $lit $typ)
3694                             if (AllowReplace(XmlILOptimization.FoldXsltConvertLiteral, local0)) {
3695                                 return Replace(XmlILOptimization.FoldXsltConvertLiteral, local0,  FoldXsltConvert(local1, local3) );
3696                             }
3697                         }
3698                     }
3699                 }
3700             }
3701             if (this[XmlILOptimization.EliminateXsltConvert]) {
3702                 if (local2.NodeType == QilNodeType.LiteralType) {
3703                     XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value;
3704                     if ( ( (local1).XmlType ) == (local3) ) {
3705                         // PATTERN: [EliminateXsltConvert] (XsltConvert $expr:* (LiteralType $typ:*) ^ (Equal? (TypeOf $expr) $typ)) => $expr
3706                         if (AllowReplace(XmlILOptimization.EliminateXsltConvert, local0)) {
3707                             return Replace(XmlILOptimization.EliminateXsltConvert, local0, local1);
3708                         }
3709                     }
3710                 }
3711             }
3712             return NoReplace(local0);
3713         }
3714
3715         #endregion // XSLT
3716
3717         #endregion // AUTOGENERATED
3718
3719         /// <summary>
3720         /// Selectively enable/disable optimizations
3721         /// </summary>
3722         private bool this[XmlILOptimization ann] {
3723             get { return Patterns.IsSet((int)ann); }
3724         }
3725
3726         private class NodeCounter : QilVisitor {
3727             protected QilNode target;
3728             protected int cnt;
3729
3730             /// <summary>
3731             /// Returns number of occurrences of "target" node within the subtree of "expr".
3732             /// </summary>
3733             public int Count(QilNode expr, QilNode target) {
3734                 this.cnt = 0;
3735                 this.target = target;
3736                 Visit(expr);
3737                 return this.cnt;
3738             }
3739
3740             protected override QilNode Visit(QilNode n) {
3741                 if (n == null)
3742                     return null;
3743
3744                 if (n == this.target)
3745                     this.cnt++;
3746
3747                 return VisitChildren(n);
3748             }
3749
3750             protected override QilNode VisitReference(QilNode n) {
3751                 if (n == this.target)
3752                     this.cnt++;
3753
3754                 return n;
3755             }
3756         }
3757
3758         private class NodeFinder : QilVisitor {
3759             protected bool result;
3760             protected QilNode target, parent;
3761
3762             /// <summary>
3763             /// Returns true if "target" node exists within the subtree of "expr".
3764             /// </summary>
3765             public bool Find(QilNode expr, QilNode target) {
3766                 this.result = false;
3767                 this.target = target;
3768                 this.parent = null;
3769                 VisitAssumeReference(expr);
3770                 return this.result;
3771             }
3772
3773             /// <summary>
3774             /// Recursively visit, searching for target.  If/when found, call OnFound() method.
3775             /// </summary>
3776             protected override QilNode Visit(QilNode expr) {
3777                 if (!this.result) {
3778                     if (expr == this.target)
3779                         this.result = OnFound(expr);
3780
3781                     if (!this.result) {
3782                         QilNode parentOld = this.parent;
3783                         this.parent = expr;
3784                         VisitChildren(expr);
3785                         this.parent = parentOld;
3786                     }
3787                 }
3788
3789                 return expr;
3790             }
3791
3792             /// <summary>
3793             /// Determine whether target is a reference.
3794             /// </summary>
3795             protected override QilNode VisitReference(QilNode expr) {
3796                 if (expr == this.target)
3797                     this.result = OnFound(expr);
3798
3799                 return expr;
3800             }
3801
3802             /// <summary>
3803             /// By default, just return true.
3804             /// </summary>
3805             protected virtual bool OnFound(QilNode expr) {
3806                 return true;
3807             }
3808         }
3809
3810         private class PositionOfFinder : NodeFinder {
3811             /// <summary>
3812             /// Return true only if parent node type is PositionOf.
3813             /// </summary>
3814             protected override bool OnFound(QilNode expr) {
3815                 return this.parent != null && this.parent.NodeType == QilNodeType.PositionOf;
3816             }
3817         }
3818
3819         private class EqualityIndexVisitor : QilVisitor {
3820             protected bool result;
3821             protected QilNode ctxt, key;
3822
3823             /// <summary>
3824             /// Returns true if the subtree of "expr" meets the following requirements:
3825             ///   1. Does not contain a reference to "key"
3826             ///   2. Every reference to "ctxt" is wrapped by a QilNodeType.Root node
3827             /// </summary>
3828             public bool Scan(QilNode expr, QilNode ctxt, QilNode key) {
3829                 this.result = true;
3830                 this.ctxt = ctxt;
3831                 this.key = key;
3832                 Visit(expr);
3833                 return this.result;
3834             }
3835
3836             /// <summary>
3837             /// Recursively visit, looking for references to "key" and "ctxt".
3838             /// </summary>
3839             protected override QilNode VisitReference(QilNode expr) {
3840                 if (this.result) {
3841                     if (expr == this.key || expr == this.ctxt) {
3842                         this.result = false;
3843                         return expr;
3844                     }
3845                 }
3846                 return expr;
3847             }
3848
3849             /// <summary>
3850             /// If Root wraps a reference to "ctxt", then don't visit "ctxt" and continue scan.
3851             /// </summary>
3852             protected override QilNode VisitRoot(QilUnary root) {
3853                 if (root.Child == this.ctxt)
3854                     return root;
3855
3856                 return VisitChildren(root);
3857             }
3858         }
3859
3860         /// <summary>
3861         /// Returns true if any operator within the "expr" subtree references "target".
3862         /// </summary>
3863         private bool DependsOn(QilNode expr, QilNode target) {
3864             return new NodeFinder().Find(expr, target);
3865         }
3866
3867         /// <summary>
3868         /// Returns true if there is no PositionOf operator within the "expr" subtree that references iterator "iter".
3869         /// </summary>
3870         protected bool NonPositional(QilNode expr, QilNode iter) {
3871             return !(new PositionOfFinder().Find(expr, iter));
3872         }
3873
3874         /// <summary>
3875         /// Scans "expr" subtree, looking for "refOld" references and replacing them with "refNew" references.
3876         /// </summary>
3877         private QilNode Subs(QilNode expr, QilNode refOld, QilNode refNew) {
3878             QilNode result;
3879
3880             this.subs.AddSubstitutionPair(refOld, refNew);
3881             if (expr is QilReference)
3882                 result = VisitReference(expr);
3883             else
3884                 result = Visit(expr);
3885             this.subs.RemoveLastSubstitutionPair();
3886
3887             return result;
3888         }
3889
3890         /// <summary>
3891         /// True if the specified iterator is a global variable Let iterator.
3892         /// </summary>
3893         private bool IsGlobalVariable(QilIterator iter) {
3894             return this.qil.GlobalVariableList.Contains(iter);
3895         }
3896
3897         /// <summary>
3898         /// True if the specified node is a global variable or parameter.
3899         /// </summary>
3900         private bool IsGlobalValue(QilNode nd) {
3901             if (nd.NodeType == QilNodeType.Let)
3902                 return this.qil.GlobalVariableList.Contains(nd);
3903
3904             if (nd.NodeType == QilNodeType.Parameter)
3905                 return this.qil.GlobalParameterList.Contains(nd);
3906
3907             return false;
3908         }
3909
3910         /// <summary>
3911         /// Return true if "typ" is xs:decimal=, xs:integer=, xs:int=, xs:double=, or xs:float=.
3912         /// </summary>
3913         private bool IsPrimitiveNumeric(XmlQueryType typ) {
3914             if (typ == XmlQueryTypeFactory.IntX) return true;
3915             if (typ == XmlQueryTypeFactory.IntegerX) return true;
3916             if (typ == XmlQueryTypeFactory.DecimalX) return true;
3917             if (typ == XmlQueryTypeFactory.FloatX) return true;
3918             if (typ == XmlQueryTypeFactory.DoubleX) return true;
3919
3920             return false;
3921         }
3922
3923         /// <summary>
3924         /// Returns true if "typ" matches one of the XPath content node tests: *, text(), comment(), pi(), or node().
3925         /// </summary>
3926         private bool MatchesContentTest(XmlQueryType typ) {
3927             if (typ == XmlQueryTypeFactory.Element) return true;
3928             if (typ == XmlQueryTypeFactory.Text) return true;
3929             if (typ == XmlQueryTypeFactory.Comment) return true;
3930             if (typ == XmlQueryTypeFactory.PI) return true;
3931             if (typ == XmlQueryTypeFactory.Content) return true;
3932
3933             return false;
3934         }
3935
3936         /// <summary>
3937         /// True if the specified expression constructs one or more nodes using QilExpression constructor operators.
3938         /// This information is used to determine whether the results of a function should be streamed to a writer
3939         /// rather than cached.
3940         /// </summary>
3941         private bool IsConstructedExpression(QilNode nd) {
3942             QilTernary ndCond;
3943
3944             // In debug mode, all functions should return void (streamed to writer), so that call stack
3945             // consistently shows caller's line number
3946             if (this.qil.IsDebug)
3947                 return true;
3948
3949             if (nd.XmlType.IsNode) {
3950                 switch (nd.NodeType) {
3951                     case QilNodeType.ElementCtor:
3952                     case QilNodeType.AttributeCtor:
3953                     case QilNodeType.CommentCtor:
3954                     case QilNodeType.PICtor:
3955                     case QilNodeType.TextCtor:
3956                     case QilNodeType.RawTextCtor:
3957                     case QilNodeType.DocumentCtor:
3958                     case QilNodeType.NamespaceDecl:
3959                     case QilNodeType.XsltCopy:
3960                     case QilNodeType.XsltCopyOf:
3961                     case QilNodeType.Choice:
3962                         return true;
3963
3964                     case QilNodeType.Loop:
3965                         // Return true if the return expression is constructed
3966                         return IsConstructedExpression(((QilLoop) nd).Body);
3967
3968                     case QilNodeType.Sequence:
3969                         // Return true if the list is empty or at least one expression in the list is constructed
3970                         if (nd.Count == 0)
3971                             return true;
3972
3973                         foreach (QilNode ndItem in nd) {
3974                             if (IsConstructedExpression(ndItem))
3975                                 return true;
3976                         }
3977                         break;
3978
3979                     case QilNodeType.Conditional:
3980                         // Return true if either left and right branches of the conditional are constructed
3981                         ndCond = (QilTernary) nd;
3982                         return IsConstructedExpression(ndCond.Center) || IsConstructedExpression(ndCond.Right);
3983
3984                     case QilNodeType.Invoke:
3985                         // Return true if the function might return nodes
3986                         return !((QilInvoke) nd).Function.XmlType.IsAtomicValue;
3987                 }
3988             }
3989
3990             return false;
3991         }
3992
3993         /// <summary>
3994         /// True if the specified expression is a literal value.
3995         /// </summary>
3996         private bool IsLiteral(QilNode nd) {
3997             switch (nd.NodeType) {
3998                 case QilNodeType.True:
3999                 case QilNodeType.False:
4000                 case QilNodeType.LiteralString:
4001                 case QilNodeType.LiteralInt32:
4002                 case QilNodeType.LiteralInt64:
4003                 case QilNodeType.LiteralDouble:
4004                 case QilNodeType.LiteralDecimal:
4005                 case QilNodeType.LiteralQName:
4006                     return true;
4007             }
4008             return false;
4009         }
4010
4011         /// <summary>
4012         /// Return true if all children of "nd" are constant.
4013         /// </summary>
4014         private bool AreLiteralArgs(QilNode nd) {
4015             foreach (QilNode child in nd)
4016                 if (!IsLiteral(child))
4017                     return false;
4018
4019             return true;
4020         }
4021
4022         /// <summary>
4023         /// Extract the value of a literal.
4024         /// </summary>
4025         private object ExtractLiteralValue(QilNode nd) {
4026             if (nd.NodeType == QilNodeType.True)
4027                 return true;
4028             else if (nd.NodeType == QilNodeType.False)
4029                 return false;
4030             else if (nd.NodeType == QilNodeType.LiteralQName)
4031                 return nd;
4032
4033             Debug.Assert(nd is QilLiteral, "All literals except True, False, and QName must use QilLiteral");
4034             return ((QilLiteral) nd).Value;
4035         }
4036
4037         /// <summary>
4038         /// Return true if "nd" has a child of type Sequence.
4039         /// </summary>
4040         private bool HasNestedSequence(QilNode nd) {
4041             foreach (QilNode child in nd) {
4042                 if (child.NodeType == QilNodeType.Sequence)
4043                     return true;
4044             }
4045             return false;
4046         }
4047
4048         /// <summary>
4049         /// True if the JoinAndDod pattern is allowed to match the specified node.
4050         /// </summary>
4051         private bool AllowJoinAndDod(QilNode nd) {
4052             OptimizerPatterns patt = OptimizerPatterns.Read(nd);
4053
4054             // AllowJoinAndDod if this pattern is the descendant, descendant-or-self, content, preceding, following, or
4055             // following-sibling axis, filtered by either an element name or a node kind test.
4056             if (patt.MatchesPattern(OptimizerPatternName.FilterElements) || patt.MatchesPattern(OptimizerPatternName.FilterContentKind)) {
4057                 if (IsStepPattern(patt, QilNodeType.DescendantOrSelf) || IsStepPattern(patt, QilNodeType.Descendant) ||
4058                     IsStepPattern(patt, QilNodeType.Content) || IsStepPattern(patt, QilNodeType.XPathPreceding) ||
4059                     IsStepPattern(patt, QilNodeType.XPathFollowing) || IsStepPattern(patt, QilNodeType.FollowingSibling)) {
4060                     return true;
4061                 }
4062             }
4063             return false;
4064         }
4065
4066         /// <summary>
4067         /// True if the DodReverse pattern is allowed to match the specified node.
4068         /// </summary>
4069         private bool AllowDodReverse(QilNode nd) {
4070             OptimizerPatterns patt = OptimizerPatterns.Read(nd);
4071
4072             // AllowDodReverse if this pattern is the ancestor, ancestor-or-self, preceding, or preceding-sibling axis,
4073             // filtered by either an element name or a node kind test.
4074             if (patt.MatchesPattern(OptimizerPatternName.Axis) ||
4075                 patt.MatchesPattern(OptimizerPatternName.FilterElements) ||
4076                 patt.MatchesPattern(OptimizerPatternName.FilterContentKind)) {
4077                 if (IsStepPattern(patt, QilNodeType.Ancestor) || IsStepPattern(patt, QilNodeType.AncestorOrSelf) ||
4078                     IsStepPattern(patt, QilNodeType.XPathPreceding) || IsStepPattern(patt, QilNodeType.PrecedingSibling)) {
4079                     return true;
4080                 }
4081             }
4082             return false;
4083         }
4084
4085         /// <summary>
4086         /// Return true if XsltConvert applied to a Literal can be folded (i.e. the XsltConvert eliminated).
4087         /// </summary>
4088         private bool CanFoldXsltConvert(QilNode ndLiteral, XmlQueryType typTarget) {
4089             // Attempt to fold--on failure, an unfolded XsltConvert node will be returned
4090             return FoldXsltConvert(ndLiteral, typTarget).NodeType != QilNodeType.XsltConvert;
4091         }
4092
4093         /// <summary>
4094         /// Return true if XsltConvert applied to a Literal can be folded (i.e. the XsltConvert eliminated), without
4095         /// any loss of information.
4096         /// </summary>
4097         private bool CanFoldXsltConvertNonLossy(QilNode ndLiteral, XmlQueryType typTarget) {
4098             QilNode ndDest;
4099
4100             // Fold conversion to target type; if conversion cannot be folded, a XsltConvert node is returned
4101             ndDest = FoldXsltConvert(ndLiteral, typTarget);
4102             if (ndDest.NodeType == QilNodeType.XsltConvert)
4103                 return false;
4104
4105             // Convert back to source type; if conversion cannot be folded, a XsltConvert node is returned
4106             ndDest = FoldXsltConvert(ndDest, ndLiteral.XmlType);
4107             if (ndDest.NodeType == QilNodeType.XsltConvert)
4108                 return false;
4109
4110             // If original value is the same as the round-tripped value, then conversion is non-lossy
4111             return ExtractLiteralValue(ndLiteral).Equals(ExtractLiteralValue(ndDest));
4112         }
4113
4114         /// <summary>
4115         /// Fold a XsltConvert applied to a Literal into another Literal.  If the fold results in some kind of
4116         /// conversion error, or if the QilExpression cannot represent the result as a Literal, return an unfolded
4117         /// XsltConvert expression.
4118         /// </summary>
4119         private QilNode FoldXsltConvert(QilNode ndLiteral, XmlQueryType typTarget) {
4120             try {
4121                 if (typTarget.IsAtomicValue) {
4122                     // Convert the literal to an XmlAtomicValue
4123                     XmlAtomicValue value = new XmlAtomicValue(ndLiteral.XmlType.SchemaType, ExtractLiteralValue(ndLiteral));
4124                     value = XsltConvert.ConvertToType(value, typTarget);
4125
4126                     if (typTarget == XmlQueryTypeFactory.StringX)
4127                         return this.f.LiteralString(value.Value);
4128                     else if (typTarget == XmlQueryTypeFactory.IntX)
4129                         return this.f.LiteralInt32(value.ValueAsInt);
4130                     else if (typTarget == XmlQueryTypeFactory.IntegerX)
4131                         return this.f.LiteralInt64(value.ValueAsLong);
4132                     else if (typTarget == XmlQueryTypeFactory.DecimalX)
4133                         return this.f.LiteralDecimal((decimal) value.ValueAs(XsltConvert.DecimalType));
4134                     else if (typTarget == XmlQueryTypeFactory.DoubleX)
4135                         return this.f.LiteralDouble(value.ValueAsDouble);
4136                     else if (typTarget == XmlQueryTypeFactory.BooleanX)
4137                         return value.ValueAsBoolean ? this.f.True() : this.f.False();
4138                 }
4139             }
4140             catch (OverflowException) {}
4141             catch (FormatException) {}
4142
4143             // Conversion error or QilExpression cannot represent resulting literal
4144             return this.f.XsltConvert(ndLiteral, typTarget);
4145         }
4146
4147         /// <summary>
4148         /// Compute the arithmetic operation "opType" over two literal operands and return the result as a QilLiteral.
4149         /// In the case of an overflow or divide by zero exception, return the unfolded result.
4150         /// </summary>
4151         private QilNode FoldComparison(QilNodeType opType, QilNode left, QilNode right) {
4152             object litLeft, litRight;
4153             int cmp;
4154             Debug.Assert(left.XmlType == right.XmlType, "Comparison is not defined between " + left.XmlType + " and " + right.XmlType);
4155
4156             // Extract objects that represent each literal value
4157             litLeft = ExtractLiteralValue(left);
4158             litRight = ExtractLiteralValue(right);
4159
4160             if (left.NodeType == QilNodeType.LiteralDouble) {
4161                 // Equals and CompareTo do not handle NaN correctly
4162                 if (Double.IsNaN((double) litLeft) || Double.IsNaN((double) litRight))
4163                     return (opType == QilNodeType.Ne) ? f.True() : f.False();
4164             }
4165
4166             if (opType == QilNodeType.Eq)
4167                 return litLeft.Equals(litRight) ? f.True() : f.False();
4168
4169             if (opType == QilNodeType.Ne)
4170                 return litLeft.Equals(litRight) ? f.False() : f.True();
4171
4172             if (left.NodeType == QilNodeType.LiteralString) {
4173                 // CompareTo does not use Ordinal comparison
4174                 cmp = string.CompareOrdinal((string) litLeft, (string) litRight);
4175             }
4176             else {
4177                 cmp = ((IComparable) litLeft).CompareTo(litRight);
4178             }
4179
4180             switch (opType) {
4181                 case QilNodeType.Gt: return cmp > 0 ? f.True() : f.False();
4182                 case QilNodeType.Ge: return cmp >= 0 ? f.True() : f.False();
4183                 case QilNodeType.Lt: return cmp < 0 ? f.True() : f.False();
4184                 case QilNodeType.Le: return cmp <= 0 ? f.True() : f.False();
4185             }
4186
4187             Debug.Assert(false, "Cannot fold this comparison operation: " + opType);
4188             return null;
4189         }
4190
4191         /// <summary>
4192         /// Return true if arithmetic operation "opType" can be computed over two literal operands without causing
4193         /// an overflow or divide by zero exception.
4194         /// </summary>
4195         private bool CanFoldArithmetic(QilNodeType opType, QilLiteral left, QilLiteral right) {
4196             return (FoldArithmetic(opType, left, right) is QilLiteral);
4197         }
4198
4199         /// <summary>
4200         /// Compute the arithmetic operation "opType" over two literal operands and return the result as a QilLiteral.
4201         /// Arithmetic operations are always checked; in the case of an overflow or divide by zero exception, return
4202         /// the unfolded result.
4203         /// </summary>
4204         private QilNode FoldArithmetic(QilNodeType opType, QilLiteral left, QilLiteral right) {
4205             Debug.Assert(left.NodeType == right.NodeType);
4206
4207             // Catch any overflow or divide by zero exceptions
4208             try {
4209                 checked {
4210                     switch (left.NodeType) {
4211                         case QilNodeType.LiteralInt32: {
4212                             int intLeft = left;
4213                             int intRight = right;
4214
4215                             switch (opType) {
4216                                 case QilNodeType.Add: return f.LiteralInt32(intLeft + intRight);
4217                                 case QilNodeType.Subtract: return f.LiteralInt32(intLeft - intRight);
4218                                 case QilNodeType.Multiply: return f.LiteralInt32(intLeft * intRight);
4219                                 case QilNodeType.Divide: return f.LiteralInt32(intLeft / intRight);
4220                                 case QilNodeType.Modulo: return f.LiteralInt32(intLeft % intRight);
4221                             }
4222                             break;
4223                         }
4224
4225                         case QilNodeType.LiteralInt64: {
4226                             long lngLeft = left;
4227                             long lngRight = right;
4228
4229                             switch (opType) {
4230                                 case QilNodeType.Add: return f.LiteralInt64(lngLeft + lngRight);
4231                                 case QilNodeType.Subtract: return f.LiteralInt64(lngLeft - lngRight);
4232                                 case QilNodeType.Multiply: return f.LiteralInt64(lngLeft * lngRight);
4233                                 case QilNodeType.Divide: return f.LiteralInt64(lngLeft / lngRight);
4234                                 case QilNodeType.Modulo: return f.LiteralInt64(lngLeft % lngRight);
4235                             }
4236                             break;
4237                         }
4238
4239                         case QilNodeType.LiteralDecimal: {
4240                             decimal lngLeft = left;
4241                             decimal lngRight = right;
4242
4243                             switch (opType) {
4244                                 case QilNodeType.Add: return f.LiteralDecimal(lngLeft + lngRight);
4245                                 case QilNodeType.Subtract: return f.LiteralDecimal(lngLeft - lngRight);
4246                                 case QilNodeType.Multiply: return f.LiteralDecimal(lngLeft * lngRight);
4247                                 case QilNodeType.Divide: return f.LiteralDecimal(lngLeft / lngRight);
4248                                 case QilNodeType.Modulo: return f.LiteralDecimal(lngLeft % lngRight);
4249                             }
4250                             break;
4251                         }
4252
4253                         case QilNodeType.LiteralDouble: {
4254                             double lngLeft = left;
4255                             double lngRight = right;
4256
4257                             switch (opType) {
4258                                 case QilNodeType.Add: return f.LiteralDouble(lngLeft + lngRight);
4259                                 case QilNodeType.Subtract: return f.LiteralDouble(lngLeft - lngRight);
4260                                 case QilNodeType.Multiply: return f.LiteralDouble(lngLeft * lngRight);
4261                                 case QilNodeType.Divide: return f.LiteralDouble(lngLeft / lngRight);
4262                                 case QilNodeType.Modulo: return f.LiteralDouble(lngLeft % lngRight);
4263                             }
4264                             break;
4265                         }
4266                     }
4267                 }
4268             }
4269             catch (OverflowException) {
4270             }
4271             catch (DivideByZeroException) {
4272             }
4273
4274             // An error occurred, so don't fold operationo
4275             switch (opType) {
4276                 case QilNodeType.Add: return f.Add(left, right);
4277                 case QilNodeType.Subtract: return f.Subtract(left, right);
4278                 case QilNodeType.Multiply: return f.Multiply(left, right);
4279                 case QilNodeType.Divide: return f.Divide(left, right);
4280                 case QilNodeType.Modulo: return f.Modulo(left, right);
4281             }
4282
4283             Debug.Assert(false, "Cannot fold this arithmetic operation: " + opType);
4284             return null;
4285         }
4286
4287         /// <summary>
4288         /// Mark the specified node as matching the Step pattern and set the step node and step input arguments.
4289         /// </summary>
4290         private void AddStepPattern(QilNode nd, QilNode input) {
4291             OptimizerPatterns patt = OptimizerPatterns.Write(nd);
4292             patt.AddPattern(OptimizerPatternName.Step);
4293             patt.AddArgument(OptimizerPatternArgument.StepNode, nd);
4294             patt.AddArgument(OptimizerPatternArgument.StepInput, input);
4295         }
4296
4297         /// <summary>
4298         /// Return true if "nd" matches the Step pattern and the StepType argument is equal to "stepType".
4299         /// </summary>
4300         private bool IsDocOrderDistinct(QilNode nd) {
4301             return OptimizerPatterns.Read(nd).MatchesPattern(OptimizerPatternName.IsDocOrderDistinct);
4302         }
4303
4304         /// <summary>
4305         /// Return true if "nd" matches the Step pattern and the StepType argument is equal to "stepType".
4306         /// </summary>
4307         private bool IsStepPattern(QilNode nd, QilNodeType stepType) {
4308             return IsStepPattern(OptimizerPatterns.Read(nd), stepType);
4309         }
4310
4311         /// <summary>
4312         /// Return true if "patt" matches the Step pattern and the StepType argument is equal to "stepType".
4313         /// </summary>
4314         private bool IsStepPattern(OptimizerPatterns patt, QilNodeType stepType) {
4315             return patt.MatchesPattern(OptimizerPatternName.Step) && ((QilNode) patt.GetArgument(OptimizerPatternArgument.StepNode)).NodeType == stepType;
4316         }
4317
4318         /// <summary>
4319         /// Remove unused global functions, variables, or parameters from the list.
4320         /// </summary>
4321         private static void EliminateUnusedGlobals(IList<QilNode> globals) {
4322             int newIdx = 0;
4323
4324             for (int oldIdx = 0; oldIdx < globals.Count; oldIdx++) {
4325                 QilNode nd = globals[oldIdx];
4326                 bool isUsed;
4327
4328                 if (nd.NodeType == QilNodeType.Function) {
4329                     // Keep a function if it has at least one caller
4330                     isUsed = XmlILConstructInfo.Read(nd).CallersInfo.Count != 0;
4331                 }
4332                 else {
4333                     Debug.Assert(nd.NodeType == QilNodeType.Let || nd.NodeType == QilNodeType.Parameter, "Unexpected type of a global");
4334
4335                     // Keep a variable or parameter if it was referenced at least once or may have side effects
4336                     OptimizerPatterns optPatt = OptimizerPatterns.Read(nd);
4337                     isUsed = optPatt.MatchesPattern(OptimizerPatternName.IsReferenced) || optPatt.MatchesPattern(OptimizerPatternName.MaybeSideEffects);
4338                 }
4339
4340                 if (isUsed) {
4341                     if (newIdx < oldIdx)
4342                         globals[newIdx] = globals[oldIdx];
4343
4344                     newIdx++;
4345                 }
4346             }
4347
4348             // Removing elements from the end makes the algorithm linear
4349             for (int oldIdx = globals.Count - 1; oldIdx >= newIdx; oldIdx--) {
4350                 globals.RemoveAt(oldIdx);
4351             }
4352         }
4353     }
4354 }