indexDocument(mbox, redo, itemId, pd);
indexDocument(mbox, redo, deleteFirst, itemId, pd);
    public void indexItem(Mailbox mbox, int itemId, byte itemType, long timestamp, boolean noRedo)    throws IOException, ServiceException {        MailItem item;        try {            item = mbox.getItemById(null, itemId, itemType);        } catch (MailServiceException.NoSuchItemException e) {            // Because index commits are batched, during mailbox restore            // it's possible to see the commit record of indexing operation            // after the delete operation on the item being indexed.            // (delete followed by edit, for example)            // We can't distinguish this legitimate case from a case of            // really missing the item being indexed due to unexpected            // problem.  So just ignore the NoSuchItemException.            return;        }        IndexItem redo = null;        if (!noRedo) {            redo = new IndexItem(mbox.getId(), item.getId(), itemType);            redo.start(System.currentTimeMillis());            redo.log();            redo.allowCommit();        }        switch (itemType) {            case MailItem.TYPE_APPOINTMENT:            case MailItem.TYPE_TASK:                break;            case MailItem.TYPE_DOCUMENT:            case MailItem.TYPE_WIKI:                try {                    com.zimbra.cs.mailbox.Document document = (com.zimbra.cs.mailbox.Document)item;                    ParsedDocument pd = new ParsedDocument(document.getBlob().getBlob().getFile(),                                document.getName(),                                 document.getContentType(),                                timestamp);                    indexDocument(mbox, redo, itemId, pd);                } catch (IOException e) {                    throw ServiceException.FAILURE("indexDocument caught Exception", e);                }                break;            case MailItem.TYPE_MESSAGE:                InputStream is = mbox.getMessageById(null, itemId).getRawMessage();                MimeMessage mm;                try {                    mm = new Mime.FixedMimeMessage(JMSession.getSession(), is);                    ParsedMessage pm = new ParsedMessage(mm, timestamp, mbox.attachmentsIndexingEnabled());                    indexMessage(mbox, redo, itemId, pm);                } catch (Throwable e) {                    mLog.warn("Skipping indexing; Unable to parse message " + itemId + ": " + e.toString(), e);                    // Eat up all errors during message analysis.  Throwing                    // anything here will force server halt during crash                    // recovery.  Because we can't possibly predict all                    // data-dependent message parse problems, we opt to live                    // with unindexed messages rather than P1 support calls.                    // Write abort record for this item, to prevent repeat calls                    // to index this unindexable item.                    if (redo != null)                        redo.abort();                } finally {                    is.close();                }                break;            case MailItem.TYPE_CONTACT:                indexContact(mbox, redo, itemId, (Contact) item);                break;            case MailItem.TYPE_NOTE:                indexNote(mbox, redo, itemId, (Note) item);                break;            default:                if (redo != null)                    redo.abort();            throw ServiceException.FAILURE("Invalid item type for indexing: type=" + itemType, null);        }    }