synchronized public void indexContact(Mailbox mbox, IndexItem redo, int mailItemId, Contact contact)
synchronized public void indexContact(Mailbox mbox, IndexItem redo, boolean deleteFirst, int mailItemId, Contact contact)
    synchronized public void indexContact(Mailbox mbox, IndexItem redo, int mailItemId, Contact contact)    throws ServiceException {        initAnalyzer(mbox);        mLog.info("indexContact("+contact+")");        try {            StringBuffer contentText = new StringBuffer();            Map m = contact.getFields();            for (Iterator it = m.values().iterator(); it.hasNext(); )            {                String cur = (String)it.next();                contentText.append(cur);                contentText.append(' ');            }            // FIXME: this is very slow, and unnecessary in many instances (e.g. a contact is new).  Create some kind of a flag            // so we don't try to do this when a contact is known to be new -- such as when re-indexing.            try {                deleteDocuments(new int[] { mailItemId });            } catch (IOException e1) {                mLog.debug("indexContact ignored IOException deleting documents (index does not exist yet)");            }            Document doc = new Document();            String subj = contact.getFileAsString().toLowerCase();            String name = (subj.length() > DbMailItem.MAX_SENDER_LENGTH ? subj.substring(0, DbMailItem.MAX_SENDER_LENGTH) : subj);            StringBuffer emailStrBuf = new StringBuffer();            List emailList = contact.getEmailAddresses();            for (Iterator iter = emailList.iterator(); iter.hasNext();) {                String cur = (String)(iter.next());                emailStrBuf.append(cur);                emailStrBuf.append(' ');            }            String emailStr = emailStrBuf.toString();            contentText.append(ZimbraAnalyzer.getAllTokensConcatenated(LuceneFields.L_H_TO, emailStr));            /* put the email addresses in the "To" field so they can be more easily searched */            doc.add(Field.UnStored(LuceneFields.L_H_TO, emailStr));            doc.add(Field.UnStored(LuceneFields.L_CONTENT, contentText.toString()));            doc.add(Field.UnStored(LuceneFields.L_H_SUBJECT, subj));            doc.add(Field.Keyword(LuceneFields.L_MAILBOX_BLOB_ID, Integer.toString(mailItemId)));            doc.add(Field.Text(LuceneFields.L_PARTNAME, LuceneFields.L_PARTNAME_CONTACT));            doc.add(new Field(LuceneFields.L_SORT_SUBJECT, subj.toUpperCase(), true/*store*/, true/*index*/, false /*token*/));            doc.add(new Field(LuceneFields.L_SORT_NAME, name.toUpperCase(), false/*store*/, true/*index*/, false /*token*/));            addDocument(redo, doc, mailItemId, contact.getDate(), false);        } catch (IOException ioe) {            throw ServiceException.FAILURE("indexContact caught IOException", ioe);        }    }    