package trees

import (
	
	

	
	
	

	
	
)

const (
	siblingSpacing   = 50.0
	directionPenalty = 2 * layoutgraph.TreeParentSpacing
)

// get a map from depth level 0-n to tree nodes at that depth
// .                     ┌───┐
// . L 0                 │   │
// .                     └───┘
// .        ┌───┐        ┌───┐        ┌───┐
// . L 1    │   │        │   │        │   │
// .        └───┘        └───┘        └───┘
// .     ┌───┐ ┌───┐  ┌───┐ ┌───┐  ┌───┐ ┌───┐
// . L 2 │   │ │   │  │   │ │   │  │   │ │   │
// .     └───┘ └───┘  └───┘ └───┘  └───┘ └───┘
func levelsByDepth( *layoutgraph.Tree,  *limits.WorkGuard) (map[int][]*layoutgraph.Tree, error) {
	if  == nil {
		return nil, treePreprocessBadState("tree placement cannot traverse a nil tree")
	}
	type  struct {
		  *layoutgraph.Tree
		 int
	}
	 := []{{: }}
	 := make(map[*layoutgraph.Tree]struct{})
	 := make(map[int][]*layoutgraph.Tree)
	for  := 0;  < len(); ++ {
		if  := .Step();  != nil {
			return nil, 
		}
		 := []
		if . == nil || ..Node == nil {
			return nil, treePreprocessBadState("tree placement encountered an incomplete tree")
		}
		if ,  := [.];  {
			return nil, treePreprocessBadState("tree placement encountered a repeated tree node")
		}
		[.] = struct{}{}
		[.] = append([.], .)
		for ,  := range ..Children {
			if  := .Step();  != nil {
				return nil, 
			}
			 = append(, {: , : . + 1})
		}
	}
	return , nil
}

func shiftSubtreeHorizontally( *layoutgraph.Tree,  float64,  *limits.WorkGuard) error {
	return offsetSubtree(, , 0, )
}

func spacingToChildren( *layoutgraph.Tree,  *limits.WorkGuard) (float64, error) {
	 := 0.0
	for ,  := range .Children {
		if  := .Step();  != nil {
			return 0, 
		}
		if  == nil || .SentinelEdge == nil {
			return 0, treePreprocessBadState("tree placement encountered an incomplete child edge")
		}
		 := float64(.SentinelEdge.MinHeight)
		if .Orientation == geo.Left || .Orientation == geo.Right {
			 = float64(.SentinelEdge.MinWidth)
		}
		 = math.Max(, )
	}
	if  == 0 {
		return layoutgraph.TreeParentSpacing, nil
	}
	 :=  + 2*layoutgraph.MinArrowheadClearance
	if len(.Children) == 1 {
		//  ┌───┐
		//  │   │ We want enough space to place the label at the X
		//  └─┬─┘  ┬ MinArrowheadClearance
		//    │    ┼
		//   X│    │ maxLabelSize
		//    │    ┼
		//  ┌─▼─┐  ┴ MinArrowheadClearance
		//  │   │
		//  └───┘
		return math.Max(layoutgraph.TreeParentSpacing, ), nil
	}
	//         ┌───┐
	//         │   │       We want enough space to place the labels at the X positions
	//         └─┬─┘        ┬
	//           │          │ TreeParentSpacing/2
	//    ┌──────┴──────┐   ┼
	//    │             │   │
	//   X│             │X  │ labelSpacingWithArrowheads
	//    │             │   │
	//  ┌─▼─┐         ┌─▼─┐ ┴
	//  │   │         │   │
	//  └───┘         └───┘
	return layoutgraph.TreeParentSpacing/2 + math.Max(layoutgraph.TreeParentSpacing/2, ), nil
}

func layoutTree( *layoutgraph.Tree,  *limits.WorkGuard) error {
	,  := levelsByDepth(, )
	if  != nil {
		return 
	}

	// 1. The level height is the tallest node's at each level
	 := make(map[int]float64)
	for  := 0;  < len(); ++ {
		 := 0.0
		for ,  := range [] {
			if  := .Step();  != nil {
				return 
			}
			 = math.Max(, .Node.Height)
		}
		[] = 
	}
	// 1.1. Edge labels may require additional spacing, so spacing for the level is based on the largest label
	 := make(map[int]float64)
	for  := 0;  < len()-1; ++ {
		for ,  := range [] {
			if  := .Step();  != nil {
				return 
			}
			,  := spacingToChildren(, )
			if  != nil {
				return 
			}
			[+1] = math.Max([+1], )
		}
	}

	//   ┌───┐        ┌─────┐              ┌──┐ ┌───┐
	//   │   │ ┌───┐  │     │ ┌─────────┐  │  │ │   │
	// ------------------------------------------------
	//   │   │ └───┘  │     │ └─────────┘  │  │ │   │
	//   └───┘        └─────┘              └──┘ └───┘
	// 2. On each level, center all nodes to the center y value for that level
	 := 0.0
	for  := 1;  < len(); ++ {
		 :=  + []
		for ,  := range [] {
			if  := .Step();  != nil {
				return 
			}
			 := math.Round(([] - .Node.Height) / 2)
			if  := moveTreeNodeAbsWithChildren(.Node, .Node.TopLeft.X, +, );  != nil {
				return 
			}
		}
		 =  + []
	}

	// 3. Position all level nodes x values on each level, going bottom up by level
	for  := len() - 1;  > 0; -- {
		// nextPosition moves along the x axis as we position each level node on this level
		 := 0.0
		for ,  := range [] {
			if  := .Step();  != nil {
				return 
			}
			if len(.Children) == 0 {
				// 3a. Simply set position according to nextPosition value
				if  := moveTreeNodeAbsWithChildren(.Node, , .Node.TopLeft.Y, );  != nil {
					return 
				}
			} else {
				 := len([+1])
				for  :=  - 1;  >= 0; -- {
					if  := .Step();  != nil {
						return 
					}
					if [+1][].Parent ==  {
						 = 
						break
					}
				}
				 := func( float64) error {
					for  :=  + 1;  < len([+1]); ++ {
						if  := .Step();  != nil {
							return 
						}
						if  := shiftSubtreeHorizontally([+1][], , );  != nil {
							return 
						}
					}
					return nil
				}

				// 3b 1. Space children evenly on the level below
				,  := totalChildrenSpacing(, )
				if  != nil {
					return 
				}
				if  := spaceChildrenEvenly(, );  != nil {
					return 
				}
				,  := totalChildrenSpacing(, )
				if  != nil {
					return 
				}
				 :=  - 
				// 3b 1a. if this shifts the children we also need to shift their subsequent level nodes
				if  > 0 {
					if  := ();  != nil {
						return 
					}
				}
				// 3b 2. Center over children
				,  := childrenCenterX(, )
				if  != nil {
					return 
				}
				if  := moveTreeNodeAbsWithChildren(.Node, math.Round(-.Node.Width/2), .Node.TopLeft.Y, );  != nil {
					return 
				}

				// 3b 3. if after centering, this node's position is less than the desired spacing,
				// shift its whole subtree to reach the desired spacing (keeping the centering intact)
				 :=  - .Node.TopLeft.X
				if  > 0 {
					if  := shiftSubtreeHorizontally(, , );  != nil {
						return 
					}
					if  := ();  != nil {
						return 
					}
				}
			}

			// 3c. the next position on this level is siblingSpacing past the end of this level node
			 = .Node.TopLeft.X + .Node.Width + siblingSpacing
		}
	}
	return .Finish()
}

func validateBottomOrientation( *layoutgraph.Tree,  *limits.WorkGuard) error {
	 := []*layoutgraph.Tree{}
	 := make(map[*layoutgraph.Tree]struct{})
	for len() > 0 {
		if  := .Step();  != nil {
			return 
		}
		 := [len()-1]
		 = [:len()-1]
		if  == nil || .Node == nil || .Node.TopLeft == nil {
			return treePreprocessBadState("tree placement encountered an incomplete tree")
		}
		if ,  := [];  {
			return treePreprocessBadState("tree placement encountered a repeated tree node")
		}
		[] = struct{}{}
		if .Parent != nil {
			if .Parent.Node == nil || .Parent.Node.TopLeft == nil {
				return treePreprocessBadState("tree placement encountered an incomplete parent")
			}
			if .Node.TopLeft.Y < .Parent.Node.TopLeft.Y+.Parent.Node.Height {
				return invariant.Errorf("tree node %d is not in Bottom orientation", .Node.ID)
			}
		}
		for ,  := range slices.Backward(.Children) {
			if  := .Step();  != nil {
				return 
			}
			 = append(, )
		}
	}
	return .Check()
}

func positionEdgeLabels( *layoutgraph.Tree,  *limits.WorkGuard) error {
	if  == nil {
		return treePreprocessBadState("tree placement cannot label a nil tree")
	}
	type  struct {
		 *layoutgraph.Tree
		 bool
	}
	 := []{{: }}
	 := make(map[*layoutgraph.Tree]struct{})
	for len() > 0 {
		if  := .Step();  != nil {
			return 
		}
		 := [len()-1]
		 = [:len()-1]
		 := .
		if  == nil || .Node == nil {
			return treePreprocessBadState("tree placement encountered an incomplete label tree")
		}
		if !. {
			if ,  := [];  {
				return treePreprocessBadState("tree placement encountered a repeated tree node")
			}
			[] = struct{}{}
			 = append(, {: , : true})
			for ,  := range slices.Backward(.Children) {
				if  := .Step();  != nil {
					return 
				}
				 = append(, {: })
			}
			continue
		}

		 := .SentinelEdge
		if  == nil {
			return treePreprocessBadState("tree node %d has no sentinel edge for label placement", .Node.ID)
		}
		if .Label == nil {
			continue
		}
		 := float64(.MinHeight)
		if .Orientation.IsHorizontal() {
			 = float64(.MinWidth)
		}
		if  != 0 {
			if .Parent == nil || .Parent.Node == nil {
				return treePreprocessBadState("tree node %d has no parent for label placement", .Node.ID)
			}
			if len(.Parent.Children) == 1 {
				.Label.Position = label.UnlockedMiddle
				.LabelPercentage = 0.5
			} else {
				//         ┌───┐
				//  parent │   │       We want to place the labels at the X positions
				//         └─┬─┘        ┬    ┬
				//           │          │    │ TreeParentSpacing/2
				//    ┌──────┴──────┐   │    ┼
				//    │      .      │   │dy  │
				//   X│      .      │X  │    │ childSegmentLength
				//    │      .      │   │    │
				//  ┌─▼─┐    .    ┌─▼─┐ ┴    ┴
				//  │   │ child   │   │ child
				//  └───┘    .    └───┘
				//           ├──────┤
				//              dx
				 := .Node
				 := .Parent.Node
				 := .Center().X - .Center().X
				 := .TopLeft.Y - (.TopLeft.Y + .Height)
				 := math.Abs() + 
				 :=  - layoutgraph.TreeParentSpacing/2

				// LabelPercentage = distance from edge.From along edge / total edge distance
				 :=  / 2
				 := .From == 
				if ! {
					 =  - /2
				}
				.LabelPercentage =  / 
				// if the child is to the left, to be on the outside we want the label on the relative bottom position
				if  < 0 {
					.Label.Position = label.UnlockedBottom
				} else {
					.Label.Position = label.UnlockedTop
				}
				// if the edge is in the other direction we need to mirror to get the same position
				if  {
					.Label.Position = .Label.Position.Mirrored()
				}
				if .Orientation.IsHorizontal() {
					// mirroring is needed due to the effects of invertOrientationToBottom on a horizontal orientation
					.Label.Position = .Label.Position.Mirrored()
				}
			}
		}
		if  := .Finish();  != nil {
			return 
		}
	}
	return nil
}

// We compute the children's center by averaging the their centers
func childrenCenterX( *layoutgraph.Tree,  *limits.WorkGuard) (float64, error) {
	if len(.Children) == 0 {
		return 0, treePreprocessBadState("tree placement cannot center a leaf")
	}
	 := 0.0
	for ,  := range .Children {
		if  := .Step();  != nil {
			return 0, 
		}
		if  == nil || .Node == nil || .Node.TopLeft == nil {
			return 0, treePreprocessBadState("tree placement encountered an incomplete child")
		}
		 += .Node.TopLeft.X + .Node.Width/2
	}
	// note: assumes this is only called on nodes with children
	 /= float64(len(.Children))
	return , nil
}

func spaceChildrenEvenly( *layoutgraph.Tree,  *limits.WorkGuard) error {
	 := siblingSpacing

	 := make([]float64, 1, len(.Children))
	// 1. Determine the maximum spacing between siblings
	for  := 1;  < len(.Children); ++ {
		if  := .Step();  != nil {
			return 
		}
		 := .Children[].Node.TopLeft.X - (.Children[-1].Node.TopLeft.X + .Children[-1].Node.Width)
		 = math.Max(, )
		 = append(, )
	}

	// 1a. Check that spacing evenly doesn't require too much space
	for  := 1;  < len(.Children); ++ {
		if  := .Step();  != nil {
			return 
		}
		 :=  - []
		if  == 0 {
			continue
		}
		,  := spacingBefore(, , )
		if  != nil {
			return 
		}
		if + > 10*siblingSpacing {
			// spacing evenly would introduce too much excess space, so just keep the current spacing as-is
			return nil
		}
		// the next child will have less space after shifting
		if +1 < len(.Children) {
			[+1] -= 
		}
	}

	// 2. Space all siblings with the maximum spacing
	for  := 1;  < len(.Children); ++ {
		if  := .Step();  != nil {
			return 
		}
		 :=  - []
		if  > 0 {
			if  := shiftSubtreeHorizontally(.Children[], , );  != nil {
				return 
			}
		}
	}
	return nil
}

func totalChildrenSpacing( *layoutgraph.Tree,  *limits.WorkGuard) (float64, error) {
	 := 0.0
	for  := 1;  < len(.Children); ++ {
		if  := .Step();  != nil {
			return 0, 
		}
		 += .Children[].Node.TopLeft.X - (.Children[-1].Node.TopLeft.X + .Children[-1].Node.Width)
	}
	return , nil
}

func spacingBefore( *layoutgraph.Tree,  int,  *limits.WorkGuard) (float64, error) {
	// returns the minimum space between child at i and i-1 including all descendant levels
	// .        ┌───┐            0, 1
	// .        │ t │ Children: [A, X]
	// .        └▲─▲┘
	// .    ┌────┘ └────┐
	// .  ┌─┴─┐   ┌─────┴─────┐
	// .  │ A │   │     X     │
	// .  └─▲─┘   └─────▲─────┘
	// .    │ ├─3─┤     │
	// . ┌──┴──┐      ┌─┴─┐
	// . │  B  │      │ Y │
	// . └─────┘      └───┘
	// .       ├───6──┤      return min(3,6)
	,  := levelRights(.Children[-1], )
	if  != nil {
		return 0, 
	}
	,  := levelLefts(.Children[], )
	if  != nil {
		return 0, 
	}

	 := [0] - [0]
	for  := 1;  < len() &&  < len(); ++ {
		if  := .Step();  != nil {
			return 0, 
		}
		 = math.Min(, []-[])
	}
	return , nil
}

// returns the leftmost positions for each level of descendants from this node
func levelLefts( *layoutgraph.Tree,  *limits.WorkGuard) ([]float64, error) {
	,  := levelsByDepth(, )
	if  != nil {
		return nil, 
	}
	 := make([]float64, len())
	for  := 0;  < len(); ++ {
		if len([]) == 0 || [][0].Node.TopLeft == nil {
			return nil, treePreprocessBadState("tree placement encountered an incomplete level")
		}
		if  := .Step();  != nil {
			return nil, 
		}
		[] = [][0].Node.TopLeft.X
	}
	return , nil
}

func levelRights( *layoutgraph.Tree,  *limits.WorkGuard) ([]float64, error) {
	,  := levelsByDepth(, )
	if  != nil {
		return nil, 
	}
	 := make([]float64, len())
	for  := 0;  < len(); ++ {
		if len([]) == 0 {
			return nil, treePreprocessBadState("tree placement encountered an empty level")
		}
		 := [][len([])-1]
		if .Node.TopLeft == nil {
			return nil, treePreprocessBadState("tree placement encountered an incomplete level")
		}
		if  := .Step();  != nil {
			return nil, 
		}
		[] = .Node.TopLeft.X + .Node.Width
	}
	return , nil
}

func centerAlignChildren( *layoutgraph.Tree,  *limits.WorkGuard) error {
	// 1. the x axis offset is computed so the root's children are centered with the root.
	// The center x value of the children should be equal to the root center x when aligned,
	// so we check how much to move everything in order to correct that.
	,  := childrenCenterX(, )
	if  != nil {
		return 
	}
	 := math.Round((.Node.TopLeft.X + .Node.Width/2) - )

	// 2. shift all children to be in alignment
	for ,  := range .Children {
		if  := .Step();  != nil {
			return 
		}
		if  := offsetSubtree(, , 0, );  != nil {
			return 
		}
	}
	return .Finish()
}

// treePlacementDescendants is the guarded equivalent of
// Graph.AllDescendantNodes for tree-placement movement. Push order mirrors
// that helper so both traversals produce the same mutation order.
func treePlacementDescendants( *layoutgraph.Node,  *limits.WorkGuard) ([]*layoutgraph.Node, error) {
	if  == nil || .Graph == nil {
		return nil, treePreprocessBadState("tree placement cannot move a node without graph ownership")
	}
	 := .Graph
	 := map[*layoutgraph.Node]struct{}{: {}}
	 := make([]*layoutgraph.Node, 0)
	 := func( *layoutgraph.Node) error {
		if  == nil {
			return nil
		}
		if  := .Sequences[];  != nil {
			for ,  := range slices.Backward(.Nodes) {
				if  := .Step();  != nil {
					return 
				}
				 = append(, )
			}
		}
		if .IsClusterVessel() {
			if  := .Clusters[];  != nil {
				for ,  := range slices.Backward(.Nodes) {
					if  := .Step();  != nil {
						return 
					}
					 = append(, )
				}
			}
		}
		if .IsContainer() {
			 := .Containers[]
			for ,  := range slices.Backward() {
				if  := .Step();  != nil {
					return 
				}
				 = append(, )
			}
		}
		return nil
	}
	if  := ();  != nil {
		return nil, 
	}
	 := make([]*layoutgraph.Node, 0, len())
	for len() > 0 {
		if  := .Step();  != nil {
			return nil, 
		}
		 := [len()-1]
		 = [:len()-1]
		if  == nil {
			return nil, treePreprocessBadState("tree placement encountered a nil graph descendant")
		}
		if ,  := [];  {
			continue
		}
		[] = struct{}{}
		 = append(, )
		if  := ();  != nil {
			return nil, 
		}
	}
	return , nil
}

func moveTreeNodeWithChildren( *layoutgraph.Node, ,  float64,  *limits.WorkGuard) error {
	if  == nil || .TopLeft == nil {
		return treePreprocessBadState("tree placement cannot move an incomplete node")
	}
	if  == 0 &&  == 0 {
		return .Check()
	}
	,  := treePlacementDescendants(, )
	if  != nil {
		return 
	}
	if  := .Step();  != nil {
		return 
	}
	.Translate(, )
	if  := .Finish();  != nil {
		return 
	}
	for ,  := range  {
		if  := .Step();  != nil {
			return 
		}
		if .TopLeft == nil {
			return treePreprocessBadState("tree placement encountered a descendant without a position")
		}
		.Translate(, )
		if  := .Finish();  != nil {
			return 
		}
	}
	return nil
}

func moveTreeNodeAbsWithChildren( *layoutgraph.Node, ,  float64,  *limits.WorkGuard) error {
	if  == nil || .TopLeft == nil {
		return treePreprocessBadState("tree placement cannot move an incomplete node")
	}
	if .TopLeft.X ==  && .TopLeft.Y ==  {
		return .Check()
	}
	return moveTreeNodeWithChildren(, -.TopLeft.X, -.TopLeft.Y, )
}

func offsetSubtree( *layoutgraph.Tree, ,  float64,  *limits.WorkGuard) error {
	 := []*layoutgraph.Tree{}
	 := make(map[*layoutgraph.Tree]struct{})
	for len() > 0 {
		if  := .Step();  != nil {
			return 
		}
		 := [len()-1]
		 = [:len()-1]
		if  == nil || .Node == nil {
			return treePreprocessBadState("tree placement encountered an incomplete tree")
		}
		if ,  := [];  {
			return treePreprocessBadState("tree placement encountered a repeated tree node")
		}
		[] = struct{}{}
		if  := moveTreeNodeWithChildren(.Node, , , );  != nil {
			return 
		}
		for ,  := range slices.Backward(.Children) {
			if  := .Step();  != nil {
				return 
			}
			 = append(, )
		}
	}
	return .Finish()
}

// .     ┌─────────┐                   ┌──────────┐
// .     │ a       │                 ┌─┤ c        │
// .     └────┬────┘         ┌─────┐ │ └──────────┘
// .   ┌──────┴──────┐       │  a  │ │
// . ┌─┴──┐       ┌──┴─┐     │     ├─┤
// . │ b  │       │ c  │ <=> │     │ │
// . │    │       │    │     └─────┘ │ ┌──────────┐
// . │    │       │    │             └─┤ b        │
// . └────┘       └────┘               └──────────┘
// this swaps the x and y coordinates as well as the width and height of all nodes in the tree
// this is so that we can layout a tree to the right with the same code to lay it out to the bottom
// by swapping dimensions before and after
func swapDimensions( *layoutgraph.Tree,  *limits.WorkGuard) error {
	 := []*layoutgraph.Tree{}
	 := make(map[*layoutgraph.Tree]struct{})
	for len() > 0 {
		if  := .Step();  != nil {
			return 
		}
		 := [len()-1]
		 = [:len()-1]
		if  == nil || .Node == nil || .Node.TopLeft == nil {
			return treePreprocessBadState("tree placement encountered an incomplete tree")
		}
		if ,  := [];  {
			return treePreprocessBadState("tree placement encountered a repeated tree node")
		}
		[] = struct{}{}
		if  := moveTreeNodeAbsWithChildren(.Node, .Node.TopLeft.Y, .Node.TopLeft.X, );  != nil {
			return 
		}
		.Node.Width, .Node.Height = .Node.Height, .Node.Width
		if  := .Finish();  != nil {
			return 
		}
		for ,  := range slices.Backward(.Children) {
			if  := .Step();  != nil {
				return 
			}
			 = append(, )
		}
	}
	return nil
}

// .                       |
// .  ┌────┐       ┌────┐  |
// .  │ c  │       │ b  │  |
// .  │    │       │    │  |
// .  │    │       │    │  |
// .  └──┬─┘       └─┬──┘  |
// .     └─────┬─────┘     |
// .      ┌────┴────┐      |
// .      │    a    │      |
// .      └─────────┘      |
// . ----------------------|-----------------------
// .                       |      ┌─────────┐
// .          ^            |      │    a    │
// .          |            |      └────┬────┘
// .        flips ->       |    ┌──────┴──────┐
// .                       |  ┌─┴──┐       ┌──┴─┐
// .                       |  │ b  │       │ c  │
// .                       |  │    │       │    │
// .                       |  │    │       │    │
// .                       |  └────┘       └────┘
// this flips all nodes in the tree such that the top left is the mirror topleft accounting for the width and height
func flip( *layoutgraph.Tree,  *limits.WorkGuard) error {
	 := []*layoutgraph.Tree{}
	 := make(map[*layoutgraph.Tree]struct{})
	for len() > 0 {
		if  := .Step();  != nil {
			return 
		}
		 := [len()-1]
		 = [:len()-1]
		if  == nil || .Node == nil || .Node.TopLeft == nil {
			return treePreprocessBadState("tree placement encountered an incomplete tree")
		}
		if ,  := [];  {
			return treePreprocessBadState("tree placement encountered a repeated tree node")
		}
		[] = struct{}{}
		if  := moveTreeNodeAbsWithChildren(
			.Node,
			-(.Node.TopLeft.X + .Node.Width),
			-(.Node.TopLeft.Y + .Node.Height),
			,
		);  != nil {
			return 
		}
		for ,  := range slices.Backward(.Children) {
			if  := .Step();  != nil {
				return 
			}
			 = append(, )
		}
	}
	return .Finish()
}

func setOrientation( *layoutgraph.Tree,  geo.Orientation,  *limits.WorkGuard) error {
	 := []*layoutgraph.Tree{}
	 := make(map[*layoutgraph.Tree]struct{})
	for len() > 0 {
		if  := .Step();  != nil {
			return 
		}
		 := [len()-1]
		 = [:len()-1]
		if  == nil || .Node == nil {
			return treePreprocessBadState("tree placement encountered an incomplete tree")
		}
		if ,  := [];  {
			return treePreprocessBadState("tree placement encountered a repeated tree node")
		}
		[] = struct{}{}
		.Orientation = 
		if  := .Finish();  != nil {
			return 
		}
		for ,  := range slices.Backward(.Children) {
			if  := .Step();  != nil {
				return 
			}
			 = append(, )
		}
	}
	return nil
}