17e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki/*
27e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * Copyright (C) 2010 The Android Open Source Project
37e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki *
47e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License");
57e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * you may not use this file except in compliance with the License.
67e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * You may obtain a copy of the License at
77e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki *
87e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki *      http://www.apache.org/licenses/LICENSE-2.0
97e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki *
107e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * Unless required by applicable law or agreed to in writing, software
117e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS,
127e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * See the License for the specific language governing permissions and
147e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * limitations under the License.
157e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki */
167e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
177e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onukipackage com.android.email.mail.store.imap;
187e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
197e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onukiimport java.util.ArrayList;
207e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
217e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki/**
227e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki * Class represents an IMAP list.
237e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki */
247e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onukipublic class ImapList extends ImapElement {
257e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
267e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * {@link ImapList} representing an empty list.
277e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
287e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public static final ImapList EMPTY = new ImapList() {
290fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki        @Override public void destroy() {
300fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki            // Don't call super.destroy().
310fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki            // It's a shared object.  We don't want the mDestroyed to be set on this.
320fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki        }
330fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki
347e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        @Override void add(ImapElement e) {
357e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            throw new RuntimeException();
367e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
377e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    };
387e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
390fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki    private ArrayList<ImapElement> mList = new ArrayList<ImapElement>();
407e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
417e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /* package */ void add(ImapElement e) {
427e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        if (e == null) {
437e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            throw new RuntimeException("Can't add null");
447e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
457e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        mList.add(e);
467e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
477e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
487e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    @Override
497e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final boolean isString() {
507e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return false;
517e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
527e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
537e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    @Override
547e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final boolean isList() {
557e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return true;
567e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
577e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
587e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final int size() {
597e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return mList.size();
607e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
617e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
627e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final boolean isEmpty() {
637e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return size() == 0;
647e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
657e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
667e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
677e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return true if the element at {@code index} exists, is string, and equals to {@code s}.
687e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * (case insensitive)
697e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
707e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final boolean is(int index, String s) {
717e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return is(index, s, false);
727e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
737e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
747e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
757e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Same as {@link #is(int, String)}, but does the prefix match if {@code prefixMatch}.
767e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
777e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final boolean is(int index, String s, boolean prefixMatch) {
787e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        if (!prefixMatch) {
797e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            return getStringOrEmpty(index).is(s);
807e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        } else {
817e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            return getStringOrEmpty(index).startsWith(s);
827e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
837e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
847e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
857e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
867e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return the element at {@code index}.
877e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * If {@code index} is out of range, returns {@link ImapElement#NONE}.
887e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
897e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapElement getElementOrNone(int index) {
907e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return (index >= mList.size()) ? ImapElement.NONE : mList.get(index);
917e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
927e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
937e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
947e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return the element at {@code index} if it's a list.
957e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * If {@code index} is out of range or not a list, returns {@link ImapList#EMPTY}.
967e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
977e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapList getListOrEmpty(int index) {
987e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        ImapElement el = getElementOrNone(index);
997e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return el.isList() ? (ImapList) el : EMPTY;
1007e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1017e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1027e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1037e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return the element at {@code index} if it's a string.
1047e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * If {@code index} is out of range or not a string, returns {@link ImapString#EMPTY}.
1057e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1067e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapString getStringOrEmpty(int index) {
1077e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        ImapElement el = getElementOrNone(index);
1087e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return el.isString() ? (ImapString) el : ImapString.EMPTY;
1097e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1107e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1117e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1127e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return an element keyed by {@code key}.  Return null if not found.  {@code key} has to be
1137e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * at an even index.
1147e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1157e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /* package */ final ImapElement getKeyedElementOrNull(String key, boolean prefixMatch) {
1167e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        for (int i = 1; i < size(); i += 2) {
1177e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            if (is(i-1, key, prefixMatch)) {
1187e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki                return mList.get(i);
1197e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            }
1207e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
1217e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return null;
1227e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1237e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1247e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1257e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return an {@link ImapList} keyed by {@code key}.
1267e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return {@link ImapList#EMPTY} if not found.
1277e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1287e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapList getKeyedListOrEmpty(String key) {
1297e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return getKeyedListOrEmpty(key, false);
1307e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1317e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1327e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1337e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return an {@link ImapList} keyed by {@code key}.
1347e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return {@link ImapList#EMPTY} if not found.
1357e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1367e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapList getKeyedListOrEmpty(String key, boolean prefixMatch) {
1377e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        ImapElement e = getKeyedElementOrNull(key, prefixMatch);
1387e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return (e != null) ? ((ImapList) e) : ImapList.EMPTY;
1397e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1407e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1417e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1427e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return an {@link ImapString} keyed by {@code key}.
1437e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return {@link ImapString#EMPTY} if not found.
1447e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1457e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapString getKeyedStringOrEmpty(String key) {
1467e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return getKeyedStringOrEmpty(key, false);
1477e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1487e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1497e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1507e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return an {@link ImapString} keyed by {@code key}.
1517e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return {@link ImapString#EMPTY} if not found.
1527e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1537e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final ImapString getKeyedStringOrEmpty(String key, boolean prefixMatch) {
1547e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        ImapElement e = getKeyedElementOrNull(key, prefixMatch);
1557e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return (e != null) ? ((ImapString) e) : ImapString.EMPTY;
1567e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1577e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1587e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1597e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return true if it contains {@code s}.
1607e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1617e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final boolean contains(String s) {
1627e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        for (int i = 0; i < size(); i++) {
1637e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            if (getStringOrEmpty(i).is(s)) {
1647e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki                return true;
1657e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            }
1667e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
1677e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return false;
1687e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1697e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1707e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    @Override
1717e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public void destroy() {
1720fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki        if (mList != null) {
1730fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki            for (ImapElement e : mList) {
1740fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki                e.destroy();
1750fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki            }
1760fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki            mList = null;
1777e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
1780fd444b0b4c07ac1545e0edc64b54fd738edfc94Makoto Onuki        super.destroy();
1797e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1807e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1817e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    @Override
1827e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public String toString() {
1837e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return mList.toString();
1847e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1857e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1867e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1877e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Return the text representations of the contents concatenated with ",".
1887e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
1897e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public final String flatten() {
1907e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return flatten(new StringBuilder()).toString();
1917e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
1927e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
1937e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    /**
1947e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Returns text representations (i.e. getString()) of contents joined together with
1957e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * "," as the separator.
1967e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     *
1977e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * Only used for building the capability string passed to vendor policies.
1987e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     *
1997e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * We can't use toString(), because it's for debugging (meaning the format may change any time),
2007e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     * and it won't expand literals.
2017e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki     */
2027e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    private final StringBuilder flatten(StringBuilder sb) {
2037e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        sb.append('[');
2047e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        for (int i = 0; i < mList.size(); i++) {
2057e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            if (i > 0) {
2067e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki                sb.append(',');
2077e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            }
2087e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            final ImapElement e = getElementOrNone(i);
2097e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            if (e.isList()) {
2107e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki                getListOrEmpty(i).flatten(sb);
2117e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            } else if (e.isString()) {
2127e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki                sb.append(getStringOrEmpty(i).getString());
2137e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            }
2147e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
2157e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        sb.append(']');
2167e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return sb;
2177e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
2187e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki
2197e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    @Override
2207e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    public boolean equalsForTest(ImapElement that) {
2217e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        if (!super.equalsForTest(that)) {
2227e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            return false;
2237e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
2247e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        ImapList thatList = (ImapList) that;
2257e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        if (size() != thatList.size()) {
2267e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            return false;
2277e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
2287e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        for (int i = 0; i < size(); i++) {
2297e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            if (!mList.get(i).equalsForTest(thatList.getElementOrNone(i))) {
2307e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki                return false;
2317e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki            }
2327e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        }
2337e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki        return true;
2347e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki    }
2357e5ba0e1eaee76ab6e6c7ea9362348f660796596Makoto Onuki}
236