# File lib/rack/session/memcache.rb, line 67
      def set_session(env, session_id, new_session, options)
        expiry = options[:expire_after]
        expiry = expiry.nil? ? 0 : expiry + 1

        @mutex.lock if env['rack.multithread']
        if options[:renew] or options[:drop]
          @pool.delete session_id
          return false if options[:drop]
          session_id = generate_sid
          @pool.add session_id, {} # so we don't worry about cache miss on #set
        end

        session = @pool.get(session_id) || {}
        old_session = new_session.instance_variable_get '@old'
        old_session = old_session ? Marshal.load(old_session) : {}

        unless Hash === old_session and Hash === new_session
          env['rack.errors'].
            puts 'Bad old_session or new_session sessions provided.'
        else # merge sessions
          # alterations are either update or delete, making as few changes as
          # possible to prevent possible issues.

          # removed keys
          delete = old_session.keys - new_session.keys
          if $VERBOSE and not delete.empty?
            env['rack.errors'].
              puts "//@#{session_id}: delete #{delete*','}"
          end
          delete.each{|k| session.delete k }

          # added or altered keys
          update = new_session.keys.
            select{|k| new_session[k] != old_session[k] }
          if $VERBOSE and not update.empty?
            env['rack.errors'].puts "//@#{session_id}: update #{update*','}"
          end
          update.each{|k| session[k] = new_session[k] }
        end

        @pool.set session_id, session, expiry
        return session_id
      rescue MemCache::MemCacheError, Errno::ECONNREFUSED
        # MemCache server cannot be contacted
        warn "#{self} is unable to find memcached server."
        warn $!.inspect
        return false
      ensure
        @mutex.unlock if @mutex.locked?
      end