def merge_outlines(old_data, new_data, position)
      old_data = actual_object(old_data)
      new_data = actual_object(new_data)
      if old_data.nil? || old_data.empty? || old_data[:First].nil?
        # old_data is a reference to the actual object,
        # so if we update old_data, we're done, no need to take any further action
        old_data.update new_data
      elsif new_data.nil? || new_data.empty? || new_data[:First].nil?
        return old_data
      else
        new_data = new_data.dup # avoid old data corruption
        # number of outline nodes, after the merge
        old_data[:Count] = old_data[:Count].to_i + new_data[:Count].to_i
        # walk the Hash here ...
        # I'm just using the start / end insert-position for now...
        # first  - is going to be the start of the outline base node's :First, after the merge
        # last   - is going to be the end   of the outline base node's :Last,  after the merge
        # median - the start of what will be appended to the end of the outline base node's :First
        # parent - the outline base node of the resulting merged outline
        # FIXME implement the possibility to insert somewhere in the middle of the outline
        prev = nil
        pos = first = actual_object((position.nonzero? ? old_data : new_data)[:First])
        last = actual_object((position.nonzero? ? new_data : old_data)[:Last])
        median = { is_reference_only: true, referenced_object: actual_object((position.nonzero? ? new_data : old_data)[:First]) }
        old_data[:First] = { is_reference_only: true, referenced_object: first }
        old_data[:Last] = { is_reference_only: true, referenced_object: last }
        parent = { is_reference_only: true, referenced_object: old_data }
        while pos
          # walking through old_data here and updating the :Parent as we go,
          # this updates the inserted new_data :Parent's as well once it is appended and the
          # loop keeps walking the appended data.
          pos[:Parent] = parent if pos[:Parent]
          # connect the two outlines
          # if there is no :Next, the end of the outline base node's :First is reached and this is
          # where the new data gets appended, the same way you would append to a two-way linked list.
          if pos[:Next].nil?
            median[:referenced_object][:Prev] = { is_reference_only: true, referenced_object: prev } if median
            pos[:Next] = median
            # midian becomes 'nil' because this loop keeps going after the appending is done,
            # to update the parents of the appended tree and we wouldn't want to keep appending it infinitely.
            median = nil
          end
          # iterating over the outlines main nodes (this is not going into subtrees)
          # while keeping every rotations previous node saved
          prev = pos
          pos = actual_object(pos[:Next])
        end
        # make sure the last object doesn't have the :Next and the first no :Prev property
        prev.delete :Next
        actual_object(old_data[:First]).delete :Prev
      end
    end
def merge_outlines(old_data, new_data, position)
      old_data = actual_object(old_data)
      new_data = actual_object(new_data)
      if old_data.nil? || old_data.empty? || old_data[:First].nil?
        # old_data is a reference to the actual object,
        # so if we update old_data, we're done, no need to take any further action
        old_data.update new_data
      elsif new_data.nil? || new_data.empty? || new_data[:First].nil?
        return old_data
      else
        new_data = new_data.dup # avoid old data corruption
        # number of outline nodes, after the merge
        old_data[:Count] = old_data[:Count].to_i + new_data[:Count].to_i
        # walk the Hash here ...
        # I'm just using the start / end insert-position for now...
        # first  - is going to be the start of the outline base node's :First, after the merge
        # last   - is going to be the end   of the outline base node's :Last,  after the merge
        # median - the start of what will be appended to the end of the outline base node's :First
        # parent - the outline base node of the resulting merged outline
        # FIXME implement the possibility to insert somewhere in the middle of the outline
        prev = nil
        pos = first = actual_object((position.nonzero? ? old_data : new_data)[:First])
        last = actual_object((position.nonzero? ? new_data : old_data)[:Last])
        median = { is_reference_only: true, referenced_object: actual_object((position.nonzero? ? new_data : old_data)[:First]) }
        old_data[:First] = { is_reference_only: true, referenced_object: first }
        old_data[:Last] = { is_reference_only: true, referenced_object: last }
        parent = { is_reference_only: true, referenced_object: old_data }
        while pos
          # walking through old_data here and updating the :Parent as we go,
          # this updates the inserted new_data :Parent's as well once it is appended and the
          # loop keeps walking the appended data.
          pos[:Parent] = parent if pos[:Parent]
          # connect the two outlines
          # if there is no :Next, the end of the outline base node's :First is reached and this is
          # where the new data gets appended, the same way you would append to a two-way linked list.
          if pos[:Next].nil?
            median[:referenced_object][:Prev] = { is_reference_only: true, referenced_object: prev } if median
            pos[:Next] = median
            # midian becomes 'nil' because this loop keeps going after the appending is done,
            # to update the parents of the appended tree and we wouldn't want to keep appending it infinitely.
            median = nil
          end
          # iterating over the outlines main nodes (this is not going into subtrees)
          # while keeping every rotations previous node saved
          prev = pos
          pos = actual_object(pos[:Next])
        end
        # make sure the last object doesn't have the :Next and the first no :Prev property
        prev.delete :Next
        actual_object(old_data[:First]).delete :Prev
      end
    end
Merges 2 outlines by appending one to the end or start of the other.
 old_data - the main outline, which is also the one that will be used in the resulting PDF.
 new_data - the outline to be appended
 position - an integer representing the position where a PDF is being inserted.
            This method only differentiates between inserted at the beginning, or not.
            Not at the beginning, means the new outline will be added to the end of the original outline.
 An outline base node (tree base) has :Type, :Count, :First, :Last
 Every node within the outline base node's :First or :Last can have also have the following pointers to other nodes:
 :First or :Last (only if the node has a subtree / subsection)
 :Parent (the node's parent)
 :Prev, :Next (previous and next node)
 Non-node-pointer data in these nodes:
 :Title - the node's title displayed in the PDF outline
 :Count - Number of nodes in it's subtree (0 if no subtree)
 :Dest  - node link destination (if the node is linking to something)