# File lib/cidr.rb, line 1536
    def remainder(addr, options=nil)
        known_args = [:Objectify, :Short]
        short = nil
        objectify = nil

        # validate options
        if (options)
            raise ArgumentError, "Hash expected for argument 'options' but " +
                                 "#{options.class} provided." if (!options.kind_of?(Hash) )
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end
        end

        if ( !addr.kind_of?(NetAddr::CIDR) )
            begin
                addr = NetAddr::CIDR.create(addr)
            rescue Exception => error
                raise ArgumentError, "Argument 'addr' raised the following " +
                                     "errors: #{error}"
            end
        end


        # make sure 'addr' is the same ip version
        if ( addr.version != @version )
            raise VersionError, "#{addr.desc(:Short => true)} is of a different " +
                                "IP version than #{self.desc(:Short => true)}."
        end

        # make sure we contain 'to_exclude'
        if ( self.contains?(addr) != true )
            raise BoundaryError, "#{addr.desc(:Short => true)} does not fit " +
                                 "within the bounds of #{self.desc(:Short => true)}."
        end

        # split this cidr in half & see which half 'to_exclude'
        # belongs in. take that half & repeat the process. every time
        # we repeat, store the non-matching half
        new_mask = self.bits + 1
        lower_network = self.to_i(:network)
        upper_network = self.to_i(:network) + 2**(@address_len - new_mask)

        new_subnets = []
        until(new_mask > addr.bits)
            if (addr.to_i(:network) < upper_network)
                match = lower_network
                non_match = upper_network
            else
                match = upper_network
                non_match = lower_network
            end

            if (!objectify)
                non_match = NetAddr.ip_int_to_str(non_match, @version)
                non_match = NetAddr.shorten(non_match) if (short && @version == 6)
                new_subnets.unshift("#{non_match}/#{new_mask}")
            else
                new_subnets.unshift( NetAddr.cidr_build(@version, non_match, NetAddr.bits_to_mask(new_mask,version) ) )
            end

            new_mask = new_mask + 1
            lower_network = match
            upper_network = match + 2**(@address_len - new_mask)
        end

        return(new_subnets)
    end