# File lib/larch/imap/mailbox.rb, line 203
  def scan
    now = Time.now.to_i
    return if @last_scan && (now - @last_scan) < SCAN_INTERVAL

    first_scan = @last_scan.nil?
    @last_scan = now

    # Compare the mailbox's current status with its last known status.
    begin
      return unless status = imap_status('MESSAGES', 'UIDNEXT', 'UIDVALIDITY')
    rescue Error => e
      return if @imap.options[:create_mailbox]
      raise
    end

    flag_range = nil
    full_range = nil

    if @db_mailbox.uidvalidity && @db_mailbox.uidnext &&
        status['UIDVALIDITY'] == @db_mailbox.uidvalidity

      # The UIDVALIDITY is the same as what we saw last time we scanned this
      # mailbox, which means that all the existing messages in the database are
      # still valid. We only need to request headers for new messages.
      #
      # If this is the first scan of this mailbox during this Larch session,
      # then we'll also update the flags of all messages in the mailbox.

      flag_range = 1...@db_mailbox.uidnext if first_scan
      full_range = @db_mailbox.uidnext...status['UIDNEXT']

    else

      # The UIDVALIDITY has changed or this is the first time we've scanned this
      # mailbox (ever). Either way, all existing messages in the database are no
      # longer valid, so we have to throw them out and re-request everything.

      @db_mailbox.remove_all_messages
      full_range = 1...status['UIDNEXT']
    end

    @db_mailbox.update(:uidvalidity => status['UIDVALIDITY'])

    need_flag_scan = flag_range && flag_range.max && flag_range.min && flag_range.max - flag_range.min > 0
    need_full_scan = full_range && full_range.max && full_range.min && full_range.max - full_range.min > 0

    return unless need_flag_scan || need_full_scan

    fetch_flags(flag_range) if need_flag_scan

    if need_full_scan
      fetch_headers(full_range, {
        :progress_start => @db_mailbox.messages_dataset.count + 1,
        :progress_total => status['MESSAGES']
      })
    end

    @db_mailbox.update(:uidnext => status['UIDNEXT'])
    return
  end