def serialize_objects_and_references
      obj_dir = {}
      objid_cache = {}
      # create a dictionary for referenced objects (no value resolution at this point)
      # at the same time, delete duplicates and old versions when objects have multiple versions
      @parsed.uniq!
      @parsed.length.times do |i|
        o = @parsed[i]
        objid_cache[o.object_id] = i
        tmp_key = [o[:indirect_reference_id], o[:indirect_generation_number]]
        if tmp_found = obj_dir[tmp_key]
          tmp_found.clear
          @parsed[objid_cache[tmp_found.object_id]] = nil
        end
        obj_dir[tmp_key] = o
      end
      @parsed.compact!
      objid_cache.clear

      should_resolve = [@parsed, @root_object]
      while should_resolve.count > 0
        obj = should_resolve.pop
        if obj.is_a?(Hash)
          obj.keys.each do |k|
            o = obj[k]
            if o.is_a?(Hash)
              if o[:is_reference_only]
                if o[:indirect_reference_id].nil?
                  o = nil
                else
                  o[:referenced_object] = obj_dir[[o[:indirect_reference_id], o[:indirect_generation_number]]]
                  warn "Couldn't connect reference for #{o}" if o[:referenced_object].nil? && (o[:indirect_reference_id] + o[:indirect_generation_number] != 0)
                  o.delete :indirect_reference_id
                  o.delete :indirect_generation_number
                  o = (o[:referenced_object] && o[:referenced_object][:indirect_without_dictionary]) || o
                end
                obj[k] = o
              else
                should_resolve << o
              end
            elsif o.is_a?(Array)
              should_resolve << o
            end
          end
        elsif obj.is_a?(Array)
          obj.map! do |o|
            if o.is_a?(Hash)
              if o[:is_reference_only]
                if o[:indirect_reference_id].nil?
                  o = nil
                else
                  o[:referenced_object] = obj_dir[[o[:indirect_reference_id], o[:indirect_generation_number]]]
                  warn "Couldn't connect reference for #{o}" if o[:referenced_object].nil?
                  o.delete :indirect_reference_id
                  o.delete :indirect_generation_number
                  o = (o[:referenced_object] && o[:referenced_object][:indirect_without_dictionary]) || o
                end
              else
                should_resolve << o
              end
            elsif o.is_a?(Array)
              should_resolve << o
            end
            o
          end
        end
      end
    end
def serialize_objects_and_references
      obj_dir = {}
      objid_cache = {}
      # create a dictionary for referenced objects (no value resolution at this point)
      # at the same time, delete duplicates and old versions when objects have multiple versions
      @parsed.uniq!
      @parsed.length.times do |i|
        o = @parsed[i]
        objid_cache[o.object_id] = i
        tmp_key = [o[:indirect_reference_id], o[:indirect_generation_number]]
        if tmp_found = obj_dir[tmp_key]
          tmp_found.clear
          @parsed[objid_cache[tmp_found.object_id]] = nil
        end
        obj_dir[tmp_key] = o
      end
      @parsed.compact!
      objid_cache.clear

      should_resolve = [@parsed, @root_object]
      while should_resolve.count > 0
        obj = should_resolve.pop
        if obj.is_a?(Hash)
          obj.keys.each do |k|
            o = obj[k]
            if o.is_a?(Hash)
              if o[:is_reference_only]
                if o[:indirect_reference_id].nil?
                  o = nil
                else
                  o[:referenced_object] = obj_dir[[o[:indirect_reference_id], o[:indirect_generation_number]]]
                  warn "Couldn't connect reference for #{o}" if o[:referenced_object].nil? && (o[:indirect_reference_id] + o[:indirect_generation_number] != 0)
                  o.delete :indirect_reference_id
                  o.delete :indirect_generation_number
                  o = (o[:referenced_object] && o[:referenced_object][:indirect_without_dictionary]) || o
                end
                obj[k] = o
              else
                should_resolve << o
              end
            elsif o.is_a?(Array)
              should_resolve << o
            end
          end
        elsif obj.is_a?(Array)
          obj.map! do |o|
            if o.is_a?(Hash)
              if o[:is_reference_only]
                if o[:indirect_reference_id].nil?
                  o = nil
                else
                  o[:referenced_object] = obj_dir[[o[:indirect_reference_id], o[:indirect_generation_number]]]
                  warn "Couldn't connect reference for #{o}" if o[:referenced_object].nil?
                  o.delete :indirect_reference_id
                  o.delete :indirect_generation_number
                  o = (o[:referenced_object] && o[:referenced_object][:indirect_without_dictionary]) || o
                end
              else
                should_resolve << o
              end
            elsif o.is_a?(Array)
              should_resolve << o
            end
            o
          end
        end
      end
    end
@private
 connects references and objects, according to their reference id's.

 Also replaces :indirect_without_dictionary objects with their actual values. Strings, Hashes and Arrays still share memory space.

 should be moved to the parser's workflow.