let rearrange_treeOr tree gr edge_id cycle node=
    match gr with
      Right _ -> (tree,[])
    | Left graph ->
      let edge = findedge edge_id tree
      in let (c,t,p) = edge.edge
      in match edge.edgeway with
        Normal -> (match node.nname with
            And -> rearrange_treeMUX tree gr edge_id cycle
          | LongOr -> rearrange_treeMUX tree gr edge_id cycle
          | Or -> rearrange_treeFuse tree gr edge_id cycle
          | Id -> let next_node = 
                    let rec ne cyc =
                      match cyc with
                        x::y::tail -> if y == t then x else ne (y::tail)
                      | _ -> NewName.invalid_id
                    in if (List.hd cycle) == t then (List.hd (List.rev cycle)) else ne cycle
                  in let _ = report2 "Or yle Id"
                  in let next_edge = find_edge_id t next_node tree
                  in let gra = graph_from_tree tree
                  in let node = DG.findnode next_node gra
                  in let desc = nodedesc node.nname
                  in if ns_inclvalue desc.outputtype Boolean 
                    then rearrange_treeId tree (GrbTrDtoCOverId.Tr.umake gra (Right next_edge)) next_edge cycle c.sourceid
                    else rearrange_treeId tree (GrbTrPassOverId.Tr.umake gra (Right next_edge)) next_edge cycle c.sourceid
          | _ ->  let op_node = findnode t tree
                  in let op_gnode = DG.findnode t graph
                  in let _ = report2 "Or over OP node normal" 
                  in let op_new_out = DG.nodefoldoutedges graph (fun y a -> y::a) op_gnode []
                  in let op_old_out = edgefilter tree (fun _ x -> let (cx,_,_) = x.edge in cx.sourceid==t)
                  in let (cn,id_node,pn) = List.hd op_new_out
                  in let id_node_out = DG.nodefoldoutedges graph (fun y a -> y::a) id_node []
                  in let op_changed = IdtMap.add t {op_node with children = [id_node.id]} (IdtMap.remove t tree.treeNodes)
                  in let tree2 = 
                      {tree with 
                      treeNodes = IdtMap.add id_node.id {node = id_node; allDone = true; number = op_node.number; children = op_node.children} op_changed; 
                      treeEdges = IdtMap.add cn.nameforudg {edge = (cn,id_node.id,pn); edgeway = Cross; used = true} tree.treeEdges}
                  in let rec add_id_outes edge_list tr= 
                    match edge_list with
                      x::tail -> let (cx,tx,px) = x.edge
                                 in let (cn,tn,pn) = List.hd (List.filter (fun (_,tt,_) -> tt.id==tx) id_node_out)
                                 in let edges = 
                                    IdtMap.add cn.nameforudg {x with edge = (cn,tn.id,pn)} (IdtMap.remove cx.nameforudg tr.treeEdges)
                                 in let t_n = findnode tx tr
                                 in let n = DG.findnode tx graph
                                 in let nodes = 
                                    IdtMap.add tx {node = n; number = t_n.number; allDone = true; children = t_n.children} (IdtMap.remove tx tr.treeNodes)
                                 in add_id_outes tail {tr with treeEdges = edges; treeNodes = nodes}
                    | _ -> tr
                  in let tree22 = add_id_outes (List.filter (fun x -> x.edgeway == Cross || x.edgeway == Forward) op_old_out) tree2
                  in let tree3 = add_id_outes (List.filter (fun x -> x.edgeway == Normal || x.edgeway == Backward) op_old_out) tree22
                  in let id_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
                  in let inp_or = List.filter (fun (cx,_,_) -> cx.sourceid != op_gnode.id) id_inp
                  in let (co,_,po) = List.hd inp_or
                  in let or_changed = if hasnode co.sourceid tree3
                    then
                      let or_node = findnode co.sourceid tree3
                      in IdtMap.add co.sourceid {or_node with children = id_node.id::or_node.children} tree3.treeNodes
                    else tree3.treeNodes
                  in let tree4 = 
                      {tree3 with 
                      treeNodes = or_changed; 
                      treeEdges = IdtMap.add co.nameforudg {edge = (co,id_node.id,po); used = true; edgeway = Normal} tree3.treeEdges}
                  in let (added_nodes,tree5) =
                    if co.sourceid == c.sourceid 
                      then ([id_node.id],tree4)
                      else let longOr = DG.findnode co.sourceid graph
                           in let (cm,_,pm) = List.hd (DG.nodefoldedges (fun y a -> y::a) longOr [])
                           in let nodes1 = 
                              IdtMap.add longOr.id {node = longOr; number = op_node.number; allDone = true; children = [id_node.id]} tree4.treeNodes
                           in let node = findnode cm.sourceid tree4
                           in let nodes = 
                              IdtMap.add cm.sourceid {node with children = longOr.id::node.children} (IdtMap.remove cm.sourceid nodes1)
                           in let edges = IdtMap.add cm.nameforudg {edge = (cm,longOr.id,pm); used = true; edgeway = Normal} tree4.treeEdges
                           in ([id_node.id;longOr.id],{tree4 with treeEdges = edges; treeNodes = nodes})
                  in let (next_edge_id,next_t) = 
                    let rec ne cyc  =
                      match cyc with
                        x::y::tail -> if x == t 
                          then let filterid = edgefilter tree5 (fun _ x1 -> let (cx,tx,_)=x1.edge in tx ==y && cx.sourceid == id_node.id && x1.edgeway == Normal)
                            in (List.hd (List.map (fun x2 -> let (cx,_,_) = x2.edge in cx.nameforudg) filterid ),y) 
                          else ne (y::tail)
                      | x::tail -> if x == t 
                        then let filterid = edgefilter tree5 (fun _ x2 -> let (cx,tx,_)=x2.edge in tx ==(List.hd (List.rev cycle)) && cx.sourceid == id_node.id && x2.edgeway == Backward)
                          in (List.hd (List.map (fun x1 -> let (cx,_,_) = x1.edge in cx.nameforudg) filterid),(List.hd (List.rev cycle))) 
                        else ne tail
                      | _ -> (NewName.invalid_id,NewName.invalid_id)
                    in ne (List.rev cycle)
                  in let rec split cyc seen =
                              match cyc with
                                x::tail -> if x == t
                                          then (List.rev seen,tail)
                                          else split tail (x::seen)
                              | _ -> ([],List.rev seen)
                  in let (f,s) = split cycle []
                  in let cyc = List.concat [f;added_nodes;s]
                  in let node = DG.findnode next_t graph
                  in let desc = nodedesc node.nname
                  in if ns_inclvalue desc.outputtype Boolean 
                    then rearrange_treeId tree5 (GrbTrDtoCOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid
                    else rearrange_treeId tree5 (GrbTrPassOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid
          )
      | Backward -> (match node.nname with
            And -> rearrange_treeMUX tree gr edge_id cycle
          | Or -> rearrange_treeFuse tree gr edge_id cycle
          | _ -> let op_gnode = DG.findnode t graph
                  in let op_node = findnode t tree
                  in let _ = report2 "Or over OP backward"
                  in let op_new_out = DG.nodefoldoutedges graph (fun y a -> y::a) op_gnode []
                  in let op_old_out = edgefilter tree (fun _ x -> let (cx,_,_) = x.edge in cx.sourceid==t)
                  in let (cn,id_node,pn) = List.hd op_new_out
                  in let id_node_out = DG.nodefoldoutedges graph (fun y a -> y::a) id_node []
                  in let op_changed = IdtMap.add t {op_node with children = [id_node.id]} (IdtMap.remove t tree.treeNodes)
                  in let tree2 = 
                      {tree with 
                      treeNodes = IdtMap.add id_node.id {node = id_node; allDone = true; number = op_node.number; children = op_node.children} op_changed; 
                      treeEdges = IdtMap.add cn.nameforudg {edge = (cn,id_node.id,pn); edgeway = Normal; used = true} tree.treeEdges}
                  in let rec add_id_outes edge_list tr= 
                    match edge_list with
                      x::tail -> let (cx,tx,px) = x.edge
                                 in let (cnn,tn,pnn) = List.hd (List.filter (fun (_,tt,_) -> tt.id==tx) id_node_out)
                                 in let edges = IdtMap.add cnn.nameforudg {x with edge = (cnn,tn.id,pnn)} (IdtMap.remove cx.nameforudg tr.treeEdges)
                                 in let t_n = findnode tx tr
                                 in let n = DG.findnode tx graph
                                 in let nodes = IdtMap.add tx {node = n; number = t_n.number; allDone = true; children = t_n.children} (IdtMap.remove tx tr.treeNodes)
                                 in add_id_outes tail {tr with treeEdges = edges; treeNodes = nodes}
                    | _ -> tr
                  in let tree3 = add_id_outes op_old_out tree2
                  in let id_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
                  in let inp_or = List.filter (fun (cx,_,_) -> cx.sourceid != op_gnode.id) id_inp
                  in let (co,_,po) = List.hd inp_or
                  in let or_changed = if hasnode co.sourceid tree3
                    then
                      let or_node = findnode co.sourceid tree3
                      in IdtMap.add co.sourceid {or_node with children = id_node.id::or_node.children} tree3.treeNodes
                    else tree3.treeNodes
                  in let tree4 = 
                      {tree3 with 
                      treeNodes = or_changed; 
                      treeEdges = IdtMap.add co.nameforudg {edge = (co,id_node.id,po); used = true; edgeway = Backward} tree3.treeEdges}
                  in let (added_nodes,tree5) =
                    if co.sourceid == c.sourceid
                      then ([],tree4)
                      else let longOr = DG.findnode co.sourceid graph
                           in let (cm,_,pm) = List.hd (DG.nodefoldedges (fun y a -> y::a) longOr [])
                           in let nodes1 = 
                              IdtMap.add longOr.id {node = longOr; number = op_node.number; allDone = true; children = [id_node.id]} tree4.treeNodes
                           in let node = findnode cm.sourceid tree4
                           in let nodes = 
                              IdtMap.add cm.sourceid {node with children = longOr.id::node.children} (IdtMap.remove cm.sourceid nodes1)
                           in let edges = IdtMap.add cm.nameforudg {edge = (cm,longOr.id,pm); used = true; edgeway = Normal} tree4.treeEdges
                           in ([longOr.id],{tree4 with treeEdges = edges; treeNodes = nodes})
                  in let (next_edge_id,next_t) = 
                    let rec ne cyc  =
                      match cyc with
                         x::y::tail -> if x == t 
                         then 
                          let filterid = edgefilter tree5 (fun _ x -> let (cx,tx,_)=x.edge in tx ==y && cx.sourceid == id_node.id && x.edgeway == Normal)
                          in (List.hd (List.map (fun x -> let (cx,_,_) = x.edge in cx.nameforudg) filterid),y) 
                         else ne (y::tail)
                      | x::tail -> if x == t 
                          then 
                            let filterid = (edgefilter tree5 (fun _ x -> let (cx,tx,_)=x.edge in tx ==(List.hd (List.rev cycle)) && cx.sourceid == id_node.id && x.edgeway == Backward))
                            in (List.hd (List.map (fun x -> let (cx,_,_) = x.edge in cx.nameforudg) filterid),(List.hd (List.rev cycle))) 
                          else ne tail
                      | _ -> (NewName.invalid_id,NewName.invalid_id)
                    in ne (List.rev cycle)
                  in let rec split cyc seen =
                              match cyc with
                                x::tail -> if x == t
                                          then (List.rev seen,tail)
                                          else split tail (x::seen)
                              | _ -> (List.rev seen,[])
                  in let (f,s) = split cycle []
                  in let cyc = List.concat [added_nodes;f;[id_node.id];s]
                  in let node = DG.findnode next_t graph
                  in let desc = nodedesc node.nname
                  in if ns_inclvalue desc.outputtype Boolean 
                    then rearrange_treeId tree5 (GrbTrDtoCOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid
                    else rearrange_treeId tree5 (GrbTrPassOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid)