while (!modified.isEmpty()) {
delta: while (!modified.isEmpty()) {
    private void deltaSync(ZimbraSoapContext zsc, Element response, Mailbox mbox, long begin, boolean typedDeletes)    throws ServiceException {        if (begin >= mbox.getLastChangeID())            return;        OperationContext octxt = zsc.getOperationContext();        // first, fetch deleted items        MailItem.TypedIdList tombstones = mbox.getTombstoneSet(begin);        Element eDeleted = response.addElement(MailService.E_DELETED);        // then, handle created/modified folders        if (zsc.isDelegatedRequest()) {            //  first, make sure that something changed...            if (!mbox.getModifiedFolders(begin).isEmpty()) {                // special-case the folder hierarchy for delegated delta sync                Set<Folder> visible = mbox.getVisibleFolders(octxt);                boolean anyFolders = folderSync(zsc, response, mbox, mbox.getFolderById(null, DEFAULT_FOLDER_ID), visible, SyncPhase.DELTA);                // if no folders are visible, add an empty "<folder/>" as a hint                if (!anyFolders)                    response.addElement(MailService.E_FOLDER);            }        } else {            for (Folder folder : mbox.getModifiedFolders(begin))                ToXML.encodeFolder(response, zsc, folder, Change.ALL_FIELDS);        }        // next, handle created/modified tags        for (Tag tag : mbox.getModifiedTags(octxt, begin))            ToXML.encodeTag(response, zsc, tag, Change.ALL_FIELDS);        // finally, handle created/modified "other items"        Pair<List<Integer>,MailItem.TypedIdList> changed = mbox.getModifiedItems(octxt, begin);        List<Integer> modified = changed.getFirst();        while (!modified.isEmpty()) {            List batch = modified.subList(0, Math.min(modified.size(), FETCH_BATCH_SIZE));            for (MailItem item : mbox.getItemById(octxt, modified, MailItem.TYPE_UNKNOWN)) {                //  For items in the system, if the content has changed since the user last sync'ed                 //      (because it was edited or created), just send back the folder ID and saved date --                //      the client will request the whole object out of band -- potentially using the                 //      content servlet's "include metadata in headers" hack.                //  If it's just the metadata that changed, send back the set of mutable attributes.                boolean created = item.getSavedSequence() > begin;                ToXML.encodeItem(response, zsc, item, created ? Change.MODIFIED_FOLDER | Change.MODIFIED_CONFLICT : MUTABLE_FIELDS);            }            batch.clear();        }        // items that have been altered in non-visible folders will be returned as "deleted" in order to handle moves        if (changed.getSecond() != null)            tombstones.add(changed.getSecond());        // cleanup: only return a <deleted> element if we're sending back deleted item ids        if (tombstones == null || tombstones.isEmpty()) {            eDeleted.detach();        } else {            StringBuilder deleted = new StringBuilder(), typed = new StringBuilder();            for (Map.Entry<Byte,List<Integer>> entry : tombstones) {                typed.setLength(0);                for (Integer id : entry.getValue()) {                    deleted.append(deleted.length() == 0 ? "" : ",").append(id);                    if (typedDeletes)                        typed.append(typed.length() == 0 ? "" : ",").append(id);                }                if (typedDeletes) {                    // only add typed delete information if the client explicitly requested it                    String eltName = elementNameForType(entry.getKey());                    if (eltName != null)                        eDeleted.addElement(eltName).addAttribute(MailService.A_IDS, typed.toString());                }            }            eDeleted.addAttribute(MailService.A_IDS, deleted.toString());        }    }