def login(username, password) #:yields: login_results
      @request_struct.username = username
      @request_struct.password = password

      # We are required to set the Accept header to this by the RETS 1.5 specification.
      set_header('Accept', '*/*')

      response = request(@urls.login)

      # Parse response to get other URLS
      results = @response_parser.parse_key_value(response.body)
      # TODO: fix test to like this
      # results = ResponseDocument.safe_parse(response.body).validate!.parse_key_value

      if (results.success?)
        CAPABILITY_LIST.each do |capability|
          next unless results.response[capability]

          uri = URI.parse(results.response[capability])

          if uri.absolute?
            @urls[capability] = uri
          else
            base = @urls.login.clone
            base.path = results.response[capability]
            @urls[capability] = base
          end
        end

        logger.debug("Capability URL List: #{@urls.inspect}") if logger
      else
        raise LoginError.new(response.message + "(#{results.reply_code}: #{results.reply_text})")
      end

      # Perform the mandatory get request on the action URL.
      results.secondary_response = perform_action_url

      # We only yield
      if block_given?
        begin
          yield results
        ensure
          self.logout
        end
      else
        results
      end
    end
def login(username, password) #:yields: login_results
      @request_struct.username = username
      @request_struct.password = password

      # We are required to set the Accept header to this by the RETS 1.5 specification.
      set_header('Accept', '*/*')

      response = request(@urls.login)

      # Parse response to get other URLS
      results = @response_parser.parse_key_value(response.body)
      # TODO: fix test to like this
      # results = ResponseDocument.safe_parse(response.body).validate!.parse_key_value

      if (results.success?)
        CAPABILITY_LIST.each do |capability|
          next unless results.response[capability]

          uri = URI.parse(results.response[capability])

          if uri.absolute?
            @urls[capability] = uri
          else
            base = @urls.login.clone
            base.path = results.response[capability]
            @urls[capability] = base
          end
        end

        logger.debug("Capability URL List: #{@urls.inspect}") if logger
      else
        raise LoginError.new(response.message + "(#{results.reply_code}: #{results.reply_text})")
      end

      # Perform the mandatory get request on the action URL.
      results.secondary_response = perform_action_url

      # We only yield
      if block_given?
        begin
          yield results
        ensure
          self.logout
        end
      else
        results
      end
    end
RETS Transaction Methods 

 Most of these transaction methods mirror the RETS specification methods, so if you are
 unsure what they mean, you should check the RETS specification. The latest version can be
 found at http://www.rets.org
 Attempts to log into the server using the provided username and password.

 If called with a block, the results of the login action are yielded,
 and logout is called when the block returns.  In that case, #login
 returns the block's value. If called without a block, returns the
 result.

 As specified in the RETS specification, the Action URL is called and
 the results made available in the #secondary_results accessor of the
 results object.