# events[].return_value.value
You are being

# events[].return_value.value
You are being

# events[].parameters[].value
{:execute_type=>3, :formatted_command_string=>"SELECT a.attname\n  FROM (\n         SELECT indrelid,

# events[].return_value.value
{"execute_type":3,"formatted_command_string":"SELECT a.attname\n  FROM (\n         SELECT indrelid, 

# events[].return_value.value
root

# events[].return_value.value
Request

Parameters:

None

# events[].return_value.value
"

\n
\n

# events[].return_value.value
"\n

\n"

# events[].return_value.value
".console .pos-absolute {\n  position: absolute;\n}\n\n.console .pos-fixed {\n  position: fixed;\n}\

# events[].return_value.value
<script type="text/javascript" data-template="console" nonce="">
(function() {
  /**
 * Constructor 

# events[].return_value.value
<script type="text/javascript" data-template="error_page" nonce="">
(function() {
  // Try intercept

# events[].parameters[].value
<Audience>my-single-tenant</Audience>

# events[].parameters[].value
<NameID Format='urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress'>foo@foo.com</NameID>

# events[].parameters[].value
<ds:DigestValue>w9FsEdyTErRZ3ZTNIIDjiKRvjuj3kZG3sDILyZ59pbA=</ds:DigestValue>

# events[].sql_query.sql
INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"

# events[].sql_query.normalized_sql
INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"

# events[].sql_query.sql
SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2

# events[].sql_query.normalized_sql
SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2

# events[].return_value.value
You are being redirected.

# events[].sql_query.sql
SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2

# events[].sql_query.normalized_sql
SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2

# events[].return_value.value
root

# events[].return_value.value
Request

Parameters:

None

# events[].return_value.value
"

\n
\n

# events[].return_value.value
"\n

\n"

# events[].return_value.value
".console .pos-absolute {\n  position: absolute;\n}\n\n.console .pos-fixed {\n  position: fixed;\n}\

# events[].return_value.value
<script type="text/javascript" data-template="console" nonce="">
(function() {
  /**
 * Constructor 

# events[].return_value.value
<script type="text/javascript" data-template="error_page" nonce="">
(function() {
  // Try intercept

# events[].return_value.value
root

# events[].return_value.value
Request

Parameters:

None

# events[].return_value.value
"

\n
\n

# events[].return_value.value
"\n

\n"

# events[].return_value.value
".console .pos-absolute {\n  position: absolute;\n}\n\n.console .pos-fixed {\n  position: fixed;\n}\

# events[].return_value.value
<script type="text/javascript" data-template="console" nonce="">
(function() {
  /**
 * Constructor 

# events[].return_value.value
<script type="text/javascript" data-template="error_page" nonce="">
(function() {
  // Try intercept

# classMap[].children[].children[].children[].source
    def self.register_interceptor(object = nil, &block)
      interceptor = object || block
      interceptors << interceptor
    end

# classMap[].children[].children[].children[].children[].source
      def prepend(&block)
        @prepend << block
      end

# classMap[].children[].children[].children[].children[].children[].source
        def [](key)
          scope = find { |node| node.frame.key? key }
          scope && scope.frame[key]
        end

# classMap[].children[].children[].children[].children[].children[].source
        def new(hash)
          self.class.new hash, self, scope_level
        end

# classMap[].children[].children[].children[].children[].children[].source
        def constraints(constraints = {})
          scope(constraints: constraints) { yield }
        end

# classMap[].children[].children[].children[].children[].children[].comment
# === Parameter Restriction
# Allows you to constrain the nested routes based on a set of rules.
# For instance, in order to change the routes to allow for a dot character in the +id+ parameter:
#
#   constraints(id: /\d+\.\d+/) do
#     resources :posts
#   end
#
# Now routes such as +/posts/1+ will no longer be valid, but +/posts/1.1+ will be.
# The +id+ parameter must match the constraint passed in for this example.
#
# You may use this to also restrict other parameters:
#
#   resources :posts do
#     constraints(post_id: /\d+\.\d+/) do
#       resources :comments
#     end
#   end
#
# === Restricting based on IP
#
# Routes can also be constrained to an IP or a certain range of IP addresses:
#
#   constraints(ip: /192\.168\.\d+\.\d+/) do
#     resources :posts
#   end
#
# Any user connecting from the 192.168.* range will be able to see this resource,
# where as any user connecting outside of this range will be told there is no such route.
#
# === Dynamic request matching
#
# Requests to routes can be constrained based on specific criteria:
#
#    constraints(-> (req) { /iPhone/.match?(req.env["HTTP_USER_AGENT"]) }) do
#      resources :iphones
#    end
#
# You are able to move this logic out into a class if it is too complex for routes.
# This class must have a +matches?+ method defined on it which either returns +true+
# if the user should be given access to that route, or +false+ if the user should not.
#
#    class Iphone
#      def self.matches?(request)
#        /iPhone/.match?(request.env["HTTP_USER_AGENT"])
#      end
#    end
#
# An expected place for this code would be +lib/constraints+.
#
# This class is then used like this:
#
#    constraints(Iphone) do
#      resources :iphones
#    end

# classMap[].children[].children[].children[].children[].children[].source
        def get(*args, &block)
          map_method(:get, args, &block)
        end

# classMap[].children[].children[].children[].children[].children[].comment
# Define a route that only recognizes HTTP GET.
# For supported arguments, see match[rdoc-ref:Base#match]
#
#   get 'bacon', to: 'food#bacon'

# classMap[].children[].children[].children[].source
    def routes=(routes) # :nodoc:
      set_header("action_dispatch.routes", routes)
    end

# classMap[].children[].children[].children[].source
    def cookies_serializer
      get_header Cookies::COOKIES_SERIALIZER
    end

# classMap[].children[].children[].children[].source
    def send_early_hints(links)
      return unless env["rack.early_hints"]

      env["rack.early_hints"].call(links)
    end

# classMap[].children[].children[].children[].comment
# Early Hints is an HTTP/2 status code that indicates hints to help a client start
# making preparations for processing the final response.
#
# If the env contains +rack.early_hints+ then the server accepts HTTP2 push for Link headers.
#
# The +send_early_hints+ method accepts a hash of links as follows:
#
#   send_early_hints("Link" => "</style.css>; rel=preload; as=style\n</script.js>; rel=preload")
#
# If you are using +javascript_include_tag+ or +stylesheet_link_tag+ the
# Early Hints headers are included by default if supported.

# classMap[].children[].children[].children[].source
    def local?
      LOCALHOST.match?(remote_addr) && LOCALHOST.match?(remote_ip)
    end

# classMap[].children[].children[].children[].comment
# True if the request came from localhost, 127.0.0.1, or ::1.

# classMap[].children[].children[].children[].source
    def use_cookies_with_metadata
      get_header Cookies::USE_COOKIES_WITH_METADATA
    end

# classMap[].children[].children[].children[].source
        def #{env.delete_prefix("HTTP_").downcase}  # def accept_charset
          get_header "#{env}"                       #   get_header "HTTP_ACCEPT_CHARSET"
        end                                         # end

# classMap[].children[].children[].children[].source
    def request_id
      get_header ACTION_DISPATCH_REQUEST_ID
    end

# classMap[].children[].children[].children[].comment
# Returns the unique request id, which is based on either the X-Request-Id header that can
# be generated by a firewall, load balancer, or web server or by the RequestId middleware
# (which sets the action_dispatch.request_id environment variable).
#
# This unique ID is useful for tracing a request from end-to-end as part of logging or debugging.
# This relies on the Rack variable set by the ActionDispatch::RequestId middleware.

# classMap[].children[].children[].children[].children[].source
      def [](key)
        load_for_read!
        key = key.to_s

        if key == "session_id"
          id&.public_id
        else
          @delegate[key]
        end
      end

# classMap[].children[].children[].children[].children[].comment
# Returns value of the key stored in the session or
# +nil+ if the given key is not found in the session.

# classMap[].children[].children[].children[].children[].children[].source
        def []=(k, v);        @delegate[k] = v; end

# classMap[].children[].children[].children[].children[].source
      def []=(key, value)
        load_for_write!
        @delegate[key.to_s] = value
      end

# classMap[].children[].children[].children[].children[].comment
# Writes given value to given key of the session.

# classMap[].children[].children[].children[].children[].source
      def load_session(req)
        stale_session_check! do
          data = unpacked_cookie_data(req)
          data = persistent_session_id!(data)
          [Rack::Session::SessionId.new(data["session_id"]), data]
        end
      end

# classMap[].children[].children[].children[].children[].source
      def []=(name, options)
        if options.is_a?(Hash)
          options.symbolize_keys!
          value = options[:value]
        else
          value = options
          options = { value: value }
        end

        handle_options(options)

        if @cookies[name.to_s] != value || options[:expires]
          @cookies[name.to_s] = value
          @set_cookies[name.to_s] = options
          @delete_cookies.delete(name.to_s)
        end

        value
      end

# classMap[].children[].children[].children[].children[].comment
# Sets the cookie named +name+. The second argument may be the cookie's
# value or a hash of options as documented above.

# classMap[].children[].children[].children[].source
    def compiled_method_container
      self.class
    end

# classMap[].children[].children[].children[].source
      def abstract!
        @abstract = true
      end

# classMap[].children[].children[].children[].comment
# Define a controller as abstract. See internal_methods for more
# details.

# classMap[].children[].children[].children[].source
    def performed?
      response_body || response.committed?
    end

# classMap[].children[].children[].children[].comment
# Tests if render or redirect has already happened.

# classMap[].children[].children[].children[].children[].source
      def log_process_action(payload) #:nodoc:
        messages, view_runtime = [], payload[:view_runtime]
        messages << ("Views: %.1fms" % view_runtime.to_f) if view_runtime
        messages
      end

# classMap[].children[].children[].children[].children[].comment
# A hook which allows other frameworks to log what happened during
# controller process action. This method should return an array
# with the messages to be added.

# classMap[].children[].children[].children[].source
    def redirect_to(*)
      ActiveSupport::Notifications.instrument("redirect_to.action_controller", request: request) do |payload|
        result = super
        payload[:status]   = response.status
        payload[:location] = response.filtered_location
        result
      end
    end

# classMap[].children[].children[].children[].children[].source
      def inherited(klass)
        if klass._wrapper_options.format.any?
          params = klass._wrapper_options.dup
          params.klass = klass
          klass._wrapper_options = params
        end
        super
      end

# classMap[].children[].children[].children[].children[].comment
# Sets the default wrapper key or model which will be used to determine
# wrapper key and attribute names. Called automatically when the
# module is inherited.

# classMap[].children[].children[].comment
# Default way to set up Devise. Run rails generate devise_install to create
# a fresh initializer with all configuration values.

# classMap[].children[].children[].source
  def self.include_helpers(scope)
    ActiveSupport.on_load(:action_controller) do
      include scope::Helpers if defined?(scope::Helpers)
      include scope::UrlHelpers
    end

    ActiveSupport.on_load(:action_view) do
      include scope::UrlHelpers
    end
  end

# classMap[].children[].children[].comment
# Include helpers in the given scope to AC and AV.

# classMap[].children[].children[].source
  def self.add_mapping(resource, options)
    mapping = Devise::Mapping.new(resource, options)
    @@mappings[mapping.name] = mapping
    @@default_scope ||= mapping.name
    @@helpers.each { |h| h.define_helpers(mapping) }
    mapping
  end

# classMap[].children[].children[].comment
# Small method that adds a mapping to Devise.

# classMap[].children[].children[].children[].source
    def routes
      @routes ||= ROUTES.values_at(*self.modules).compact.uniq
    end

# classMap[].children[].children[].children[].source
    def fullpath
      "/#{@path_prefix}/#{@path}".squeeze("/")
    end

# classMap[].children[].children[].children[].comment
# Gives the class the mapping points to.

# classMap[].children[].children[].children[].source
    def finalize!
      result = super
      @devise_finalized ||= begin
        if Devise.router_name.nil? && defined?(@devise_finalized) && self != Rails.application.try(:routes)
          warn "[DEVISE] We have detected that you are using devise_for inside engine routes. " \
            "In this case, you probably want to set Devise.router_name = MOUNT_POINT, where "   \
            "MOUNT_POINT is a symbol representing where this engine will be mounted at. For "   \
            "now Devise will default the mount point to :main_app. You can explicitly set it"   \
            " to :main_app as well in case you want to keep the current behavior."
        end

        Devise.configure_warden!
        Devise.regenerate_helpers!
        true
      end
      result
    end

# classMap[].children[].children[].source
  def self.configure_warden! #:nodoc:
    @@warden_configured ||= begin
      warden_config.failure_app   = Devise::Delegator.new
      warden_config.default_scope = Devise.default_scope
      warden_config.intercept_401 = false

      Devise.mappings.each_value do |mapping|
        warden_config.scope_defaults mapping.name, strategies: mapping.strategies

        warden_config.serialize_into_session(mapping.name) do |record|
          mapping.to.serialize_into_session(record)
        end

        warden_config.serialize_from_session(mapping.name) do |args|
          mapping.to.serialize_from_session(*args)
        end
      end

      @@warden_config_blocks.map { |block| block.call Devise.warden_config }
      true
    end
  end

# classMap[].children[].children[].comment
# A method used internally to complete the setup of warden manager after routes are loaded.
# See lib/devise/rails/routes.rb - ActionDispatch::Routing::RouteSet#finalize_with_devise!

# classMap[].children[].children[].children[].children[].children[].source
        def log_process_action(payload)
          payload[:status] ||= 401 unless payload[:exception]
          super
        end

# classMap[].children[].children[].children[].children[].source
      def warden
        request.env['warden'] or raise MissingWarden
      end

# classMap[].children[].children[].children[].children[].comment
# The main accessor for the warden proxy instance

# classMap[].children[].children[].children[].children[].source
      def devise_controller?
        is_a?(::DeviseController)
      end

# classMap[].children[].children[].children[].children[].comment
# Return true if it's a devise_controller. false to all controllers unless
# the controllers defined inside devise. Useful if you want to apply a before
# filter to all controllers, except the ones in devise:
#
#   before_action :my_filter, unless: :devise_controller?

# classMap[].children[].children[].children[].children[].children[].source
          def #{accessor}
            if defined?(@#{accessor})
              @#{accessor}
            elsif superclass.respond_to?(:#{accessor})
              superclass.#{accessor}
            else
              Devise.#{accessor}
            end
          end

# classMap[].children[].children[].children[].children[].source
      def active_for_authentication?
        true
      end

# classMap[].children[].children[].children[].children[].source
      def timedout?(last_access)
        !timeout_in.nil? && last_access && last_access <= timeout_in.ago
      end

# classMap[].children[].children[].children[].children[].comment
# Checks whether the user session has expired based on configured time.

# classMap[].children[].children[].children[].children[].source
    def devise_for(*resources)
      @devise_finalized = false
      raise_no_secret_key unless Devise.secret_key
      options = resources.extract_options!

      options[:as]          ||= @scope[:as]     if @scope[:as].present?
      options[:module]      ||= @scope[:module] if @scope[:module].present?
      options[:path_prefix] ||= @scope[:path]   if @scope[:path].present?
      options[:path_names]    = (@scope[:path_names] || {}).merge(options[:path_names] || {})
      options[:constraints]   = (@scope[:constraints] || {}).merge(options[:constraints] || {})
      options[:defaults]      = (@scope[:defaults] || {}).merge(options[:defaults] || {})
      options[:options]       = @scope[:options] || {}
      options[:options][:format] = false if options[:format] == false

      resources.map!(&:to_sym)

      resources.each do |resource|
        mapping = Devise.add_mapping(resource, options)

        begin
          raise_no_devise_method_error!(mapping.class_name) unless mapping.to.respond_to?(:devise)
        rescue NameError => e
          raise unless mapping.class_name == resource.to_s.classify
          warn "[WARNING] You provided devise_for #{resource.inspect} but there is " \
            "no model #{mapping.class_name} defined in your application"
          next
        rescue NoMethodError => e
          raise unless e.message.include?("undefined method `devise'")
          raise_no_devise_method_error!(mapping.class_name)
        end

        if options[:controllers] && options[:controllers][:omniauth_callbacks]
          unless mapping.omniauthable?
            raise ArgumentError, "Mapping omniauth_callbacks on a resource that is not omniauthable\n" \
              "Please add `devise :omniauthable` to the `#{mapping.class_name}` model"
          end
        end

        routes = mapping.used_routes

        devise_scope mapping.name do
          with_devise_exclusive_scope mapping.fullpath, mapping.name, options do
            routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
          end
        end
      end
    end

# classMap[].children[].children[].children[].children[].comment
# Includes devise_for method for routes. This method is responsible to
# generate all needed routes for devise, based on what modules you have
# defined in your model.
#
# ==== Examples
#
# Let's say you have an User model configured to use authenticatable,
# confirmable and recoverable modules. After creating this inside your routes:
#
#   devise_for :users
#
# This method is going to look inside your User model and create the
# needed routes:
#
#  # Session routes for Authenticatable (default)
#       new_user_session GET    /users/sign_in                    {controller:"devise/sessions", action:"new"}
#           user_session POST   /users/sign_in                    {controller:"devise/sessions", action:"create"}
#   destroy_user_session DELETE /users/sign_out                   {controller:"devise/sessions", action:"destroy"}
#
#  # Password routes for Recoverable, if User model has :recoverable configured
#      new_user_password GET    /users/password/new(.:format)     {controller:"devise/passwords", action:"new"}
#     edit_user_password GET    /users/password/edit(.:format)    {controller:"devise/passwords", action:"edit"}
#          user_password PUT    /users/password(.:format)         {controller:"devise/passwords", action:"update"}
#                        POST   /users/password(.:format)         {controller:"devise/passwords", action:"create"}
#
#  # Confirmation routes for Confirmable, if User model has :confirmable configured
#  new_user_confirmation GET    /users/confirmation/new(.:format) {controller:"devise/confirmations", action:"new"}
#      user_confirmation GET    /users/confirmation(.:format)     {controller:"devise/confirmations", action:"show"}
#                        POST   /users/confirmation(.:format)     {controller:"devise/confirmations", action:"create"}
#
# ==== Routes integration
#
# +devise_for+ is meant to play nicely with other routes methods. For example,
# by calling +devise_for+ inside a namespace, it automatically nests your devise
# controllers:
#
#     namespace :publisher do
#       devise_for :account
#     end
#
# The snippet above will use publisher/sessions controller instead of devise/sessions
# controller. You can revert this change or configure it directly by passing the :module
# option described below to +devise_for+.
#
# Also note that when you use a namespace it will affect all the helpers and methods
# for controllers and views. For example, using the above setup you'll end with
# following methods: current_publisher_account, authenticate_publisher_account!,
# publisher_account_signed_in, etc.
#
# The only aspect not affect by the router configuration is the model name. The
# model name can be explicitly set via the :class_name option.
#
# ==== Options
#
# You can configure your routes with some options:
#
#  * class_name: set up a different class to be looked up by devise, if it cannot be
#    properly found by the route name.
#
#      devise_for :users, class_name: 'Account'
#
#  * path: allows you to set up path name that will be used, as rails routes does.
#    The following route configuration would set up your route as /accounts instead of /users:
#
#      devise_for :users, path: 'accounts'
#
#  * singular: set up the singular name for the given resource. This is used as the helper methods
#    names in controller ("authenticate_#{singular}!", "#{singular}_signed_in?", "current_#{singular}"
#    and "#{singular}_session"), as the scope name in routes and as the scope given to warden.
#
#      devise_for :admins, singular: :manager
#
#      devise_scope :manager do
#        ...
#      end
#
#      class ManagerController < ApplicationController
#        before_action authenticate_manager!
#
#        def show
#          @manager = current_manager
#          ...
#        end
#      end
#
#  * path_names: configure different path names to overwrite defaults :sign_in, :sign_out, :sign_up,
#    :password, :confirmation, :unlock.
#
#      devise_for :users, path_names: {
#        sign_in: 'login', sign_out: 'logout',
#        password: 'secret', confirmation: 'verification',
#        registration: 'register', edit: 'edit/profile'
#      }
#
#  * controllers: the controller which should be used. All routes by default points to Devise controllers.
#    However, if you want them to point to custom controller, you should do:
#
#      devise_for :users, controllers: { sessions: "users/sessions" }
#
#  * failure_app: a rack app which is invoked whenever there is a failure. Strings representing a given
#    are also allowed as parameter.
#
#  * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :delete),
#    if you wish to restrict this to accept only :post or :delete requests you should do:
#
#      devise_for :users, sign_out_via: [:get, :post]
#
#    You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
#
#  * module: the namespace to find controllers (default: "devise", thus
#    accessing devise/sessions, devise/registrations, and so on). If you want
#    to namespace all at once, use module:
#
#      devise_for :users, module: "users"
#
#  * skip: tell which controller you want to skip routes from being created.
#    It accepts :all as an option, meaning it will not generate any route at all:
#
#      devise_for :users, skip: :sessions
#
#  * only: the opposite of :skip, tell which controllers only to generate routes to:
#
#      devise_for :users, only: :sessions
#
#  * skip_helpers: skip generating Devise url helpers like new_session_path(@user).
#    This is useful to avoid conflicts with previous routes and is false by default.
#    It accepts true as option, meaning it will skip all the helpers for the controllers
#    given in :skip but it also accepts specific helpers to be skipped:
#
#      devise_for :users, skip: [:registrations, :confirmations], skip_helpers: true
#      devise_for :users, skip_helpers: [:registrations, :confirmations]
#
#  * format: include "(.:format)" in the generated routes? true by default, set to false to disable:
#
#      devise_for :users, format: false
#
#  * constraints: works the same as Rails' constraints
#
#  * defaults: works the same as Rails' defaults
#
#  * router_name: allows application level router name to be overwritten for the current scope
#
# ==== Scoping
#
# Following Rails 3 routes DSL, you can nest devise_for calls inside a scope:
#
#   scope "/my" do
#     devise_for :users
#   end
#
# However, since Devise uses the request path to retrieve the current user,
# this has one caveat: If you are using a dynamic segment, like so ...
#
#   scope ":locale" do
#     devise_for :users
#   end
#
# you are required to configure default_url_options in your
# ApplicationController class, so Devise can pick it:
#
#   class ApplicationController < ActionController::Base
#     def self.default_url_options
#       { locale: I18n.locale }
#     end
#   end
#
# ==== Adding custom actions to override controllers
#
# You can pass a block to devise_for that will add any routes defined in the block to Devise's
# list of known actions.  This is important if you add a custom action to a controller that
# overrides an out of the box Devise controller.
# For example:
#
#    class RegistrationsController < Devise::RegistrationsController
#      def update
#         # do something different here
#      end
#
#      def deactivate
#        # not a standard action
#        # deactivate code here
#      end
#    end
#
# In order to get Devise to recognize the deactivate action, your devise_scope entry should look like this:
#
#     devise_scope :owner do
#       post "deactivate", to: "registrations#deactivate", as: "deactivate_registration"
#     end
#

# classMap[].children[].children[].source
  def saml_login
    request = OneLogin::RubySaml::Authrequest.new
    redirect_to(request.create(saml_settings))
  end

# classMap[].children[].children[].source
  def saml_callback
    response = OneLogin::RubySaml::Response.new(
      params[:SAMLResponse],
      :settings => saml_settings
    )
  
    if response.is_valid?
      @user = User.create_or_find_by!(email: response.nameid)
      sign_in(@user)
      redirect_to(:logged_in)
    else
      raise response.errors.inspect
    end
  end

# classMap[].children[].children[].children[].children[].source
      def self.uuid
        RUBY_VERSION < '1.9' ? "_#{@@uuid_generator.generate}" : "_#{SecureRandom.uuid}"
      end

# classMap[].children[].children[].children[].children[].source
      def self.element_text(element)
        element.texts.map(&:value).join if element
      end

# classMap[].children[].children[].children[].children[].comment
# Given a REXML::Element instance, return the concatenation of all child text nodes. Assumes
# that there all children other than text nodes can be ignored (e.g. comments). If nil is
# passed, nil will be returned.

# classMap[].children[].children[].children[].children[].source
      def self.uri_match?(destination_url, settings_url)
        dest_uri = URI.parse(destination_url)
        acs_uri = URI.parse(settings_url)

        if dest_uri.scheme.nil? || acs_uri.scheme.nil? || dest_uri.host.nil? || acs_uri.host.nil?
          raise URI::InvalidURIError
        else
          dest_uri.scheme.downcase == acs_uri.scheme.downcase &&
            dest_uri.host.downcase == acs_uri.host.downcase &&
            dest_uri.path == acs_uri.path &&
            dest_uri.query == acs_uri.query
        end
      rescue URI::InvalidURIError
        original_uri_match?(destination_url, settings_url)
      end

# classMap[].children[].children[].children[].children[].comment
# Given two strings, attempt to match them as URIs using Rails' parse method.  If they can be parsed,
# then the fully-qualified domain name and the host should performa a case-insensitive match, per the
# RFC for URIs.  If Rails can not parse the string in to URL pieces, return a boolean match of the
# two strings.  This maintains the previous functionality.
# @return [Boolean]

# classMap[].children[].children[].children[].children[].source
      def self.format_cert(cert)
        # don't try to format an encoded certificate or if is empty or nil
        if cert.respond_to?(:ascii_only?)
          return cert if cert.nil? || cert.empty? || !cert.ascii_only?
        else
          return cert if cert.nil? || cert.empty? || cert.match(/\x0d/)
        end

        if cert.scan(/BEGIN CERTIFICATE/).length > 1
          formatted_cert = []
          cert.scan(/-{5}BEGIN CERTIFICATE-{5}[\n\r]?.*?-{5}END CERTIFICATE-{5}[\n\r]?/m) {|c|
            formatted_cert << format_cert(c)
          }
          formatted_cert.join("\n")
        else
          cert = cert.gsub(/\-{5}\s?(BEGIN|END) CERTIFICATE\s?\-{5}/, "")
          cert = cert.gsub(/\r/, "")
          cert = cert.gsub(/\n/, "")
          cert = cert.gsub(/\s/, "")
          cert = cert.scan(/.{1,64}/)
          cert = cert.join("\n")
          "-----BEGIN CERTIFICATE-----\n#{cert}\n-----END CERTIFICATE-----"
        end
      end

# classMap[].children[].children[].children[].children[].comment
# Return a properly formatted x509 certificate
#
# @param cert [String] The original certificate
# @return [String] The formatted certificate
#

# classMap[].children[].children[].children[].children[].source
      def single_logout_service_binding=(url)
        @single_logout_service_binding = url
      end

# classMap[].children[].children[].children[].children[].comment
# Setter for Single Logout Service Binding.
#
# (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")
# @param url [String]
#

# classMap[].children[].children[].children[].children[].source
      def sp_entity_id=(val)
        @sp_entity_id = val
      end

# classMap[].children[].children[].children[].children[].comment
# Setter for SP Entity ID.
# @param val [String].
#

# classMap[].children[].children[].children[].children[].source
      def sp_entity_id
        val = nil
        if @sp_entity_id.nil?
          if @issuer
            val = @issuer
          end
        else
          val = @sp_entity_id
        end
        val
      end

# classMap[].children[].children[].children[].children[].source
      def get_idp_cert_multi
        return nil if idp_cert_multi.nil? || idp_cert_multi.empty?

        raise ArgumentError.new("Invalid value for idp_cert_multi") if not idp_cert_multi.is_a?(Hash)

        certs = {:signing => [], :encryption => [] }

        if idp_cert_multi.key?(:signing) and not idp_cert_multi[:signing].empty?
          idp_cert_multi[:signing].each do |idp_cert|
            formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
            certs[:signing].push(OpenSSL::X509::Certificate.new(formatted_cert))
          end
        end

        if idp_cert_multi.key?(:encryption) and not idp_cert_multi[:encryption].empty?
          idp_cert_multi[:encryption].each do |idp_cert|
            formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
            certs[:encryption].push(OpenSSL::X509::Certificate.new(formatted_cert))
          end
        end

        certs
      end

# classMap[].children[].children[].children[].children[].comment
# @return [Hash with 2 arrays of OpenSSL::X509::Certificate] Build multiple IdP certificates from the settings.
#

# classMap[].children[].children[].children[].children[].source
      def get_idp_cert
        return nil if idp_cert.nil? || idp_cert.empty?

        formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
        OpenSSL::X509::Certificate.new(formatted_cert)
      end

# classMap[].children[].children[].children[].children[].comment
# @return [OpenSSL::X509::Certificate|nil] Build the IdP certificate from the settings (previously format it)
#

# classMap[].children[].children[].children[].children[].source
      def get_fingerprint
        idp_cert_fingerprint || begin
          idp_cert = get_idp_cert
          if idp_cert
            fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new
            fingerprint_alg.hexdigest(idp_cert.to_der).upcase.scan(/../).join(":")
          end
        end
      end

# classMap[].children[].children[].children[].children[].comment
# Calculates the fingerprint of the IdP x509 certificate.
# @return [String] The fingerprint
#

# classMap[].children[].children[].children[].children[].source
      def create(settings, params = {})
        params = create_params(settings, params)
        params_prefix = (settings.idp_sso_target_url =~ /\?/) ? '&' : '?'
        saml_request = CGI.escape(params.delete("SAMLRequest"))
        request_params = "#{params_prefix}SAMLRequest=#{saml_request}"
        params.each_pair do |key, value|
          request_params << "&#{key.to_s}=#{CGI.escape(value.to_s)}"
        end
        raise "Invalid settings, idp_sso_target_url is not set!" if settings.idp_sso_target_url.nil?
        @login_url = settings.idp_sso_target_url + request_params
      end

# classMap[].children[].children[].children[].children[].comment
# Creates the AuthNRequest string.
# @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
# @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
# @return [String] AuthNRequest string that includes the SAMLRequest
#

# classMap[].children[].children[].children[].children[].source
      def create_params(settings, params={})
        # The method expects :RelayState but sometimes we get 'RelayState' instead.
        # Based on the HashWithIndifferentAccess value in Rails we could experience
        # conflicts so this line will solve them.
        relay_state = params[:RelayState] || params['RelayState']

        if relay_state.nil?
          params.delete(:RelayState)
          params.delete('RelayState')
        end

        request_doc = create_authentication_xml_doc(settings)
        request_doc.context[:attribute_quote] = :quote if settings.double_quote_xml_attribute_values

        request = ""
        request_doc.write(request)

        Logging.debug "Created AuthnRequest: #{request}"

        request = deflate(request) if settings.compress_request
        base64_request = encode(request)
        request_params = {"SAMLRequest" => base64_request}

        if settings.security[:authn_requests_signed] && !settings.security[:embed_sign] && settings.private_key
          params['SigAlg']    = settings.security[:signature_method]
          url_string = OneLogin::RubySaml::Utils.build_query(
            :type => 'SAMLRequest',
            :data => base64_request,
            :relay_state => relay_state,
            :sig_alg => params['SigAlg']
          )
          sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
          signature = settings.get_sp_key.sign(sign_algorithm.new, url_string)
          params['Signature'] = encode(signature)
        end

        params.each_pair do |key, value|
          request_params[key] = value.to_s
        end

        request_params
      end

# classMap[].children[].children[].children[].children[].comment
# Creates the Get parameters for the request.
# @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
# @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
# @return [Hash] Parameters
#

# classMap[].children[].children[].children[].children[].source
      def create_authentication_xml_doc(settings)
        document = create_xml_document(settings)
        sign_document(document, settings)
      end

# classMap[].children[].children[].children[].children[].comment
# Creates the SAMLRequest String.
# @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
# @return [String] The SAMLRequest String.
#

# classMap[].children[].children[].children[].children[].source
      def create_xml_document(settings)
        time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")

        request_doc = XMLSecurity::Document.new
        request_doc.uuid = uuid

        root = request_doc.add_element "samlp:AuthnRequest", { "xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol", "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" }
        root.attributes['ID'] = uuid
        root.attributes['IssueInstant'] = time
        root.attributes['Version'] = "2.0"
        root.attributes['Destination'] = settings.idp_sso_target_url unless settings.idp_sso_target_url.nil?
        root.attributes['IsPassive'] = settings.passive unless settings.passive.nil?
        root.attributes['ProtocolBinding'] = settings.protocol_binding unless settings.protocol_binding.nil?
        root.attributes["AttributeConsumingServiceIndex"] = settings.attributes_index unless settings.attributes_index.nil?
        root.attributes['ForceAuthn'] = settings.force_authn unless settings.force_authn.nil?

        # Conditionally defined elements based on settings
        if settings.assertion_consumer_service_url != nil
          root.attributes["AssertionConsumerServiceURL"] = settings.assertion_consumer_service_url
        end
        if settings.sp_entity_id != nil
          issuer = root.add_element "saml:Issuer"
          issuer.text = settings.sp_entity_id
        end

        if settings.name_identifier_value_requested != nil
          subject = root.add_element "saml:Subject"

          nameid = subject.add_element "saml:NameID"
          nameid.attributes['Format'] = settings.name_identifier_format if settings.name_identifier_format
          nameid.text = settings.name_identifier_value_requested

          subject_confirmation = subject.add_element "saml:SubjectConfirmation"
          subject_confirmation.attributes['Method'] = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
        end

        if settings.name_identifier_format != nil
          root.add_element "samlp:NameIDPolicy", {
              # Might want to make AllowCreate a setting?
              "AllowCreate" => "true",
              "Format" => settings.name_identifier_format
          }
        end

        if settings.authn_context || settings.authn_context_decl_ref

          if settings.authn_context_comparison != nil
            comparison = settings.authn_context_comparison
          else
            comparison = 'exact'
          end

          requested_context = root.add_element "samlp:RequestedAuthnContext", {
            "Comparison" => comparison,
          }

          if settings.authn_context != nil
            authn_contexts_class_ref = settings.authn_context.is_a?(Array) ? settings.authn_context : [settings.authn_context]
            authn_contexts_class_ref.each do |authn_context_class_ref|
              class_ref = requested_context.add_element "saml:AuthnContextClassRef"
              class_ref.text = authn_context_class_ref
            end
          end

          if settings.authn_context_decl_ref != nil
            authn_contexts_decl_refs = settings.authn_context_decl_ref.is_a?(Array) ? settings.authn_context_decl_ref : [settings.authn_context_decl_ref]
            authn_contexts_decl_refs.each do |authn_context_decl_ref|
              decl_ref = requested_context.add_element "saml:AuthnContextDeclRef"
              decl_ref.text = authn_context_decl_ref
            end
          end
        end

        request_doc
      end

# classMap[].children[].children[].children[].children[].source
      def sign_document(document, settings)
        # embed signature
        if settings.security[:authn_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
          private_key = settings.get_sp_key
          cert = settings.get_sp_cert
          document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
        end

        document
      end

# classMap[].children[].children[].children[].children[].source
      def self.debug(message)
        return if !!ENV["ruby-saml/testing"]

        logger.debug message
      end

# classMap[].children[].children[].children[].children[].source
      def self.logger
        @logger ||= begin
          (defined?(::Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
            DEFAULT_LOGGER
        end
      end

# classMap[].children[].children[].children[].children[].source
      def is_valid?(collect_errors = false)
        validate(collect_errors)
      end

# classMap[].children[].children[].children[].children[].comment
# Validates the SAML Response with the default values (soft = true)
# @param collect_errors [Boolean] Stop validation when first error appears or keep validating. (if soft=true)
# @return [Boolean] TRUE if the SAML Response is valid
#

# classMap[].children[].children[].children[].children[].source
      def success?
        status_code == "urn:oasis:names:tc:SAML:2.0:status:Success"
      end

# classMap[].children[].children[].children[].children[].comment
# Checks if the Status has the "Success" code
# @return [Boolean] True if the StatusCode is Sucess
#

# classMap[].children[].children[].children[].children[].source
      def status_code
        @status_code ||= begin
          nodes = REXML::XPath.match(
            document,
            "/p:Response/p:Status/p:StatusCode",
            { "p" => PROTOCOL }
          )
          if nodes.size == 1
            node = nodes[0]
            code = node.attributes["Value"] if node && node.attributes

            unless code == "urn:oasis:names:tc:SAML:2.0:status:Success"
              nodes = REXML::XPath.match(
                document,
                "/p:Response/p:Status/p:StatusCode/p:StatusCode",
                { "p" => PROTOCOL }
              )
              statuses = nodes.collect do |inner_node|
                inner_node.attributes["Value"]
              end
              extra_code = statuses.join(" | ")
              if extra_code
                code = "#{code} | #{extra_code}"
              end
            end
            code
          end
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String] StatusCode value from a SAML Response.
#

# classMap[].children[].children[].children[].children[].source
      def conditions
        @conditions ||= xpath_first_from_signed_assertion('/a:Conditions')
      end

# classMap[].children[].children[].children[].children[].comment
# Gets the Condition Element of the SAML Response if exists.
# (returns the first node that matches the supplied xpath)
# @return [REXML::Element] Conditions Element if exists
#

# classMap[].children[].children[].children[].children[].source
      def not_before
        @not_before ||= parse_time(conditions, "NotBefore")
      end

# classMap[].children[].children[].children[].children[].comment
# Gets the NotBefore Condition Element value.
# @return [Time] The NotBefore value in Time format
#

# classMap[].children[].children[].children[].children[].source
      def allowed_clock_drift
        return options[:allowed_clock_drift].to_f
      end

# classMap[].children[].children[].children[].children[].comment
# returns the allowed clock drift on timing validation
# @return [Integer]

# classMap[].children[].children[].children[].children[].source
      def not_on_or_after
        @not_on_or_after ||= parse_time(conditions, "NotOnOrAfter")
      end

# classMap[].children[].children[].children[].children[].comment
# Gets the NotOnOrAfter Condition Element value.
# @return [Time] The NotOnOrAfter value in Time format
#

# classMap[].children[].children[].children[].children[].source
      def audiences
        @audiences ||= begin
          nodes = xpath_from_signed_assertion('/a:Conditions/a:AudienceRestriction/a:Audience')
          nodes.map { |node| Utils.element_text(node) }.reject(&:empty?)
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [Array] The Audience elements from the Contitions of the SAML Response.
#

# classMap[].children[].children[].children[].children[].source
      def destination
        @destination ||= begin
          node = REXML::XPath.first(
            document,
            "/p:Response",
            { "p" => PROTOCOL }
          )
          node.nil? ? nil : node.attributes['Destination']
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String|nil] Destination attribute from the SAML Response.
#

# classMap[].children[].children[].children[].children[].source
      def session_expires_at
        @expires_at ||= begin
          node = xpath_first_from_signed_assertion('/a:AuthnStatement')
          node.nil? ? nil : parse_time(node, "SessionNotOnOrAfter")
        end
      end

# classMap[].children[].children[].children[].children[].comment
# Gets the SessionNotOnOrAfter from the AuthnStatement.
# Could be used to set the local session expiration (expire at latest)
# @return [String] The SessionNotOnOrAfter value
#

# classMap[].children[].children[].children[].children[].source
      def in_response_to
        @in_response_to ||= begin
          node = REXML::XPath.first(
            document,
            "/p:Response",
            { "p" => PROTOCOL }
          )
          node.nil? ? nil : node.attributes['InResponseTo']
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String|nil] The InResponseTo attribute from the SAML Response.
#

# classMap[].children[].children[].children[].children[].source
      def name_id
        @name_id ||= Utils.element_text(name_id_node)
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String] the NameID provided by the SAML response from the IdP.
#

# classMap[].children[].children[].children[].children[].source
      def name_id_spnamequalifier
        @name_id_spnamequalifier ||=
          if name_id_node && name_id_node.attribute("SPNameQualifier")
            name_id_node.attribute("SPNameQualifier").value
          end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String] the NameID SPNameQualifier provided by the SAML response from the IdP.
#

# classMap[].children[].children[].children[].children[].source
      def reset_errors!
        @errors = []
      end

# classMap[].children[].children[].children[].children[].source
      def version(document)
        @version ||= begin
          node = REXML::XPath.first(
            document,
            "/p:AuthnRequest | /p:Response | /p:LogoutResponse | /p:LogoutRequest",
            { "p" => PROTOCOL }
          )
          node.nil? ? nil : node.attributes['Version']
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String|nil] Gets the Version attribute from the SAML Message if exists.
#

# classMap[].children[].children[].children[].children[].source
      def id(document)
        @id ||= begin
          node = REXML::XPath.first(
            document,
            "/p:AuthnRequest | /p:Response | /p:LogoutResponse | /p:LogoutRequest",
            { "p" => PROTOCOL }
          )
          node.nil? ? nil : node.attributes['ID']
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [String|nil] Gets the ID attribute from the SAML Message if exists.
#

# classMap[].children[].children[].children[].children[].source
      def valid_saml?(document, soft = true)
        begin
          xml = Nokogiri::XML(document.to_s) do |config|
            config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS
          end
        rescue Exception => error
          return false if soft
          raise ValidationError.new("XML load failed: #{error.message}")
        end

        SamlMessage.schema.validate(xml).map do |schema_error|
          return false if soft
          raise ValidationError.new("#{schema_error.message}\n\n#{xml.to_s}")
        end
      end

# classMap[].children[].children[].children[].children[].comment
# Validates the SAML Message against the specified schema.
# @param document [REXML::Document] The message that will be validated
# @param soft [Boolean] soft Enable or Disable the soft mode (In order to raise exceptions when the message is invalid or not)
# @return [Boolean] True if the XML is valid, otherwise False, if soft=True
# @raise [ValidationError] if soft == false and validation fails
#

# classMap[].children[].children[].children[].children[].source
      def self.schema
        @@mutex.synchronize do
          Dir.chdir(File.expand_path("../../../schemas", __FILE__)) do
            ::Nokogiri::XML::Schema(File.read("saml-schema-protocol-2.0.xsd"))
          end
        end
      end

# classMap[].children[].children[].children[].children[].comment
# @return [Nokogiri::XML::Schema] Gets the schema object of the SAML 2.0 Protocol schema
#

# classMap[].children[].children[].children[].source
    def signed_element_id
      @signed_element_id ||= extract_signed_element_id
    end

# classMap[].children[].children[].children[].source
    def validate_document(idp_cert_fingerprint, soft = true, options = {})
      # get cert from response
      cert_element = REXML::XPath.first(
        self,
        "//ds:X509Certificate",
        { "ds"=>DSIG }
      )

      if cert_element
        base64_cert = OneLogin::RubySaml::Utils.element_text(cert_element)
        cert_text = Base64.decode64(base64_cert)
        begin
          cert = OpenSSL::X509::Certificate.new(cert_text)
        rescue OpenSSL::X509::CertificateError => _e
          return append_error("Certificate Error", soft)
        end

        if options[:fingerprint_alg]
          fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(options[:fingerprint_alg]).new
        else
          fingerprint_alg = OpenSSL::Digest::SHA1.new
        end
        fingerprint = fingerprint_alg.hexdigest(cert.to_der)

        # check cert matches registered idp cert
        if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
          @errors << "Fingerprint mismatch"
          return append_error("Fingerprint mismatch", soft)
        end
      else
        if options[:cert]
          base64_cert = Base64.encode64(options[:cert].to_pem)
        else
          if soft
            return false
          else
            return append_error("Certificate element missing in response (ds:X509Certificate) and not cert provided at settings", soft)
          end
        end
      end
      validate_signature(base64_cert, soft)
    end

# classMap[].children[].children[].children[].source
    def validate_signature(base64_cert, soft = true)

      document = Nokogiri::XML(self.to_s) do |config|
        config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS
      end

      # create a rexml document
      @working_copy ||= REXML::Document.new(self.to_s).root

      # get signature node
      sig_element = REXML::XPath.first(
          @working_copy,
          "//ds:Signature",
          {"ds"=>DSIG}
      )

      # signature method
      sig_alg_value = REXML::XPath.first(
        sig_element,
        "./ds:SignedInfo/ds:SignatureMethod",
        {"ds"=>DSIG}
      )
      signature_algorithm = algorithm(sig_alg_value)

      # get signature
      base64_signature = REXML::XPath.first(
        sig_element,
        "./ds:SignatureValue",
        {"ds" => DSIG}
      )
      signature = Base64.decode64(OneLogin::RubySaml::Utils.element_text(base64_signature))

      # canonicalization method
      canon_algorithm = canon_algorithm REXML::XPath.first(
        sig_element,
        './ds:SignedInfo/ds:CanonicalizationMethod',
        'ds' => DSIG
      )

      noko_sig_element = document.at_xpath('//ds:Signature', 'ds' => DSIG)
      noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => DSIG)

      canon_string = noko_signed_info_element.canonicalize(canon_algorithm)
      noko_sig_element.remove

      # get inclusive namespaces
      inclusive_namespaces = extract_inclusive_namespaces

      # check digests
      ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG})

      hashed_element = document.at_xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id })

      canon_algorithm = canon_algorithm REXML::XPath.first(
        ref,
        '//ds:CanonicalizationMethod',
        { "ds" => DSIG }
      )
      canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces)

      digest_algorithm = algorithm(REXML::XPath.first(
        ref,
        "//ds:DigestMethod",
        { "ds" => DSIG }
      ))
      hash = digest_algorithm.digest(canon_hashed_element)
      encoded_digest_value = REXML::XPath.first(
        ref,
        "//ds:DigestValue",
        { "ds" => DSIG }
      )
      digest_value = Base64.decode64(OneLogin::RubySaml::Utils.element_text(encoded_digest_value))

      unless digests_match?(hash, digest_value)
        @errors << "Digest mismatch"
        return append_error("Digest mismatch", soft)
      end

      # get certificate object
      cert_text = Base64.decode64(base64_cert)
      cert = OpenSSL::X509::Certificate.new(cert_text)

      # verify signature
      unless cert.public_key.verify(signature_algorithm.new, signature, canon_string)
        return append_error("Key validation error", soft)
      end

      return true
    end

# classMap[].children[].children[].children[].source
    def algorithm(element)
      algorithm = element
      if algorithm.is_a?(REXML::Element)
        algorithm = element.attribute("Algorithm").value
      end

      algorithm = algorithm && algorithm =~ /(rsa-)?sha(.*?)$/i && $2.to_i

      case algorithm
      when 256 then OpenSSL::Digest::SHA256
      when 384 then OpenSSL::Digest::SHA384
      when 512 then OpenSSL::Digest::SHA512
      else
        OpenSSL::Digest::SHA1
      end
    end

# classMap[].children[].children[].children[].source
    def canon_algorithm(element)
      algorithm = element
      if algorithm.is_a?(REXML::Element)
        algorithm = element.attribute('Algorithm').value
      end

      case algorithm
        when "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
             "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
          Nokogiri::XML::XML_C14N_1_0
        when "http://www.w3.org/2006/12/xml-c14n11",
             "http://www.w3.org/2006/12/xml-c14n11#WithComments"
          Nokogiri::XML::XML_C14N_1_1
        else
          Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
      end
    end

# classMap[].children[].children[].children[].source
    def render(context, options)
      render_to_object(context, options).body
    end

# classMap[].children[].children[].children[].comment
# Main render entry point shared by Action View and Action Controller.