let rearrange tree start cycle =
let node = findnode start tree
in
let rec delete_info tree worklist =
match worklist with
x::tail -> let x_out_edges = edgefilter tree (fun a b -> let (c,_,_)=b.edge in c.sourceid == x)
in let rec rem_edges edges (tree,worklist) =
match edges with
e::tail -> let (conn,target,port) = e.edge
in let rem = IdtMap.remove conn.nameforudg tree.treeEdges
in let added = if e.edgeway == Backward && node.number > (findnode target tree).number
then IdtMap.add conn.nameforudg {edge = (conn, target, port); edgeway = Backward; used = true} rem
else IdtMap.add conn.nameforudg {edge = (conn, target, port); edgeway = Unknown; used = false} rem
in if e.edgeway == Normal
then let rem_node = IdtMap.remove target tree.treeNodes
in let added_node = IdtMap.add target {(findnode target tree) with number = NodeNumber.invalid_num; allDone = false} rem_node
in ({tree with treeNodes = added_node; treeEdges = added}, (target::worklist))
else ({tree with treeEdges = added}, worklist)
| _ -> (tree,worklist)
in let (t,w) = rem_edges x_out_edges (tree,tail)
in delete_info t w
| _ -> tree
in
let rec add_normal tree nodes =
match nodes with
x::y::tail -> let x_node = findnode x tree
in let (f,s) = let rec split child other=
match child with
m::t -> if m == y
then (List.rev other,t)
else split t (m::other)
| _ -> (List.rev other,[])
in split x_node.children []
in let new_children = List.concat [[y];f;s]
in let tt = {tree with treeNodes = IdtMap.add x {x_node with children = new_children} (IdtMap.remove x tree.treeNodes)}
in add_normal (usedEdge (markedNode tt (findnode y tt)) (findedge (find_edge_id x y tt) tt) Normal) (y::tail)
| _ -> tree
in let a = let rec n cyc =
match cyc with
x::tail -> if x==start then [x] else x::(n tail)
| _ -> []
in n cycle
in let cycle_nodes = List.rev a
in let c = NodeNumber.get ()
in let _ = NodeNumber.refresh node.number
in let t1 = delete_info tree [start]
in let t2 = add_normal (markedNode t1 (findnode (List.hd cycle_nodes) t1)) cycle_nodes
in let result = depth t2 (List.rev cycle_nodes)
in let _ = NodeNumber.refresh c
in result