# File lib/addressable/uri.rb, line 1769
    def merge(hash)
      if !hash.respond_to?(:to_hash)
        raise TypeError, "Can't convert #{hash.class} into Hash."
      end
      hash = hash.to_hash

      if hash.has_key?(:authority)
        if (hash.keys & [:userinfo, :user, :password, :host, :port]).any?
          raise ArgumentError,
            "Cannot specify both an authority and any of the components " +
            "within the authority."
        end
      end
      if hash.has_key?(:userinfo)
        if (hash.keys & [:user, :password]).any?
          raise ArgumentError,
            "Cannot specify both a userinfo and either the user or password."
        end
      end

      uri = Addressable::URI.new
      uri.defer_validation do
        # Bunch of crazy logic required because of the composite components
        # like userinfo and authority.
        uri.scheme =
          hash.has_key?(:scheme) ? hash[:scheme] : self.scheme
        if hash.has_key?(:authority)
          uri.authority =
            hash.has_key?(:authority) ? hash[:authority] : self.authority
        end
        if hash.has_key?(:userinfo)
          uri.userinfo =
            hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo
        end
        if !hash.has_key?(:userinfo) && !hash.has_key?(:authority)
          uri.user =
            hash.has_key?(:user) ? hash[:user] : self.user
          uri.password =
            hash.has_key?(:password) ? hash[:password] : self.password
        end
        if !hash.has_key?(:authority)
          uri.host =
            hash.has_key?(:host) ? hash[:host] : self.host
          uri.port =
            hash.has_key?(:port) ? hash[:port] : self.port
        end
        uri.path =
          hash.has_key?(:path) ? hash[:path] : self.path
        uri.query =
          hash.has_key?(:query) ? hash[:query] : self.query
        uri.fragment =
          hash.has_key?(:fragment) ? hash[:fragment] : self.fragment
      end

      return uri
    end