@Override
    public void setFlags(List<? extends Message> messages, final Set<Flag> flags, boolean value)
        throws MessagingException {
      if (!value || !flags.contains(Flag.DELETED)) {
        /*
         * The only flagging we support is setting the Deleted flag.
         */
        return;
      }
      List<String> uids = new ArrayList<String>();
      try {
        for (Message message : messages) {
          uids.add(message.getUid());
        }

        indexUids(uids);
      } catch (IOException ioe) {
        throw new MessagingException("Could not get message number for uid " + uids, ioe);
      }
      for (Message message : messages) {

        Integer msgNum = mUidToMsgNumMap.get(message.getUid());
        if (msgNum == null) {
          MessagingException me =
              new MessagingException(
                  "Could not delete message "
                      + message.getUid()
                      + " because no msgNum found; permanent error");
          me.setPermanentFailure(true);
          throw me;
        }
        executeSimpleCommand(String.format(DELE_COMMAND + " %s", msgNum));
      }
    }
 private void fetchEnvelope(
     List<Pop3Message> messages, MessageRetrievalListener<Pop3Message> listener)
     throws IOException, MessagingException {
   int unsizedMessages = 0;
   for (Message message : messages) {
     if (message.getSize() == -1) {
       unsizedMessages++;
     }
   }
   if (unsizedMessages == 0) {
     return;
   }
   if (unsizedMessages < 50 && mMessageCount > 5000) {
     /*
      * In extreme cases we'll do a command per message instead of a bulk request
      * to hopefully save some time and bandwidth.
      */
     for (int i = 0, count = messages.size(); i < count; i++) {
       Pop3Message message = messages.get(i);
       if (listener != null) {
         listener.messageStarted(message.getUid(), i, count);
       }
       String response =
           executeSimpleCommand(
               String.format(
                   Locale.US, LIST_COMMAND + " %d", mUidToMsgNumMap.get(message.getUid())));
       String[] listParts = response.split(" ");
       // int msgNum = Integer.parseInt(listParts[1]);
       int msgSize = Integer.parseInt(listParts[2]);
       message.setSize(msgSize);
       if (listener != null) {
         listener.messageFinished(message, i, count);
       }
     }
   } else {
     Set<String> msgUidIndex = new HashSet<String>();
     for (Message message : messages) {
       msgUidIndex.add(message.getUid());
     }
     int i = 0, count = messages.size();
     String response = executeSimpleCommand(LIST_COMMAND);
     while ((response = readLine()) != null) {
       if (response.equals(".")) {
         break;
       }
       String[] listParts = response.split(" ");
       int msgNum = Integer.parseInt(listParts[0]);
       int msgSize = Integer.parseInt(listParts[1]);
       Pop3Message pop3Message = mMsgNumToMsgMap.get(msgNum);
       if (pop3Message != null && msgUidIndex.contains(pop3Message.getUid())) {
         if (listener != null) {
           listener.messageStarted(pop3Message.getUid(), i, count);
         }
         pop3Message.setSize(msgSize);
         if (listener != null) {
           listener.messageFinished(pop3Message, i, count);
         }
         i++;
       }
     }
   }
 }
 /**
  * Fetch the items contained in the FetchProfile into the given set of Messages in as efficient
  * a manner as possible.
  *
  * @param messages
  * @param fp
  * @throws MessagingException
  */
 @Override
 public void fetch(
     List<Pop3Message> messages, FetchProfile fp, MessageRetrievalListener<Pop3Message> listener)
     throws MessagingException {
   if (messages == null || messages.isEmpty()) {
     return;
   }
   List<String> uids = new ArrayList<String>();
   for (Message message : messages) {
     uids.add(message.getUid());
   }
   try {
     indexUids(uids);
   } catch (IOException ioe) {
     throw new MessagingException("fetch", ioe);
   }
   try {
     if (fp.contains(FetchProfile.Item.ENVELOPE)) {
       /*
        * We pass the listener only if there are other things to do in the
        * FetchProfile. Since fetchEnvelop works in bulk and eveything else
        * works one at a time if we let fetchEnvelope send events the
        * event would get sent twice.
        */
       fetchEnvelope(messages, fp.size() == 1 ? listener : null);
     }
   } catch (IOException ioe) {
     throw new MessagingException("fetch", ioe);
   }
   for (int i = 0, count = messages.size(); i < count; i++) {
     Pop3Message pop3Message = messages.get(i);
     try {
       if (listener != null && !fp.contains(FetchProfile.Item.ENVELOPE)) {
         listener.messageStarted(pop3Message.getUid(), i, count);
       }
       if (fp.contains(FetchProfile.Item.BODY)) {
         fetchBody(pop3Message, -1);
       } else if (fp.contains(FetchProfile.Item.BODY_SANE)) {
         /*
          * To convert the suggested download size we take the size
          * divided by the maximum line size (76).
          */
         if (mStoreConfig.getMaximumAutoDownloadMessageSize() > 0) {
           fetchBody(pop3Message, (mStoreConfig.getMaximumAutoDownloadMessageSize() / 76));
         } else {
           fetchBody(pop3Message, -1);
         }
       } else if (fp.contains(FetchProfile.Item.STRUCTURE)) {
         /*
          * If the user is requesting STRUCTURE we are required to set the body
          * to null since we do not support the function.
          */
         pop3Message.setBody(null);
       }
       if (listener != null && !(fp.contains(FetchProfile.Item.ENVELOPE) && fp.size() == 1)) {
         listener.messageFinished(pop3Message, i, count);
       }
     } catch (IOException ioe) {
       throw new MessagingException("Unable to fetch message", ioe);
     }
   }
 }