ZimbraLog.test.debug("testTagSearch()");
    public void testTagSearch()    throws Exception {        ZimbraLog.test.debug("testTagSearch()");        // Create tags        mTags = new Tag[4];        for (int i = 0; i < mTags.length; i++) {            mTags[i] = mMbox.createTag(null, TAG_PREFIX + (i + 1), (byte)0);        }        refresh();        // First assign T1 to the entire conversation, then remove it from M2-M4        mMbox.alterTag(null, mConv.getId(), mConv.getType(), mTags[0].getId(), true);        mMbox.alterTag(null, mMessage2.getId(), mMessage2.getType(), mTags[0].getId(), false);        mMbox.alterTag(null, mMessage3.getId(), mMessage3.getType(), mTags[0].getId(), false);        mMbox.alterTag(null, mMessage4.getId(), mMessage4.getType(), mTags[0].getId(), false);                // Assign tags:        //   M1: T1        //   M2: T2        //   M3: T2, T3        //   M4: no tags        mMbox.alterTag(null, mMessage2.getId(), mMessage2.getType(), mTags[1].getId(), true);        mMbox.alterTag(null, mMessage3.getId(), mMessage3.getType(), mTags[1].getId(), true);        mMbox.alterTag(null, mMessage3.getId(), mMessage3.getType(), mTags[2].getId(), true);        refresh();                // tag:TestTags1 -> (M1)        Set ids = search("tag:" + mTags[0].getName(), MailItem.TYPE_MESSAGE);        assertEquals("1: result size", 1, ids.size());        assertTrue("1: no message 1", ids.contains(new Integer(mMessage1.getId())));                // tag:TestTags1 tag:TestTags2 -> (M1,M2,M3)        ids = search("tag:" + mTags[0].getName() + " tag:" + mTags[1].getName(), MailItem.TYPE_MESSAGE);        assertEquals("2: result size", 3, ids.size());        assertTrue("2: no message 1", ids.contains(new Integer(mMessage1.getId())));        assertTrue("2: no message 2", ids.contains(new Integer(mMessage2.getId())));        assertTrue("2: no message 3", ids.contains(new Integer(mMessage3.getId())));                // not tag:TestTags1 -> (M2,M3,M4,...)        ids = search("not tag:" + mTags[0].getName(), MailItem.TYPE_MESSAGE);        assertFalse("3: message 1 found", ids.contains(new Integer(mMessage1.getId())));        assertTrue("3: no message 2", ids.contains(new Integer(mMessage2.getId())));        assertTrue("3: no message 3", ids.contains(new Integer(mMessage3.getId())));        assertTrue("3: no message 4", ids.contains(new Integer(mMessage4.getId())));                // not tag:TestTags2 not tag:TestTags3 -> (M1,M4,...)        ids = search("not tag:" + mTags[1].getName() + " not tag:" + mTags[2].getName(), MailItem.TYPE_MESSAGE);        assertTrue("4: no message 1", ids.contains(new Integer(mMessage1.getId())));        assertFalse("4: contains message 2", ids.contains(new Integer(mMessage2.getId())));        assertFalse("4: contains message 3", ids.contains(new Integer(mMessage3.getId())));        assertTrue("4: no message 4", ids.contains(new Integer(mMessage4.getId())));                // tag:TestTags2 not tag:TestTags3 -> (M2)        ids = search("tag:" + mTags[1].getName() + " not tag:" + mTags[2].getName(), MailItem.TYPE_MESSAGE);        assertFalse("5: message 1 found", ids.contains(new Integer(mMessage1.getId())));        assertTrue("5: no message 2", ids.contains(new Integer(mMessage2.getId())));        assertFalse("5: contains message 3", ids.contains(new Integer(mMessage3.getId())));        assertFalse("5: contains message 4", ids.contains(new Integer(mMessage4.getId())));                // tag:TestTags4 -> ()        ids = search("tag:" + mTags[3].getName(), MailItem.TYPE_MESSAGE);        assertEquals("6: search should have returned no results", 0, ids.size());    }