anchor.diff:  
   % @doc Write a list of of nodes to disk with corresponding parent node. Return
   %     the postion of the parent node in the file.
  --spec write_parent(Fd::file:io_device(), Nodes::[{tuple(), integer()}]) ->
  -        {ok, integer()}.
  +-spec write_parent(Fd::file:io_device(),
  +        Nodes::[{tuple(), tuple(), integer()}]) -> {ok, integer()}.
   write_parent(Fd, Nodes) ->
       ParentMbr = vtree:calc_nodes_mbr(Nodes),
       ChildrenPos = write_nodes(Fd, Nodes),
       {ok, ParentPos} = couch_file:append_term(
            Fd, {ParentMbr, #node{type=inner}, ChildrenPos}),
       {ok, ParentPos}.
  -%% @doc Write a list of MBR-and-childrenposition tuples to disk and returns
  -%%     the position in the file.
  -%-spec write_mbr_and_pos_list(Fd::file:io_device(),
  -%        MbrAndPosList::[{tuple(), integer()}]) -> {ok, integer()}.
  -%write_mbr_and_pos_list(Fd, MbrAndPosList) ->
  -%    write_mbr_and_pos_list(Fd, MbrAndPosList, #node{type=inner}).
  -%-spec write_mbr_and_pos_list(Fd::file:io_device(),
  -%        MbrAndPosList::[{tuple(), integer()}], Meta::tuple()) ->
  -%        {ok, integer()}.
  -%write_mbr_and_pos_list(Fd, MbrAndPosList, Meta) ->
  -%    Nodes = [{Mbr, Meta, Pos} || {Mbr, Pos} <- MbrAndPosList],
  -%    ParentMbr = vtree:calc_nodes_mbr(Nodes),
  -%    ChildrenPos = write_nodes(Fd, Nodes),
  -%    {ok, ParentPos} = couch_file:append_term(
  -%         Fd, {ParentMbr, #node{type=inner}, ChildrenPos}),
  -%    {ok, ParentPos}.
  -
  -
  -
  +
  +
  +% @doc Create a new root node for a list of tuples containing MBR and postion
  +% in the file. Returns the new enclosing MBR and position in the file.
  +-spec write_root(Fd::file:io_device(),
  +        MbrAndPos::[{mbr(), integer()}]) -> {ok, integer()}.
  +write_root(Fd, MbrAndPos) ->
  +    {Mbrs, PosList} = lists:unzip(MbrAndPos),
  +    ParentMbr = vtree:calc_mbr(Mbrs),
  +    {ok, ParentPos} = couch_file:append_term(
  +         Fd, {ParentMbr, #node{type=inner}, PosList}),
  +    {ParentMbr, ParentPos}.
  +
  +
  +% @doc inserts a subtree into an vtree at a specific level. Returns the
  +% MBR and position in the file of the new root node.
  +-spec insert_subtree(Fd::file:io_device(), RootPos::integer(),
  +        Subtree::{mbr(), integer()}, Level::integer()) ->
  +        {ok, mbr(), integer()}.
  +insert_subtree(Fd, RootPos, Subtree, Level) ->
  +    insert_subtree(Fd, RootPos, Subtree, Level, 0).
  +
  +-spec insert_subtree(Fd::file:io_device(), RootPos::integer(),
  +        Subtree::{mbr(), integer()}, Level::integer(), Depth::integer()) ->
  +        {ok, integer()}.
  +insert_subtree(Fd, RootPos, Subtree, Level, Depth) when Depth==Level ->
  +    {SubtreeMbr, SubtreePos} = Subtree,
  +    {ok, Parent} = couch_file:pread_term(Fd, RootPos),
  +    {ParentMbr, ParentMeta, EntriesPos} = Parent,
  +    MergedMbr = vtree:merge_mbr(SubtreeMbr, ParentMbr),
  +
  +    ChildrenPos = [SubtreePos|EntriesPos],
  +    if
  +    length(ChildrenPos) =< ?MAX_FILLED ->
  +        NewNode = {MergedMbr, ParentMeta, ChildrenPos},
  +        {ok, Pos} = couch_file:append_term(Fd, NewNode),
  +        {ok, MergedMbr, Pos};
  +    true ->
  +        %io:format("We need to split (leaf node)~n~p~n", [LeafNode]),
  +        Children = load_nodes(Fd, ChildrenPos),
  +        {SplittedMbr, {Node1Mbr, _, _}=Node1, {Node2Mbr, _, _}=Node2}
  +                = vtree:split_node(MergedMbr, #node{type=inner}, Children),
  +        {ok, Pos1} = couch_file:append_term(Fd, Node1),
  +        {ok, Pos2} = couch_file:append_term(Fd, Node2),
  +        {splitted, SplittedMbr, {Node1Mbr, Pos1}, {Node2Mbr, Pos2}}
  +    end;
  +insert_subtree(Fd, RootPos, Subtree, Level, Depth) ->
  +    {SubtreeMbr, SubtreePos} = Subtree,
  +    ?debugVal(RootPos),
  +    {ok, Parent} = couch_file:pread_term(Fd, RootPos),
  +    {ParentMbr, _ParentMeta, EntriesPos} = Parent,
  +    {{_LeastMbr, LeastPos}, LeastRest} = least_expansion(
  +            Fd, SubtreeMbr, EntriesPos),
  +    case insert_subtree(Fd, LeastPos, Subtree, Level, Depth+1) of
  +    {ok, NewMbr, NewPos} ->
  +        MergedMbr = vtree:merge_mbr(ParentMbr, NewMbr),
  +        LeastRestPos = [Pos || {Mbr, Pos} <- LeastRest],
  +        NewNode = {MergedMbr, #node{type=inner}, [NewPos|LeastRestPos]},
  +        {ok, Pos} = couch_file:append_term(Fd, NewNode),
  +        {ok, NewMbr, Pos};
  +    {splitted, ChildMbr, {Child1Mbr, ChildPos1}, {Child2Mbr, ChildPos2}} ->
  +        MergedMbr = vtree:merge_mbr(ParentMbr, ChildMbr),
  +        LeastRestPos = [Pos || {Mbr, Pos} <- LeastRest],
  +        if
  +        % Both nodes of the split fit in the current inner node
  +        length(EntriesPos)+2 =< ?MAX_FILLED ->
  +            ChildrenPos = LeastRestPos ++ ChildPos1 ++ ChildPos2,
  +            NewNode = {MergedMbr, #node{type=inner}, ChildrenPos},
  +            {ok, Pos} = couch_file:append_term(Fd, NewNode),
  +            {ok, MergedMbr, Pos};
  +        % We need to split the inner node
  +        true ->
  +            Child1 = {Child1Mbr, #node{type=inner}, ChildPos1},
  +            Child2 = {Child2Mbr, #node{type=inner}, ChildPos2},
  +            Children = load_nodes(Fd, LeastRest) ++ Child1 ++ Child2,
  +            {SplittedMbr, {Node1Mbr, _, _}=Node1, {Node2Mbr, _, _}=Node2}
  +                    = vtree:split_node(MergedMbr, #node{type=inner}, Children),
  +            {ok, Pos1} = couch_file:append_term(Fd, Node1),
  +            {ok, Pos2} = couch_file:append_term(Fd, Node2),
  +            {splitted, SplittedMbr, {Node1Mbr, Pos1}, {Node2Mbr, Pos2}}
  +        end
  +    end.
  +
  +
  +% XXX vmx: needs tests
  +% @doc Find the node that needs least expension for the given MBR and returns
  +% the MBR and positio of the node together with the original children MBRs and
  +% positions in the file.
  +-spec least_expansion(Fd::file:io_device(), NewMbr::mbr,
  +        PosList::[integer()]) -> {{mbr, integer()}, [{mbr, integer()}]}.
  +least_expansion(Fd, NewMbr, PosList) ->
  +    Nodes = load_nodes(Fd, PosList),
  +    ?debugVal(Nodes),
  +    NodesAndPos = lists:zip(Nodes, PosList),
  +    MbrAndPos = [{Mbr, Pos} || {{Mbr, _, _}, Pos} <- NodesAndPos],
  +    ?debugVal(MbrAndPos),
  +
  +    % Find node that matches best (least expansion of MBR)
  +    {_, _, Nth} = lists:foldl(fun({Mbr, Pos}, {MinExp, Nth2, Cnt}) ->
  +        MergedMbr = vtree:merge_mbr(NewMbr, Mbr),
  +        % if there is a element which need less expansion, put the info
  +        % into the accumulator
  +        case vtree:area(MergedMbr) - vtree:area(Mbr) of
  +        Exp when Exp < MinExp orelse (MinExp==-1) ->
  +            {Exp, Cnt, Cnt+1};
  +        _ ->
  +            {MinExp, Nth2, Cnt+1}
  +        end
  +    end, {-1, 0, 0}, MbrAndPos),
  +    ?debugVal(Nth),
  +
  +    % Remove the child where the node will be inserted
  +    {C1, C2} = lists:split(Nth-1, MbrAndPos),
  +    %C3 = tl(C2),
  +    %MbrAndPosRest = C1 ++ C3,
  +    %?debugVal(MbrAndPosRest),
  +    {hd(C2), C1 ++ tl(C2)}.
   
   %insert_onebyone(Fd, RootPos, Nodes) ->
   %    NewRootPos = lists:foldl(fun(
  
positive.code: % Returns a tuple with the MBR and the position of the root node in the file
  -spec seedtree_write_insert(Fd::file:io_device(), Orig::list(),
          OmtTree::omt_node()) -> [{tuple(), integer()}].
  seedtree_write_insert(Fd, Orig, OmtTree) ->
      % write the OmtTree to to disk.
      {ok, OmtMbrAndPos} = omt_write_tree(Fd, OmtTree),
  
negative.code:     ?assertEqual(772, length(Lookup5)),
      LeafDepths5 = vtreestats:leaf_depths(Fd5, ResultPos5),
      ?assertEqual([4], LeafDepths5).
  
  
  insert_subtree_test() ->
      {ok, {Fd, {RootPos, TreeHeight}}} = vtree_test:build_random_tree(
              "/tmp/randtree.bin", 20),
      ?debugVal(RootPos),
      ?debugVal(TreeHeight),
  
      Nodes1 = lists:foldl(fun(I, Acc) ->
          {NodeId, {NodeMbr, NodeMeta, NodeData}} =
              vtree_test:random_node({I,27+I*329,45}),
          Node = {NodeMbr, NodeMeta, {[NodeId, <<"subtree">>], NodeData}},
          [Node|Acc]
      end, [], lists:seq(1,5)),
  
  
      {Omt1, SubtreeHeight1} = omt_load(Nodes1, ?MAX_FILLED),
      ?debugVal(SubtreeHeight1),
      {ok, MbrAndPosList1} = omt_write_tree(Fd, Omt1),
  
      Result1 = lists:map(fun(MbrAndPos) ->
          {ok, NewMbr, NewPos} = insert_subtree(Fd, RootPos, MbrAndPos, 2),
          ?debugVal(NewPos),
  
          {ok, Lookup} = vtree:lookup(Fd, NewPos, {0,0,1001,1001}),
          %?assertEqual(76, length(Lookup)),
          LeafDepths = vtreestats:leaf_depths(Fd, NewPos),
          %?assertEqual([3], LeafDepths)
          {length(Lookup), LeafDepths}
      end, MbrAndPosList1),
  
      ?assertEqual([{23, [3]}, {22, [3]}], Result1).
  
  %-endif.
  