def errors
      return @errors if instance_variables.any? { |ivar| ivar.to_s == '@errors' }
      @errors = catch(:errors) do
        if authorization.nil?
          throw(:errors, {'Authorization' => ["Authorization header is missing"]})
        elsif authorization !~ /\S/
          throw(:errors, {'Authorization' => ["Authorization header is blank"]})
        end

        begin
          oauth_header_params
        rescue OAuthenticator::Error => parse_exception
          throw(:errors, parse_exception.errors)
        end

        errors = Hash.new { |h,k| h[k] = [] }

        # timestamp
        if !timestamp?
          unless signature_method == 'PLAINTEXT'
            errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is missing"
          end
        elsif timestamp !~ /\A\s*\d+\s*\z/
          errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is not an integer - got: #{timestamp}"
        else
          timestamp_i = timestamp.to_i
          if timestamp_i < Time.now.to_i - timestamp_valid_past
            errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is too old: #{timestamp}"
          elsif timestamp_i > Time.now.to_i + timestamp_valid_future
            errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is too far in the future: #{timestamp}"
          end
        end

        # oauth version
        if version? && version != '1.0'
          errors['Authorization oauth_version'] << "Authorization oauth_version must be 1.0; got: #{version}"
        end

        # she's filled with secrets
        secrets = {}

        # consumer / client application
        if !consumer_key?
          errors['Authorization oauth_consumer_key'] << "Authorization oauth_consumer_key is missing"
        else
          secrets[:consumer_secret] = consumer_secret
          if !secrets[:consumer_secret]
            errors['Authorization oauth_consumer_key'] << 'Authorization oauth_consumer_key is invalid'
          end
        end

        # token
        if token?
          secrets[:token_secret] = token_secret
          if !secrets[:token_secret]
            errors['Authorization oauth_token'] << 'Authorization oauth_token is invalid'
          elsif !token_belongs_to_consumer?
            errors['Authorization oauth_token'] << 'Authorization oauth_token does not belong to the specified consumer'
          end
        end

        # nonce
        if !nonce?
          unless signature_method == 'PLAINTEXT'
            errors['Authorization oauth_nonce'] << "Authorization oauth_nonce is missing"
          end
        elsif nonce_used?
          errors['Authorization oauth_nonce'] << "Authorization oauth_nonce has already been used"
        end

        # signature method
        if !signature_method?
          errors['Authorization oauth_signature_method'] << "Authorization oauth_signature_method is missing"
        elsif !allowed_signature_methods.any? { |sm| signature_method.downcase == sm.downcase }
          errors['Authorization oauth_signature_method'] << "Authorization oauth_signature_method must be one of " +
            "#{allowed_signature_methods.join(', ')}; got: #{signature_method}"
        end

        # signature
        if !signature?
          errors['Authorization oauth_signature'] << "Authorization oauth_signature is missing"
        end

        signable_request = SignableRequest.new(@attributes.merge(secrets).merge('authorization' => oauth_header_params))

        # body hash

        # present?
        if body_hash?
          # allowed?
          if !signable_request.form_encoded?
            # applicable?
            if SignableRequest::BODY_HASH_METHODS.key?(signature_method)
              # correct?
              if body_hash == signable_request.body_hash
                # all good
              else
                errors['Authorization oauth_body_hash'] << "Authorization oauth_body_hash is invalid"
              end
            else
              # received a body hash with plaintext. weird situation - we will ignore it; signature will not 
              # be verified but it will be a part of the signature. 
            end
          else
            errors['Authorization oauth_body_hash'] << "Authorization oauth_body_hash must not be included with form-encoded requests"
          end
        else
          # allowed?
          if !signable_request.form_encoded?
            # required?
            if body_hash_required?
              errors['Authorization oauth_body_hash'] << "Authorization oauth_body_hash is required (on non-form-encoded requests)"
            else
              # okay - not supported by client, but allowed
            end
          else
            # all good
          end
        end

        throw(:errors, errors) if errors.any?

        # proceed to check signature
        unless self.signature == signable_request.signature
          throw(:errors, {'Authorization oauth_signature' => ['Authorization oauth_signature is invalid']})
        end

        if nonce?
          begin
            use_nonce!
          rescue NonceUsedError
            throw(:errors, {'Authorization oauth_nonce' => ['Authorization oauth_nonce has already been used']})
          end
        end

        nil
      end
    end
def errors
      return @errors if instance_variables.any? { |ivar| ivar.to_s == '@errors' }
      @errors = catch(:errors) do
        if authorization.nil?
          throw(:errors, {'Authorization' => ["Authorization header is missing"]})
        elsif authorization !~ /\S/
          throw(:errors, {'Authorization' => ["Authorization header is blank"]})
        end

        begin
          oauth_header_params
        rescue OAuthenticator::Error => parse_exception
          throw(:errors, parse_exception.errors)
        end

        errors = Hash.new { |h,k| h[k] = [] }

        # timestamp
        if !timestamp?
          unless signature_method == 'PLAINTEXT'
            errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is missing"
          end
        elsif timestamp !~ /\A\s*\d+\s*\z/
          errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is not an integer - got: #{timestamp}"
        else
          timestamp_i = timestamp.to_i
          if timestamp_i < Time.now.to_i - timestamp_valid_past
            errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is too old: #{timestamp}"
          elsif timestamp_i > Time.now.to_i + timestamp_valid_future
            errors['Authorization oauth_timestamp'] << "Authorization oauth_timestamp is too far in the future: #{timestamp}"
          end
        end

        # oauth version
        if version? && version != '1.0'
          errors['Authorization oauth_version'] << "Authorization oauth_version must be 1.0; got: #{version}"
        end

        # she's filled with secrets
        secrets = {}

        # consumer / client application
        if !consumer_key?
          errors['Authorization oauth_consumer_key'] << "Authorization oauth_consumer_key is missing"
        else
          secrets[:consumer_secret] = consumer_secret
          if !secrets[:consumer_secret]
            errors['Authorization oauth_consumer_key'] << 'Authorization oauth_consumer_key is invalid'
          end
        end

        # token
        if token?
          secrets[:token_secret] = token_secret
          if !secrets[:token_secret]
            errors['Authorization oauth_token'] << 'Authorization oauth_token is invalid'
          elsif !token_belongs_to_consumer?
            errors['Authorization oauth_token'] << 'Authorization oauth_token does not belong to the specified consumer'
          end
        end

        # nonce
        if !nonce?
          unless signature_method == 'PLAINTEXT'
            errors['Authorization oauth_nonce'] << "Authorization oauth_nonce is missing"
          end
        elsif nonce_used?
          errors['Authorization oauth_nonce'] << "Authorization oauth_nonce has already been used"
        end

        # signature method
        if !signature_method?
          errors['Authorization oauth_signature_method'] << "Authorization oauth_signature_method is missing"
        elsif !allowed_signature_methods.any? { |sm| signature_method.downcase == sm.downcase }
          errors['Authorization oauth_signature_method'] << "Authorization oauth_signature_method must be one of " +
            "#{allowed_signature_methods.join(', ')}; got: #{signature_method}"
        end

        # signature
        if !signature?
          errors['Authorization oauth_signature'] << "Authorization oauth_signature is missing"
        end

        signable_request = SignableRequest.new(@attributes.merge(secrets).merge('authorization' => oauth_header_params))

        # body hash

        # present?
        if body_hash?
          # allowed?
          if !signable_request.form_encoded?
            # applicable?
            if SignableRequest::BODY_HASH_METHODS.key?(signature_method)
              # correct?
              if body_hash == signable_request.body_hash
                # all good
              else
                errors['Authorization oauth_body_hash'] << "Authorization oauth_body_hash is invalid"
              end
            else
              # received a body hash with plaintext. weird situation - we will ignore it; signature will not 
              # be verified but it will be a part of the signature. 
            end
          else
            errors['Authorization oauth_body_hash'] << "Authorization oauth_body_hash must not be included with form-encoded requests"
          end
        else
          # allowed?
          if !signable_request.form_encoded?
            # required?
            if body_hash_required?
              errors['Authorization oauth_body_hash'] << "Authorization oauth_body_hash is required (on non-form-encoded requests)"
            else
              # okay - not supported by client, but allowed
            end
          else
            # all good
          end
        end

        throw(:errors, errors) if errors.any?

        # proceed to check signature
        unless self.signature == signable_request.signature
          throw(:errors, {'Authorization oauth_signature' => ['Authorization oauth_signature is invalid']})
        end

        if nonce?
          begin
            use_nonce!
          rescue NonceUsedError
            throw(:errors, {'Authorization oauth_nonce' => ['Authorization oauth_nonce has already been used']})
          end
        end

        nil
      end
    end
initialize a {SignedRequest}. this should not be called on OAuthenticator::SignedRequest directly, but
 a subclass made with {.including_config} - see {SignedRequest}'s documentation.
 inspects the request represented by this instance of SignedRequest. if the request is authentically
 signed with OAuth, returns nil to indicate that there are no errors. if the request is inauthentic or
 invalid for any reason, this returns a hash containing the reason(s) why the request is invalid.

 The error object's structure is a hash with string keys indicating attributes with errors, and values
 being arrays of strings indicating error messages on the attribute key. this structure takes after
 structured rails / ActiveResource, and looks like:

     {'attribute1': ['messageA', 'messageB'], 'attribute2': ['messageC']}

 @return [nil, Hash<String, Array<String>>] either nil or a hash of errors