public override object ValidateElement(XmlQualifiedName name, ValidationState context, out int errorCode) { BitSet set = context.CurPos[context.CurrentState.CurPosIndex]; int index = (context.CurrentState.CurPosIndex + 1) % 2; BitSet set2 = context.CurPos[index]; set2.Clear(); int num2 = this.symbols[name]; object particle = null; errorCode = 0; for (int i = set.NextSet(-1); i != -1; i = set.NextSet(i)) { if (num2 == this.positions[i].symbol) { set2.Or(this.followpos[i]); particle = this.positions[i].particle; break; } } if (!set2.IsEmpty) { context.CurrentState.CurPosIndex = index; return(particle); } if (!base.IsOpen || !set[this.endMarkerPos]) { context.NeedValidateChildren = false; errorCode = -1; } return(null); }
public override void ConstructPos(BitSet firstpos, BitSet lastpos, BitSet[] followpos) { BitSet set = new BitSet(lastpos.Count); base.LeftChild.ConstructPos(firstpos, set, followpos); BitSet set2 = new BitSet(firstpos.Count); base.RightChild.ConstructPos(set2, lastpos, followpos); if (base.LeftChild.IsNullable && !base.RightChild.IsRangeNode) { firstpos.Or(set2); } if (base.RightChild.IsNullable) { lastpos.Or(set); } for (int i = set.NextSet(-1); i != -1; i = set.NextSet(i)) { followpos[i].Or(set2); } if (base.RightChild.IsRangeNode) { ((LeafRangeNode)base.RightChild).NextIteration = firstpos.Clone(); } }
public override ArrayList ExpectedParticles(ValidationState context, bool isRequiredOnly, XmlSchemaSet schemaSet) { ArrayList particles = new ArrayList(); if (context.RunningPositions != null) { List <RangePositionInfo> runningPositions = context.RunningPositions; BitSet set = new BitSet(this.positions.Count); for (int i = context.CurrentState.NumberOfRunningPos - 1; i >= 0; i--) { set.Or(runningPositions[i].curpos); } for (int j = set.NextSet(-1); j != -1; j = set.NextSet(j)) { if (this.positions[j].symbol >= 0) { XmlSchemaParticle p = this.positions[j].particle as XmlSchemaParticle; if (p != null) { ContentValidator.AddParticleToExpected(p, schemaSet, particles); } } } } return(particles); }
public override void ConstructPos(BitSet firstpos, BitSet lastpos, BitSet[] followpos) { base.LeftChild.ConstructPos(firstpos, lastpos, followpos); BitSet set = new BitSet(firstpos.Count); BitSet set2 = new BitSet(lastpos.Count); base.RightChild.ConstructPos(set, set2, followpos); firstpos.Or(set); lastpos.Or(set2); }
private int[][] BuildTransitionTable(BitSet firstpos, BitSet[] followpos, int endMarkerPos) { int count = this.positions.Count; int num2 = 0x2000 / count; int index = this.symbols.Count; ArrayList list = new ArrayList(); Hashtable hashtable = new Hashtable(); hashtable.Add(new BitSet(count), -1); Queue queue = new Queue(); int num4 = 0; queue.Enqueue(firstpos); hashtable.Add(firstpos, 0); list.Add(new int[index + 1]); while (queue.Count > 0) { BitSet set = (BitSet)queue.Dequeue(); int[] numArray = (int[])list[num4]; if (set[endMarkerPos]) { numArray[index] = 1; } for (int i = 0; i < index; i++) { BitSet set2 = new BitSet(count); for (int j = set.NextSet(-1); j != -1; j = set.NextSet(j)) { if (i == this.positions[j].symbol) { set2.Or(followpos[j]); } } object obj2 = hashtable[set2]; if (obj2 != null) { numArray[i] = (int)obj2; } else { int num7 = hashtable.Count - 1; if (num7 >= num2) { return(null); } queue.Enqueue(set2); hashtable.Add(set2, num7); list.Add(new int[index + 1]); numArray[i] = num7; } } num4++; } return((int[][])list.ToArray(typeof(int[]))); }
private BitSet[] CalculateTotalFollowposForRangeNodes(BitSet firstpos, BitSet[] followpos, out BitSet posWithRangeTerminals) { int count = this.positions.Count; posWithRangeTerminals = new BitSet(count); BitSet[] setArray = new BitSet[this.minMaxNodesCount]; int index = 0; for (int i = count - 1; i >= 0; i--) { Position position = this.positions[i]; if (position.symbol == -2) { LeafRangeNode particle = position.particle as LeafRangeNode; BitSet set = new BitSet(count); set.Clear(); set.Or(followpos[i]); if (particle.Min != particle.Max) { set.Or(particle.NextIteration); } for (int j = set.NextSet(-1); j != -1; j = set.NextSet(j)) { if (j > i) { Position position2 = this.positions[j]; if (position2.symbol == -2) { LeafRangeNode node2 = position2.particle as LeafRangeNode; set.Or(setArray[node2.Pos]); } } } setArray[index] = set; particle.Pos = index++; posWithRangeTerminals.Set(i); } } return(setArray); }
private BitSet GetApplicableMinMaxFollowPos(BitSet curpos, BitSet posWithRangeTerminals, BitSet[] minmaxFollowPos) { if (curpos.Intersects(posWithRangeTerminals)) { BitSet set = new BitSet(this.positions.Count); set.Or(curpos); set.And(posWithRangeTerminals); curpos = curpos.Clone(); for (int i = set.NextSet(-1); i != -1; i = set.NextSet(i)) { LeafRangeNode particle = this.positions[i].particle as LeafRangeNode; curpos.Or(minmaxFollowPos[particle.Pos]); } } return(curpos); }
public override ArrayList ExpectedElements(ValidationState context, bool isRequiredOnly) { ArrayList list = null; if (context.RunningPositions != null) { List <RangePositionInfo> runningPositions = context.RunningPositions; BitSet set = new BitSet(this.positions.Count); for (int i = context.CurrentState.NumberOfRunningPos - 1; i >= 0; i--) { set.Or(runningPositions[i].curpos); } for (int j = set.NextSet(-1); j != -1; j = set.NextSet(j)) { if (list == null) { list = new ArrayList(); } if (this.positions[j].symbol >= 0) { XmlSchemaParticle particle = this.positions[j].particle as XmlSchemaParticle; if (particle == null) { string str = this.symbols.NameOf(this.positions[j].symbol); if (str.Length != 0) { list.Add(str); } } else { string nameString = particle.NameString; if (!list.Contains(nameString)) { list.Add(nameString); } } } } } return(list); }
//For each position, this method calculates the additional follows of any range nodes that need to be added to its followpos //((ab?)2-4)c, Followpos of a is b as well as that of node R(2-4) = c private BitSet GetApplicableMinMaxFollowPos(BitSet curpos, BitSet posWithRangeTerminals, BitSet[] minmaxFollowPos) { if (curpos.Intersects(posWithRangeTerminals)) { BitSet newSet = new BitSet(positions.Count); //Doing work again newSet.Or(curpos); newSet.And(posWithRangeTerminals); curpos = curpos.Clone(); for (int pos = newSet.NextSet(-1); pos != -1; pos = newSet.NextSet(pos)) { LeafRangeNode lrNode = positions[pos].particle as LeafRangeNode; curpos.Or(minmaxFollowPos[lrNode.Pos]); } } return curpos; }
private BitSet[] CalculateTotalFollowposForRangeNodes(BitSet firstpos, BitSet[] followpos, out BitSet posWithRangeTerminals) { int positionsCount = positions.Count; //terminals posWithRangeTerminals = new BitSet(positionsCount); //Compute followpos for each range node //For any range node that is surrounded by an outer range node, its follow positions will include those of the outer range node BitSet[] minmaxFollowPos = new BitSet[minMaxNodesCount]; int localMinMaxNodesCount = 0; for (int i = positionsCount - 1; i >= 0; i--) { Position p = positions[i]; if (p.symbol == -2) { //P is a LeafRangeNode LeafRangeNode lrNode = p.particle as LeafRangeNode; Debug.Assert(lrNode != null); BitSet tempFollowPos = new BitSet(positionsCount); tempFollowPos.Clear(); tempFollowPos.Or(followpos[i]); //Add the followpos of the range node if (lrNode.Min != lrNode.Max) { //If they are the same, then followpos cannot include the firstpos tempFollowPos.Or(lrNode.NextIteration); //Add the nextIteration of the range node (this is the firstpos of its parent's leftChild) } //For each position in the bitset, if it is a outer range node (pos > i), then add its followpos as well to the current node's followpos for (int pos = tempFollowPos.NextSet(-1); pos != -1; pos = tempFollowPos.NextSet(pos)) { if (pos > i) { Position p1 = positions[pos]; if (p1.symbol == -2) { LeafRangeNode lrNode1 = p1.particle as LeafRangeNode; Debug.Assert(lrNode1 != null); tempFollowPos.Or(minmaxFollowPos[lrNode1.Pos]); } } } //set the followpos built to the index in the BitSet[] minmaxFollowPos[localMinMaxNodesCount] = tempFollowPos; lrNode.Pos = localMinMaxNodesCount++; posWithRangeTerminals.Set(i); } } return minmaxFollowPos; }
internal void Finish(ValidationEventHandler eventHandler, bool compile) { stack = null; IsCompiled = !abnormalContent && compile; if (contentNode == null) return; #if DEBUG StringBuilder bb = new StringBuilder(); contentNode.Dump(bb); Debug.WriteLineIf(CompModSwitches.XmlSchema.TraceVerbose, "\t\t\tContent: (" + bb.ToString() + ")"); #endif // add end node endNode = NewTerminalNode(XmlQualifiedName.Empty); contentNode = new InternalNode(contentNode, endNode, ContentNode.Type.Sequence); ((InternalNode)contentNode).LeftNode.ParentNode = contentNode; endNode.ParentNode = contentNode; if (!IsCompiled) { CheckXsdDeterministic(eventHandler); return; } if (nodeTable == null) nodeTable = new Hashtable(); // calculate followpos int terminals = terminalNodes.Count; BitSet[] followpos = new BitSet[terminals]; for (int i = 0; i < terminals; i++) { followpos[i] = new BitSet(terminals); } contentNode.CalcFollowpos(followpos); // state table ArrayList Dstates = new ArrayList(16); // transition table dtrans = new ArrayList(16); // lists unmarked states ArrayList unmarked = new ArrayList(16); // state lookup table Hashtable statetable = new Hashtable(); BitSet empty = new BitSet(terminals); statetable.Add(empty, -1); // start with firstpos at the root BitSet set = contentNode.Firstpos(terminals); statetable.Add(set, Dstates.Count); unmarked.Add(set); Dstates.Add(set); int[] a = new int[symbols.Count + 1]; dtrans.Add(a); if (set.Get(endNode.Pos)) { a[symbols.Count] = 1; // accepting } // current state processed int state = 0; // check all unmarked states while (unmarked.Count > 0) { int[] t = (int[])dtrans[state]; set = (BitSet)unmarked[0]; CheckDeterministic(set, terminals, eventHandler); unmarked.RemoveAt(0); // check all input symbols for (int sym = 0; sym < symbols.Count; sym++) { XmlQualifiedName n = (XmlQualifiedName)symbols[sym]; BitSet newset = new BitSet(terminals); // if symbol is in the set add followpos to new set for (int i = 0; i < terminals; i++) { if (set.Get(i) && n.Equals(((TerminalNode)terminalNodes[i]).Name)) { newset.Or(followpos[i]); } } Object lookup = statetable[newset]; // this state will transition to int transitionTo; // if new set is not in states add it if (lookup == null) { transitionTo = Dstates.Count; statetable.Add(newset, transitionTo); unmarked.Add(newset); Dstates.Add(newset); a = new int[symbols.Count + 1]; dtrans.Add(a); if (newset.Get(endNode.Pos)) { a[symbols.Count] = 1; // accepting } } else { transitionTo = (int)lookup; } // set the transition for the symbol t[sym] = transitionTo; } state++; } nodeTable = null; }
internal void Finish(ValidationEventHandler eventHandler, bool compile) { stack = null; IsCompiled = !abnormalContent && compile; if (contentNode == null) { return; } #if DEBUG StringBuilder bb = new StringBuilder(); contentNode.Dump(bb); Debug.WriteLineIf(CompModSwitches.XmlSchema.TraceVerbose, "\t\t\tContent: (" + bb.ToString() + ")"); #endif // add end node endNode = NewTerminalNode(XmlQualifiedName.Empty); contentNode = new InternalNode(contentNode, endNode, ContentNode.Type.Sequence); ((InternalNode)contentNode).LeftNode.ParentNode = contentNode; endNode.ParentNode = contentNode; if (!IsCompiled) { CheckXsdDeterministic(eventHandler); return; } if (nodeTable == null) { nodeTable = new Hashtable(); } // calculate followpos int terminals = terminalNodes.Count; BitSet[] followpos = new BitSet[terminals]; for (int i = 0; i < terminals; i++) { followpos[i] = new BitSet(terminals); } contentNode.CalcFollowpos(followpos); // state table ArrayList Dstates = new ArrayList(16); // transition table dtrans = new ArrayList(16); // lists unmarked states ArrayList unmarked = new ArrayList(16); // state lookup table Hashtable statetable = new Hashtable(); BitSet empty = new BitSet(terminals); statetable.Add(empty, -1); // start with firstpos at the root BitSet set = contentNode.Firstpos(terminals); statetable.Add(set, Dstates.Count); unmarked.Add(set); Dstates.Add(set); int[] a = new int[symbols.Count + 1]; dtrans.Add(a); if (set.Get(endNode.Pos)) { a[symbols.Count] = 1; // accepting } // current state processed int state = 0; // check all unmarked states while (unmarked.Count > 0) { int[] t = (int[])dtrans[state]; set = (BitSet)unmarked[0]; CheckDeterministic(set, terminals, eventHandler); unmarked.RemoveAt(0); // check all input symbols for (int sym = 0; sym < symbols.Count; sym++) { XmlQualifiedName n = (XmlQualifiedName)symbols[sym]; BitSet newset = new BitSet(terminals); // if symbol is in the set add followpos to new set for (int i = 0; i < terminals; i++) { if (set.Get(i) && n.Equals(((TerminalNode)terminalNodes[i]).Name)) { newset.Or(followpos[i]); } } Object lookup = statetable[newset]; // this state will transition to int transitionTo; // if new set is not in states add it if (lookup == null) { transitionTo = Dstates.Count; statetable.Add(newset, transitionTo); unmarked.Add(newset); Dstates.Add(newset); a = new int[symbols.Count + 1]; dtrans.Add(a); if (newset.Get(endNode.Pos)) { a[symbols.Count] = 1; // accepting } } else { transitionTo = (int)lookup; } // set the transition for the symbol t[sym] = transitionTo; } state++; } nodeTable = null; }
private int[][] BuildTransitionTable(BitSet firstpos, BitSet[] followpos, int endMarkerPos) { int count = this.positions.Count; int num2 = 0x2000 / count; int index = this.symbols.Count; ArrayList list = new ArrayList(); Hashtable hashtable = new Hashtable(); hashtable.Add(new BitSet(count), -1); Queue queue = new Queue(); int num4 = 0; queue.Enqueue(firstpos); hashtable.Add(firstpos, 0); list.Add(new int[index + 1]); while (queue.Count > 0) { BitSet set = (BitSet) queue.Dequeue(); int[] numArray = (int[]) list[num4]; if (set[endMarkerPos]) { numArray[index] = 1; } for (int i = 0; i < index; i++) { BitSet set2 = new BitSet(count); for (int j = set.NextSet(-1); j != -1; j = set.NextSet(j)) { if (i == this.positions[j].symbol) { set2.Or(followpos[j]); } } object obj2 = hashtable[set2]; if (obj2 != null) { numArray[i] = (int) obj2; } else { int num7 = hashtable.Count - 1; if (num7 >= num2) { return null; } queue.Enqueue(set2); hashtable.Add(set2, num7); list.Add(new int[index + 1]); numArray[i] = num7; } } num4++; } return (int[][]) list.ToArray(typeof(int[])); }
public override void ConstructPos(BitSet firstpos, BitSet lastpos, BitSet[] followpos) { LeftChild.ConstructPos(firstpos, lastpos, followpos); BitSet firstposRight = new BitSet(firstpos.Count); BitSet lastposRight = new BitSet(lastpos.Count); RightChild.ConstructPos(firstposRight, lastposRight, followpos); firstpos.Or(firstposRight); lastpos.Or(lastposRight); }
public override void ConstructPos(BitSet firstpos, BitSet lastpos, BitSet[] followpos) { BitSet firstPosTemp = new BitSet(firstpos.Count); BitSet lastPosTemp = new BitSet(lastpos.Count); SyntaxTreeNode n; ChoiceNode this_ = this; do { ConstructChildPos(this_.RightChild, firstPosTemp, lastPosTemp, followpos); n = this_.LeftChild; this_ = n as ChoiceNode; } while (this_ != null); n.ConstructPos(firstpos, lastpos, followpos); firstpos.Or(firstPosTemp); lastpos.Or(lastPosTemp); }
public override ArrayList ExpectedParticles(ValidationState context, bool isRequiredOnly, XmlSchemaSet schemaSet) { ArrayList particles = new ArrayList(); BitSet expectedPos; if (context.RunningPositions != null) { List<RangePositionInfo> runningPositions = context.RunningPositions; expectedPos = new BitSet(positions.Count); for (int i = context.CurrentState.NumberOfRunningPos - 1; i >=0; i--) { Debug.Assert(runningPositions[i].curpos != null); expectedPos.Or(runningPositions[i].curpos); } for (int pos = expectedPos.NextSet(-1); pos != -1; pos = expectedPos.NextSet(pos)) { int symbol = positions[pos].symbol; if (symbol >= 0) { //non range nodes XmlSchemaParticle p = positions[pos].particle as XmlSchemaParticle; if (p == null) { continue; } AddParticleToExpected(p, schemaSet, particles); } } } return particles; }
/// <summary> /// Algorithm 3.5 Construction of a DFA from a regular expression /// </summary> private int[][] BuildTransitionTable(BitSet firstpos, BitSet[] followpos, int endMarkerPos) { const int TimeConstant = 8192; //(MaxStates * MaxPositions should be a constant) int positionsCount = positions.Count; int MaxStatesCount = TimeConstant / positionsCount; int symbolsCount = symbols.Count; // transition table (Dtran in the book) ArrayList transitionTable = new ArrayList(); // state lookup table (Dstate in the book) Hashtable stateTable = new Hashtable(); // Add empty set that would signal an error stateTable.Add(new BitSet(positionsCount), -1); // lists unmarked states Queue unmarked = new Queue(); // initially, the only unmarked state in Dstates is firstpo(root) int state = 0; unmarked.Enqueue(firstpos); stateTable.Add(firstpos, 0); transitionTable.Add(new int[symbolsCount + 1]); // while there is an umnarked state T in Dstates do begin while (unmarked.Count > 0) { BitSet statePosSet = (BitSet)unmarked.Dequeue(); // all positions that constitute DFA state Debug.Assert(state == (int)stateTable[statePosSet]); // just make sure that statePosSet is for correct state int[] transition = (int[])transitionTable[state]; if (statePosSet[endMarkerPos]) { transition[symbolsCount] = 1; // accepting } // for each input symbol a do begin for (int symbol = 0; symbol < symbolsCount; symbol ++) { // let U be the set of positions that are in followpos(p) // for some position p in T // such that the symbol at position p is a BitSet newset = new BitSet(positionsCount); for (int pos = statePosSet.NextSet(-1); pos != -1; pos = statePosSet.NextSet(pos)) { if (symbol == positions[pos].symbol) { newset.Or(followpos[pos]); } } // if U is not empty and is not in Dstates then // add U as an unmarked state to Dstates object lookup = stateTable[newset]; if (lookup != null) { transition[symbol] = (int)lookup; } else { // construct new state int newState = stateTable.Count - 1; if (newState >= MaxStatesCount) { return null; } unmarked.Enqueue(newset); stateTable.Add(newset, newState); transitionTable.Add(new int[symbolsCount + 1]); transition[symbol] = newState; } } state++; } // now convert transition table to array return (int[][])transitionTable.ToArray(typeof(int[])); }
public override ArrayList ExpectedElements(ValidationState context, bool isRequiredOnly) { ArrayList names = null; BitSet expectedPos; if (context.RunningPositions != null) { List<RangePositionInfo> runningPositions = context.RunningPositions; expectedPos = new BitSet(positions.Count); for (int i = context.CurrentState.NumberOfRunningPos - 1; i >=0; i--) { Debug.Assert(runningPositions[i].curpos != null); expectedPos.Or(runningPositions[i].curpos); } for (int pos = expectedPos.NextSet(-1); pos != -1; pos = expectedPos.NextSet(pos)) { if (names == null) { names = new ArrayList(); } int symbol = positions[pos].symbol; if (symbol >= 0) { //non range nodes XmlSchemaParticle p = positions[pos].particle as XmlSchemaParticle; if (p == null) { string s = symbols.NameOf(positions[pos].symbol); if (s.Length != 0) { names.Add(s); } } else { string s = p.NameString; if (!names.Contains(s)) { names.Add(s); } } } } } return names; }
private void Join(ArrayList terminalNodes, BitSet lset, NamespaceList lany, BitSet rset, NamespaceList rany, out BitSet set, out NamespaceList any) { if (lset != null) { if (rset != null) { set = lset.Clone(); set.And(rset); if (!set.IsEmpty) { goto error; } set.Or(lset); set.Or(rset); } else { set = lset; } } else { set = rset; } if (lany != null) { if (rany != null) { NamespaceList list = NamespaceList.Intersection(rany, lany); if (list == null || list.IsEmpty()) { any = NamespaceList.Union(rany, lany); } else { goto error; } } else { any = lany; } } else { any = rany; } if (any != null && set != null) { for (int i = 0; i < set.Count; i++) { if (set.Get(i) && any.Allows(((TerminalNode)terminalNodes[i]).Name)) { goto error; } } } return; error: throw new XmlSchemaException(Res.Sch_NonDeterministicAny); }
private static void ConstructChildPos(SyntaxTreeNode child, BitSet firstpos, BitSet lastpos, BitSet[] followpos) { BitSet firstPosTemp = new BitSet(firstpos.Count); BitSet lastPosTemp = new BitSet(lastpos.Count); child.ConstructPos(firstPosTemp, lastPosTemp, followpos); firstpos.Or(firstPosTemp); lastpos.Or(lastPosTemp); }
private BitSet[] CalculateTotalFollowposForRangeNodes(BitSet firstpos, BitSet[] followpos, out BitSet posWithRangeTerminals) { int count = this.positions.Count; posWithRangeTerminals = new BitSet(count); BitSet[] setArray = new BitSet[this.minMaxNodesCount]; int index = 0; for (int i = count - 1; i >= 0; i--) { Position position = this.positions[i]; if (position.symbol == -2) { LeafRangeNode particle = position.particle as LeafRangeNode; BitSet set = new BitSet(count); set.Clear(); set.Or(followpos[i]); if (particle.Min != particle.Max) { set.Or(particle.NextIteration); } for (int j = set.NextSet(-1); j != -1; j = set.NextSet(j)) { if (j > i) { Position position2 = this.positions[j]; if (position2.symbol == -2) { LeafRangeNode node2 = position2.particle as LeafRangeNode; set.Or(setArray[node2.Pos]); } } } setArray[index] = set; particle.Pos = index++; posWithRangeTerminals.Set(i); } } return setArray; }
private BitSet GetApplicableMinMaxFollowPos(BitSet curpos, BitSet posWithRangeTerminals, BitSet[] minmaxFollowPos) { if (curpos.Intersects(posWithRangeTerminals)) { BitSet set = new BitSet(this.positions.Count); set.Or(curpos); set.And(posWithRangeTerminals); curpos = curpos.Clone(); for (int i = set.NextSet(-1); i != -1; i = set.NextSet(i)) { LeafRangeNode particle = this.positions[i].particle as LeafRangeNode; curpos.Or(minmaxFollowPos[particle.Pos]); } } return curpos; }
public override void ConstructPos(BitSet firstpos, BitSet lastpos, BitSet[] followpos) { BitSet lastposLeft = new BitSet(lastpos.Count); LeftChild.ConstructPos(firstpos, lastposLeft, followpos); BitSet firstposRight = new BitSet(firstpos.Count); RightChild.ConstructPos(firstposRight, lastpos, followpos); if (LeftChild.IsNullable && !RightChild.IsRangeNode) { firstpos.Or(firstposRight); } if (RightChild.IsNullable) { lastpos.Or(lastposLeft); } for (int pos = lastposLeft.NextSet(-1); pos != -1; pos = lastposLeft.NextSet(pos)) { followpos[pos].Or(firstposRight); } if (RightChild.IsRangeNode) { //firstpos is leftchild.firstpos as the or with firstposRight has not been done as it is a rangenode ((LeafRangeNode)RightChild).NextIteration = firstpos.Clone(); } }