}
 
 my @COMMANDS = qw/repair delete rename/;
-usage(1) unless GetOptions(\%CONFIG, qw/config=s quiet|q target=s@ debug help|h/, @COMMANDS);
+usage(1) unless GetOptions(\%CONFIG, qw/config=s quiet|q target=s@ debug help|h watch:i/, @COMMANDS);
 usage(0) if $CONFIG{help};
 my $COMMAND = do {
     my @command = grep {exists $CONFIG{$_}} @COMMANDS;
     $command[0]
 };
 usage(1) if defined $COMMAND and (($COMMAND eq 'delete' and !@ARGV) or $COMMAND eq 'rename' and $#ARGV != 1);
+usage(1) if defined $COMMAND and defined $CONFIG{watch};
+$CONFIG{watch} = 60 if defined $CONFIG{watch} and $CONFIG{watch} == 0;
 @ARGV = map {uc $_ eq 'INBOX' ? 'INBOX' : $_ } @ARGV; # INBOX is case-insensitive
 
 
 #############################################################################
 # Connect to the local and remote IMAP servers
 
+my $LIST = '"" ';
+my @LIST_PARAMS;
+if (!defined $COMMAND or $COMMAND eq 'repair') {
+    $LIST  = '('.uc($CONF->{_}->{'list-select-opts'}).') '.$LIST if defined $CONF->{_}->{'list-select-opts'};
+    $LIST .= (defined $CONF->{_}->{'list-mailbox'} ? '('.$CONF->{_}->{'list-mailbox'}.')' : '*') unless @ARGV;
+    @LIST_PARAMS = ('SUBSCRIBED', 'STATUS (UIDVALIDITY UIDNEXT HIGHESTMODSEQ)');
+}
+$LIST .= $#ARGV == 0 ? Net::IMAP::InterIMAP::quote($ARGV[0])
+       : ('('.join(' ',map {Net::IMAP::InterIMAP::quote($_)} @ARGV).')') if @ARGV;
+
+
 my $IMAP;
 foreach my $name (qw/local remote/) {
     my %config = %{$CONF->{$name}};
     # XXX We shouldn't need to ask for STATUS responses here, and use
     #     NOTIFY's STATUS indicator instead.  However Dovecot violates RFC
     #     5464: http://dovecot.org/pipermail/dovecot/2015-July/101474.html
-
-    my $list = '"" ';
-    my @params;
-    if (!defined $COMMAND or $COMMAND eq 'repair') {
-        $list  = '('.uc($CONF->{_}->{'list-select-opts'}).') '.$list if defined $CONF->{_}->{'list-select-opts'};
-        $list .= (defined $CONF->{_}->{'list-mailbox'} ? '('.$CONF->{_}->{'list-mailbox'}.')' : '*') unless @ARGV;
-        @params = ('SUBSCRIBED', 'STATUS (UIDVALIDITY UIDNEXT HIGHESTMODSEQ)');
-    }
-    $list .= $#ARGV == 0 ? Net::IMAP::InterIMAP::quote($ARGV[0])
-           : ('('.join(' ',map {Net::IMAP::InterIMAP::quote($_)} @ARGV).')') if @ARGV;
-    @{$IMAP->{$name}}{qw/mailboxes delims/} = $client->list($list, @params);
 }
 
+@{$IMAP->{$_}}{qw/mailboxes delims/} = $IMAP->{$_}->{client}->list($LIST, @LIST_PARAMS) for qw/local remote/;
 
 ##############################################################################
 #
 # Synchronize mailbox and subscription lists
 
 my @MAILBOXES;
-{
+sub sync_mailbox_list() {
     my %mailboxes;
     $mailboxes{$_} = 1 foreach keys %{$IMAP->{local}->{mailboxes}};
     $mailboxes{$_} = 1 foreach keys %{$IMAP->{remote}->{mailboxes}};
         }
     }
 }
+
+sync_mailbox_list();
 my ($lIMAP, $rIMAP) = map {$IMAP->{$_}->{client}} qw/local remote/;
-undef $IMAP;
 
 
 #############################################################################
         }
     }
     # clean state!
-    exit 0 unless defined $COMMAND and $COMMAND eq 'watch';
-    wait_notifications(900);
+    exit 0 unless $CONFIG{watch};
+
+    # we need to issue a NOOP command or go back to AUTH state since the
+    # LIST command may not report the correct HIGHESTMODSEQ value for
+    # the mailbox currently selected.
+    if (defined $MAILBOX) {
+        # Prefer UNSELECT over NOOP commands as it requires a single command per cycle
+        if ($lIMAP->incapable('UNSELECT') or $rIMAP->incapable('UNSELECT')) {
+            $_->noop() foreach ($lIMAP, $rIMAP);
+        } else {
+            $_->unselect() foreach ($lIMAP, $rIMAP);
+            undef $MAILBOX;
+        }
+    }
+
+    sleep $CONFIG{watch};
+    # Refresh the mailbox list and status
+    @{$IMAP->{$_}}{qw/mailboxes delims/} = $IMAP->{$_}->{client}->list($LIST, @LIST_PARAMS) for qw/local remote/;
+    sync_mailbox_list();
 }
 
 END {