protected override QilNode VisitSort(QilLoop ndSort) {
Type itemStorageType = GetItemStorageType(ndSort);
LocalBuilder locCache, locKeys;
Label lblOnEndSort = this.helper.DefineLabel();
Debug.Assert(ndSort.Variable.NodeType == QilNodeType.For);
// XmlQuerySequence<T> cache;
// cache = XmlQuerySequence.CreateOrReuse(cache);
XmlILStorageMethods methods = XmlILMethods.StorageMethods[itemStorageType];
locCache = this.helper.DeclareLocal("$$$cache", methods.SeqType);
this.helper.Emit(OpCodes.Ldloc, locCache);
this.helper.CallToken(methods.SeqReuse);
this.helper.Emit(OpCodes.Stloc, locCache);
this.helper.Emit(OpCodes.Ldloc, locCache);
// XmlSortKeyAccumulator keys;
// keys.Create(runtime);
locKeys = this.helper.DeclareLocal("$$$keys", typeof(XmlSortKeyAccumulator));
this.helper.Emit(OpCodes.Ldloca, locKeys);
this.helper.Call(XmlILMethods.SortKeyCreate);
// Construct nested iterator
// foreach (item in sort-expr) {
StartNestedIterator(ndSort.Variable, lblOnEndSort);
StartBinding(ndSort.Variable);
Debug.Assert(!this.iterNested.Storage.IsCached);
// cache.Add(item);
this.iterCurr.EnsureStackNoCache();
this.iterCurr.EnsureItemStorageType(ndSort.Variable.XmlType, GetItemStorageType(ndSort.Variable));
this.helper.Call(methods.SeqAdd);
this.helper.Emit(OpCodes.Ldloca, locKeys);
// Add keys to accumulator (there may be several keys)
foreach (QilSortKey ndKey in ndSort.Body)
VisitSortKey(ndKey, locKeys);
// keys.FinishSortKeys();
this.helper.Call(XmlILMethods.SortKeyFinish);
// }
this.helper.Emit(OpCodes.Ldloc, locCache);
this.iterCurr.LoopToEnd(lblOnEndSort);
// Remove cache reference from stack
this.helper.Emit(OpCodes.Pop);
// cache.SortByKeys(keys.Keys);
this.helper.Emit(OpCodes.Ldloc, locCache);
this.helper.Emit(OpCodes.Ldloca, locKeys);
this.helper.Call(XmlILMethods.SortKeyKeys);
this.helper.Call(methods.SeqSortByKeys);
// End nested iterator
this.iterCurr.Storage = StorageDescriptor.Local(locCache, itemStorageType, true);
EndBinding(ndSort.Variable);
EndNestedIterator(ndSort.Variable);
this.iterCurr.SetIterator(this.iterNested);
return ndSort;
}