def catalog_pages(catalogs = nil, inheritance_hash = {})
      unless catalogs

        if root_object[:Root]
          catalogs = root_object[:Root][:referenced_object] || root_object[:Root]
        else
          catalogs = (@parsed.select { |obj| obj[:Type] == :Catalog }).last
        end

        @parsed.delete_if { |obj| obj.nil? || obj[:Type] == :Catalog }
        @parsed << catalogs

        unless catalogs
          raise ParsingError, "Unknown error - parsed data doesn't contain a cataloged object!"
        end
      end
      if catalogs.is_a?(Array)
        catalogs.each { |c| catalog_pages(c, inheritance_hash) unless c.nil? }
      elsif catalogs.is_a?(Hash)
        if catalogs[:is_reference_only]
          if catalogs[:referenced_object]
            catalog_pages(catalogs[:referenced_object], inheritance_hash)
          else
            warn "couldn't follow reference!!! #{catalogs} not found!"
          end
        else
          unless catalogs[:Type] == :Page
            if (catalogs[:AS] || catalogs[:OCProperties]) && !@allow_optional_content
              raise ParsingError, "Optional Content PDF files aren't supported and their pages cannot be safely extracted."
            end

            inheritance_hash[:MediaBox] = catalogs[:MediaBox] if catalogs[:MediaBox]
            inheritance_hash[:CropBox] = catalogs[:CropBox] if catalogs[:CropBox]
            inheritance_hash[:Rotate] = catalogs[:Rotate] if catalogs[:Rotate]
            if catalogs[:Resources]
              inheritance_hash[:Resources] ||= { referenced_object: {}, is_reference_only: true }.dup
              (inheritance_hash[:Resources][:referenced_object] || inheritance_hash[:Resources]).update((catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            if catalogs[:ColorSpace]
              inheritance_hash[:ColorSpace] ||= { referenced_object: {}, is_reference_only: true }.dup
              (inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]).update((catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            # (inheritance_hash[:Resources] ||= {}).update((catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:Resources]
            # (inheritance_hash[:ColorSpace] ||= {}).update((catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:ColorSpace]

            # inheritance_hash[:Order] = catalogs[:Order] if catalogs[:Order]
            # inheritance_hash[:OCProperties] = catalogs[:OCProperties] if catalogs[:OCProperties]
            # inheritance_hash[:AS] = catalogs[:AS] if catalogs[:AS]
          end

          case catalogs[:Type]
          when :Page

            catalogs[:MediaBox] ||= inheritance_hash[:MediaBox] if inheritance_hash[:MediaBox]
            catalogs[:CropBox] ||= inheritance_hash[:CropBox] if inheritance_hash[:CropBox]
            catalogs[:Rotate] ||= inheritance_hash[:Rotate] if inheritance_hash[:Rotate]
            if inheritance_hash[:Resources]
              catalogs[:Resources] ||= { referenced_object: {}, is_reference_only: true }.dup
              catalogs[:Resources] = { referenced_object: catalogs[:Resources], is_reference_only: true } unless catalogs[:Resources][:referenced_object]
              catalogs[:Resources][:referenced_object].update((inheritance_hash[:Resources][:referenced_object] || inheritance_hash[:Resources]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            if inheritance_hash[:ColorSpace]
              catalogs[:ColorSpace] ||= { referenced_object: {}, is_reference_only: true }.dup
              catalogs[:ColorSpace] = { referenced_object: catalogs[:ColorSpace], is_reference_only: true } unless catalogs[:ColorSpace][:referenced_object]
              catalogs[:ColorSpace][:referenced_object].update((inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            # (catalogs[:ColorSpace] ||= {}).update(inheritance_hash[:ColorSpace], &HASH_UPDATE_PROC_FOR_OLD) if inheritance_hash[:ColorSpace]
            # catalogs[:Order] ||= inheritance_hash[:Order] if inheritance_hash[:Order]
            # catalogs[:AS] ||= inheritance_hash[:AS] if inheritance_hash[:AS]
            # catalogs[:OCProperties] ||= inheritance_hash[:OCProperties] if inheritance_hash[:OCProperties]

            # avoide references on MediaBox, CropBox and Rotate
            catalogs[:MediaBox] = catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary] if catalogs[:MediaBox].is_a?(Hash) && catalogs[:MediaBox][:referenced_object].is_a?(Hash) && catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary]
            catalogs[:CropBox] = catalogs[:CropBox][:referenced_object][:indirect_without_dictionary] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:CropBox][:referenced_object][:indirect_without_dictionary]
            catalogs[:Rotate] = catalogs[:Rotate][:referenced_object][:indirect_without_dictionary] if catalogs[:Rotate].is_a?(Hash) && catalogs[:Rotate][:referenced_object].is_a?(Hash) && catalogs[:Rotate][:referenced_object][:indirect_without_dictionary]

            catalogs.instance_eval { extend Page_Methods }
          when :Pages
            catalog_pages(catalogs[:Kids], inheritance_hash.dup) unless catalogs[:Kids].nil?
          when :Catalog
            @forms_object.update((catalogs[:AcroForm][:referenced_object] || catalogs[:AcroForm]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:AcroForm]
            @names_object.update((catalogs[:Names][:referenced_object] || catalogs[:Names]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:Names]
            @outlines_object.update((catalogs[:Outlines][:referenced_object] || catalogs[:Outlines]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:Outlines]
            if catalogs[:Dests] # convert PDF 1.1 Dests to PDF 1.2+ Dests
              dests_arry = (@names_object[:Dests] ||= {})
              dests_arry = ((dests_arry[:referenced_object] || dests_arry)[:Names] ||= [])
              ((catalogs[:Dests][:referenced_object] || catalogs[:Dests])[:referenced_object] || (catalogs[:Dests][:referenced_object] || catalogs[:Dests])).each {|k,v| next if CombinePDF::PDF::PRIVATE_HASH_KEYS.include?(k); dests_arry << unify_string(k.to_s); dests_arry << v; }
            end
            catalog_pages(catalogs[:Pages], inheritance_hash.dup) unless catalogs[:Pages].nil?
          end
        end
      end
      self
    end
def catalog_pages(catalogs = nil, inheritance_hash = {})
      unless catalogs

        if root_object[:Root]
          catalogs = root_object[:Root][:referenced_object] || root_object[:Root]
        else
          catalogs = (@parsed.select { |obj| obj[:Type] == :Catalog }).last
        end

        @parsed.delete_if { |obj| obj.nil? || obj[:Type] == :Catalog }
        @parsed << catalogs

        unless catalogs
          raise ParsingError, "Unknown error - parsed data doesn't contain a cataloged object!"
        end
      end
      if catalogs.is_a?(Array)
        catalogs.each { |c| catalog_pages(c, inheritance_hash) unless c.nil? }
      elsif catalogs.is_a?(Hash)
        if catalogs[:is_reference_only]
          if catalogs[:referenced_object]
            catalog_pages(catalogs[:referenced_object], inheritance_hash)
          else
            warn "couldn't follow reference!!! #{catalogs} not found!"
          end
        else
          unless catalogs[:Type] == :Page
            if (catalogs[:AS] || catalogs[:OCProperties]) && !@allow_optional_content
              raise ParsingError, "Optional Content PDF files aren't supported and their pages cannot be safely extracted."
            end

            inheritance_hash[:MediaBox] = catalogs[:MediaBox] if catalogs[:MediaBox]
            inheritance_hash[:CropBox] = catalogs[:CropBox] if catalogs[:CropBox]
            inheritance_hash[:Rotate] = catalogs[:Rotate] if catalogs[:Rotate]
            if catalogs[:Resources]
              inheritance_hash[:Resources] ||= { referenced_object: {}, is_reference_only: true }.dup
              (inheritance_hash[:Resources][:referenced_object] || inheritance_hash[:Resources]).update((catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            if catalogs[:ColorSpace]
              inheritance_hash[:ColorSpace] ||= { referenced_object: {}, is_reference_only: true }.dup
              (inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]).update((catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            # (inheritance_hash[:Resources] ||= {}).update((catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:Resources]
            # (inheritance_hash[:ColorSpace] ||= {}).update((catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:ColorSpace]

            # inheritance_hash[:Order] = catalogs[:Order] if catalogs[:Order]
            # inheritance_hash[:OCProperties] = catalogs[:OCProperties] if catalogs[:OCProperties]
            # inheritance_hash[:AS] = catalogs[:AS] if catalogs[:AS]
          end

          case catalogs[:Type]
          when :Page

            catalogs[:MediaBox] ||= inheritance_hash[:MediaBox] if inheritance_hash[:MediaBox]
            catalogs[:CropBox] ||= inheritance_hash[:CropBox] if inheritance_hash[:CropBox]
            catalogs[:Rotate] ||= inheritance_hash[:Rotate] if inheritance_hash[:Rotate]
            if inheritance_hash[:Resources]
              catalogs[:Resources] ||= { referenced_object: {}, is_reference_only: true }.dup
              catalogs[:Resources] = { referenced_object: catalogs[:Resources], is_reference_only: true } unless catalogs[:Resources][:referenced_object]
              catalogs[:Resources][:referenced_object].update((inheritance_hash[:Resources][:referenced_object] || inheritance_hash[:Resources]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            if inheritance_hash[:ColorSpace]
              catalogs[:ColorSpace] ||= { referenced_object: {}, is_reference_only: true }.dup
              catalogs[:ColorSpace] = { referenced_object: catalogs[:ColorSpace], is_reference_only: true } unless catalogs[:ColorSpace][:referenced_object]
              catalogs[:ColorSpace][:referenced_object].update((inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
            end
            # (catalogs[:ColorSpace] ||= {}).update(inheritance_hash[:ColorSpace], &HASH_UPDATE_PROC_FOR_OLD) if inheritance_hash[:ColorSpace]
            # catalogs[:Order] ||= inheritance_hash[:Order] if inheritance_hash[:Order]
            # catalogs[:AS] ||= inheritance_hash[:AS] if inheritance_hash[:AS]
            # catalogs[:OCProperties] ||= inheritance_hash[:OCProperties] if inheritance_hash[:OCProperties]

            # avoide references on MediaBox, CropBox and Rotate
            catalogs[:MediaBox] = catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary] if catalogs[:MediaBox].is_a?(Hash) && catalogs[:MediaBox][:referenced_object].is_a?(Hash) && catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary]
            catalogs[:CropBox] = catalogs[:CropBox][:referenced_object][:indirect_without_dictionary] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:CropBox][:referenced_object][:indirect_without_dictionary]
            catalogs[:Rotate] = catalogs[:Rotate][:referenced_object][:indirect_without_dictionary] if catalogs[:Rotate].is_a?(Hash) && catalogs[:Rotate][:referenced_object].is_a?(Hash) && catalogs[:Rotate][:referenced_object][:indirect_without_dictionary]

            catalogs.instance_eval { extend Page_Methods }
          when :Pages
            catalog_pages(catalogs[:Kids], inheritance_hash.dup) unless catalogs[:Kids].nil?
          when :Catalog
            @forms_object.update((catalogs[:AcroForm][:referenced_object] || catalogs[:AcroForm]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:AcroForm]
            @names_object.update((catalogs[:Names][:referenced_object] || catalogs[:Names]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:Names]
            @outlines_object.update((catalogs[:Outlines][:referenced_object] || catalogs[:Outlines]), &HASH_UPDATE_PROC_FOR_NEW) if catalogs[:Outlines]
            if catalogs[:Dests] # convert PDF 1.1 Dests to PDF 1.2+ Dests
              dests_arry = (@names_object[:Dests] ||= {})
              dests_arry = ((dests_arry[:referenced_object] || dests_arry)[:Names] ||= [])
              ((catalogs[:Dests][:referenced_object] || catalogs[:Dests])[:referenced_object] || (catalogs[:Dests][:referenced_object] || catalogs[:Dests])).each {|k,v| next if CombinePDF::PDF::PRIVATE_HASH_KEYS.include?(k); dests_arry << unify_string(k.to_s); dests_arry << v; }
            end
            catalog_pages(catalogs[:Pages], inheritance_hash.dup) unless catalogs[:Pages].nil?
          end
        end
      end
      self
    end
resets cataloging and pages