    # File lib/phusion_passenger/utils.rb, line 194
            def prepare_app_process(startup_file, options)
                    options["app_root"] = canonicalize_path(options["app_root"])
                    Dir.chdir(options["app_root"])

                    lower_privilege(startup_file, options)
                    path, is_parent = check_directory_tree_permissions(options["app_root"])
                    if path
                            username = Etc.getpwuid(Process.euid).name
                            groupname = Etc.getgrgid(Process.egid).name
                            message = "This application process is currently running as " +
                                    "user '#{username}' and group '#{groupname}' and must be " +
                                    "able to access its application root directory " +
                                    "'#{options["app_root"]}'. "
                            if is_parent
                                    message << "However the parent directory '#{path}' " +
                                            "has wrong permissions, thereby preventing " +
                                            "this process from accessing its application " +
                                            "root directory. Please fix the permissions " +
                                            "of the directory '#{path}' first."
                            else
                                    message << "However this directory is not accessible " +
                                            "because it has wrong permissions. Please fix " +
                                            "these permissions first."
                            end
                            raise(message)
                    end

                    ENV["RAILS_ENV"] = ENV["RACK_ENV"] = options["environment"]

                    base_uri = options["base_uri"]
                    if base_uri && !base_uri.empty? && base_uri != "/"
                            ENV["RAILS_RELATIVE_URL_ROOT"] = base_uri
                            ENV["RACK_BASE_URI"] = base_uri
                    end

                    encoded_environment_variables = options["environment_variables"]
                    if encoded_environment_variables
                            env_vars_string = encoded_environment_variables.unpack("m").first
                            env_vars_array  = env_vars_string.split("\0", -1)
                            env_vars_array.pop
                            env_vars = Hash[*env_vars_array]
                            env_vars.each_pair do |key, value|
                                    ENV[key] = value
                            end
                    end

                    # Instantiate the analytics logger if requested. Can be nil.
                    require 'phusion_passenger/analytics_logger'
                    options["analytics_logger"] = AnalyticsLogger.new_from_options(options)

                    # Make sure RubyGems uses any new environment variable values
                    # that have been set now (e.g. $HOME, $GEM_HOME, etc) and that
                    # it is able to detect newly installed gems.
                    Gem.clear_paths

                    # Because spawned app processes exit using #exit!, #at_exit
                    # blocks aren't called. Here we ninja patch Kernel so that
                    # we can call #at_exit blocks during app process shutdown.
                    class << Kernel
                            def passenger_call_at_exit_blocks
                                    @passenger_at_exit_blocks ||= []
                                    @passenger_at_exit_blocks.reverse_each do |block|
                                            block.call
                                    end
                            end

                            def passenger_at_exit(&block)
                                    @passenger_at_exit_blocks ||= []
                                    @passenger_at_exit_blocks << block
                                    return block
                            end
                    end
                    Kernel.class_eval do
                            def at_exit(&block)
                                    return Kernel.passenger_at_exit(&block)
                            end
                    end

                    # Rack::ApplicationSpawner depends on the 'rack' library, but the app
                    # might want us to use a bundled version instead of a
                    # gem/apt-get/yum/whatever-installed version. Therefore we must setup
                    # the correct load paths before requiring 'rack'.
                    #
                    # The most popular tool for bundling dependencies is Bundler. Bundler
                    # works as follows:
                    # - If the bundle is locked then a file .bundle/environment.rb exists
                    #   which will setup the load paths.
                    # - If the bundle is not locked then the load paths must be set up by
                    #   calling Bundler.setup.
                    # - Rails 3's boot.rb automatically loads .bundle/environment.rb or
                    #   calls Bundler.setup if that's not available.
                    # - Other Rack apps might not have a boot.rb but we still want to setup
                    #   Bundler.
                    # - Some Rails 2 apps might have explicitly added Bundler support.
                    #   These apps call Bundler.setup in their preinitializer.rb.
                    #
                    # So the strategy is as follows:

                    # Our strategy might be completely unsuitable for the app or the
                    # developer is using something other than Bundler, so we let the user
                    # manually specify a load path setup file.
                    if options["load_path_setup_file"]
                            require File.expand_path(options["load_path_setup_file"])

                    # The app developer may also override our strategy with this magic file.
                    elsif File.exist?('config/setup_load_paths.rb')
                            require File.expand_path('config/setup_load_paths')

                    # If the Bundler lock environment file exists then load that. If it
                    # exists then there's a 99.9% chance that loading it is the correct
                    # thing to do.
                    elsif File.exist?('.bundle/environment.rb')
                            require File.expand_path('.bundle/environment')

                    # If the Bundler environment file doesn't exist then there are two
                    # possibilities:
                    # 1. Bundler is not used, in which case we don't have to do anything.
                    # 2. Bundler *is* used, but the gems are not locked and we're supposed
                    #    to call Bundler.setup.
                    #
                    # The existence of Gemfile indicates whether (2) is true:
                    elsif File.exist?('Gemfile')
                            # In case of Rails 3, config/boot.rb already calls Bundler.setup.
                            # However older versions of Rails may not so loading boot.rb might
                            # not be the correct thing to do. To be on the safe side we
                            # call Bundler.setup ourselves; calling Bundler.setup twice is
                            # harmless. If this isn't the correct thing to do after all then
                            # there's always the load_path_setup_file option and
                            # setup_load_paths.rb.
                            require 'rubygems'
                            require 'bundler'
                            Bundler.setup
                    end

                    # Bundler might remove Phusion Passenger from the load path in its zealous
                    # attempt to un-require RubyGems, so here we put Phusion Passenger back
                    # into the load path. This must be done before loading the app's startup
                    # file because the app might require() Phusion Passenger files.
                    if !$LOAD_PATH.include?(LIBDIR)
                            $LOAD_PATH.unshift(LIBDIR)
                            $LOAD_PATH.uniq!
                    end

                    # !!! NOTE !!!
                    # If the app is using Bundler then any dependencies required past this
                    # point must be specified in the Gemfile. Like ruby-debug if debugging is on...

                    PhusionPassenger._spawn_options = options
            end