/*
 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.util.calendar;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.ref.SoftReference;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

/**
 * <code>ZoneInfo</code> is an implementation subclass of {@link
 * java.util.TimeZone TimeZone} that represents GMT offsets and
 * daylight saving time transitions of a time zone.
 * <p>
 * The daylight saving time transitions are described in the {@link
 * #transitions transitions} table consisting of a chronological
 * sequence of transitions of GMT offset and/or daylight saving time
 * changes. Since all transitions are represented in UTC, in theory,
 * <code>ZoneInfo</code> can be used with any calendar systems except
 * for the {@link #getOffset(int,int,int,int,int,int) getOffset}
 * method that takes Gregorian calendar date fields.
 * <p>
 * This table covers transitions from 1900 until 2037 (as of version
 * 1.4), Before 1900, it assumes that there was no daylight saving
 * time and the <code>getOffset</code> methods always return the
 * {@link #getRawOffset} value. No Local Mean Time is supported. If a
 * specified date is beyond the transition table and this time zone is
 * supposed to observe daylight saving time in 2037, it delegates
 * operations to a {@link java.util.SimpleTimeZone SimpleTimeZone}
 * object created using the daylight saving time schedule as of 2037.
 * <p>
 * The date items, transitions, GMT offset(s), etc. are read from a database
 * file. See {@link ZoneInfoFile} for details.
 * @see java.util.SimpleTimeZone
 * @since 1.4
 */

public class ZoneInfo extends TimeZone {

    private static final int UTC_TIME = 0;
    private static final int STANDARD_TIME = 1;
    private static final int WALL_TIME = 2;

    private static final long OFFSET_MASK = 0x0fL;
    private static final long DST_MASK = 0xf0L;
    private static final int DST_NSHIFT = 4;
    // this bit field is reserved for abbreviation support
    private static final long ABBR_MASK = 0xf00L;
    private static final int TRANSITION_NSHIFT = 12;

    // Flag for supporting JDK backward compatible IDs, such as "EST".
    private static final boolean USE_OLDMAPPING;
    static {
      String oldmapping = AccessController.doPrivileged(
          new sun.security.action.GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
      USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
    }

    private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();

    /**
     * The raw GMT offset in milliseconds between this zone and GMT.
     * Negative offsets are to the west of Greenwich.  To obtain local
     * <em>standard</em> time, add the offset to GMT time.
     * @serial
     */
    private int rawOffset;

    /**
     * Difference in milliseconds from the original GMT offset in case
     * the raw offset value has been modified by calling {@link
     * #setRawOffset}. The initial value is 0.
     * @serial
     */
    private int rawOffsetDiff = 0;

    /**
     * A CRC32 value of all pairs of transition time (in milliseconds
     * in <code>long</code>) in local time and its GMT offset (in
     * seconds in <code>int</code>) in the chronological order. Byte
     * values of each <code>long</code> and <code>int</code> are taken
     * in the big endian order (i.e., MSB to LSB).
     * @serial
     */
    private int checksum;

    /**
     * The amount of time in milliseconds saved during daylight saving
     * time. If <code>useDaylight</code> is false, this value is 0.
     * @serial
     */
    private int dstSavings;

    /**
     * This array describes transitions of GMT offsets of this time
     * zone, including both raw offset changes and daylight saving
     * time changes.
     * A long integer consists of four bit fields.
     * <ul>
     * <li>The most significant 52-bit field represents transition
     * time in milliseconds from Gregorian January 1 1970, 00:00:00
     * GMT.</li>
     * <li>The next 4-bit field is reserved and must be 0.</li>
     * <li>The next 4-bit field is an index value to {@link #offsets
     * offsets[]} for the amount of daylight saving at the
     * transition. If this value is zero, it means that no daylight
     * saving, not the index value zero.</li>
     * <li>The least significant 4-bit field is an index value to
     * {@link #offsets offsets[]} for <em>total</em> GMT offset at the
     * transition.</li>
     * </ul>
     * If this time zone doesn't observe daylight saving time and has
     * never changed any GMT offsets in the past, this value is null.
     * @serial
     */
    private long[] transitions;

    /**
     * This array holds all unique offset values in
     * milliseconds. Index values to this array are stored in the
     * transitions array elements.
     * @serial
     */
    private int[] offsets;

    /**
     * SimpleTimeZone parameter values. It has to have either 8 for
     * {@link java.util.SimpleTimeZone#SimpleTimeZone(int, String,
     * int, int , int , int , int , int , int , int , int) the
     * 11-argument SimpleTimeZone constructor} or 10 for {@link
     * java.util.SimpleTimeZone#SimpleTimeZone(int, String, int, int,
     * int , int , int , int , int , int , int, int, int) the
     * 13-argument SimpleTimeZone constructor} parameters.
     * @serial
     */
    private int[] simpleTimeZoneParams;

    /**
     * True if the raw GMT offset value would change after the time
     * zone data has been generated; false, otherwise. The default
     * value is false.
     * @serial
     */
    private boolean willGMTOffsetChange = false;

    /**
     * True if the object has been modified after its instantiation.
     */
    transient private boolean dirty = false;

    private static final long serialVersionUID = 2653134537216586139L;

    /**
     * A constructor.
     */
    public ZoneInfo() {
    }

    /**
     * A Constructor for CustomID.
     */
    public ZoneInfo(String ID, int rawOffset) {
        this(ID, rawOffset, 0, 0, null, null, null, false);
    }

    /**
     * Constructs a ZoneInfo instance.
     *
     * @param ID time zone name
     * @param rawOffset GMT offset in milliseconds
     * @param dstSavings daylight saving value in milliseconds or 0
     * (zero) if this time zone doesn't observe Daylight Saving Time.
     * @param checksum CRC32 value with all transitions table entry
     * values
     * @param transitions transition table
     * @param offsets offset value table
     * @param simpleTimeZoneParams parameter values for constructing
     * SimpleTimeZone
     * @param willGMTOffsetChange the value of willGMTOffsetChange
     */
    ZoneInfo(String ID,
             int rawOffset,
             int dstSavings,
             int checksum,
             long[] transitions,
             int[] offsets,
             int[] simpleTimeZoneParams,
             boolean willGMTOffsetChange) {
        setID(ID);
        this.rawOffset = rawOffset;
        this.dstSavings = dstSavings;
        this.checksum = checksum;
        this.transitions = transitions;
        this.offsets = offsets;
        this.simpleTimeZoneParams = simpleTimeZoneParams;
        this.willGMTOffsetChange = willGMTOffsetChange;
    }

    /**
     * Returns the difference in milliseconds between local time and UTC
     * of given time, taking into account both the raw offset and the
     * effect of daylight savings.
     *
     * @param date the milliseconds in UTC
     * @return the milliseconds to add to UTC to get local wall time
     */
    public int getOffset(long date) {
        return getOffsets(date, null, UTC_TIME);
    }

    public int getOffsets(long utc, int[] offsets) {
        return getOffsets(utc, offsets, UTC_TIME);
    }

    public int getOffsetsByStandard(long standard, int[] offsets) {
        return getOffsets(standard, offsets, STANDARD_TIME);
    }

    public int getOffsetsByWall(long wall, int[] offsets) {
        return getOffsets(wall, offsets, WALL_TIME);
    }

    private int getOffsets(long date, int[] offsets, int type) {
        // if dst is never observed, there is no transition.
        if (transitions == null) {
            int offset = getLastRawOffset();
            if (offsets != null) {
                offsets[0] = offset;
                offsets[1] = 0;
            }
            return offset;
        }

        date -= rawOffsetDiff;
        int index = getTransitionIndex(date, type);

        // prior to the transition table, returns the raw offset.
        // should support LMT.
        if (index < 0) {
            int offset = getLastRawOffset();
            if (offsets != null) {
                offsets[0] = offset;
                offsets[1] = 0;
            }
            return offset;
        }

        if (index < transitions.length) {
            long val = transitions[index];
            int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff;
            if (offsets != null) {
                int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
                int save = (dst == 0) ? 0 : this.offsets[dst];
                offsets[0] = offset - save;
                offsets[1] = save;
            }
            return offset;
        }

        // beyond the transitions, delegate to SimpleTimeZone if there
        // is a rule; otherwise, return rawOffset.
        SimpleTimeZone tz = getLastRule();
        if (tz != null) {
            int rawoffset = tz.getRawOffset();
            long msec = date;
            if (type != UTC_TIME) {
                msec -= rawOffset;
            }
            int dstoffset = tz.inDaylightTime(new Date(msec)) ? tz.getDSTSavings() : 0;
            if (offsets != null) {
                offsets[0] = rawoffset;
                offsets[1] = dstoffset;
            }
            return rawoffset + dstoffset;
        }
        int offset = getLastRawOffset();
        if (offsets != null) {
            offsets[0] = offset;
            offsets[1] = 0;
        }
        return offset;
    }

    private final int getTransitionIndex(long date, int type) {
        int low = 0;
        int high = transitions.length - 1;

        while (low <= high) {
            int mid = (low + high) / 2;
            long val = transitions[mid];
            long midVal = val >> TRANSITION_NSHIFT; // sign extended
            if (type != UTC_TIME) {
                midVal += offsets[(int)(val & OFFSET_MASK)]; // wall time
            }
            if (type == STANDARD_TIME) {
                int dstIndex = (int)((val >>> DST_NSHIFT) & 0xfL);
                if (dstIndex != 0) {
                    midVal -= offsets[dstIndex]; // make it standard time
                }
            }

            if (midVal < date) {
                low = mid + 1;
            } else if (midVal > date) {
                high = mid - 1;
            } else {
                return mid;
            }
        }

        // if beyond the transitions, returns that index.
        if (low >= transitions.length) {
            return low;
        }
        return low - 1;
    }

   /**
     * Returns the difference in milliseconds between local time and
     * UTC, taking into account both the raw offset and the effect of
     * daylight savings, for the specified date and time.  This method
     * assumes that the start and end month are distinct.  This method
     * assumes a Gregorian calendar for calculations.
     * <p>
     * <em>Note: In general, clients should use
     * {@link Calendar#ZONE_OFFSET Calendar.get(ZONE_OFFSET)} +
     * {@link Calendar#DST_OFFSET Calendar.get(DST_OFFSET)}
     * instead of calling this method.</em>
     *
     * @param era       The era of the given date. The value must be either
     *                  GregorianCalendar.AD or GregorianCalendar.BC.
     * @param year      The year in the given date.
     * @param month     The month in the given date. Month is 0-based. e.g.,
     *                  0 for January.
     * @param day       The day-in-month of the given date.
     * @param dayOfWeek The day-of-week of the given date.
     * @param millis    The milliseconds in day in <em>standard</em> local time.
     * @return The milliseconds to add to UTC to get local time.
     */
    public int getOffset(int era, int year, int month, int day,
                         int dayOfWeek, int milliseconds) {
        if (milliseconds < 0 || milliseconds >= AbstractCalendar.DAY_IN_MILLIS) {
            throw new IllegalArgumentException();
        }

        if (era == java.util.GregorianCalendar.BC) { // BC
            year = 1 - year;
        } else if (era != java.util.GregorianCalendar.AD) {
            throw new IllegalArgumentException();
        }

        CalendarDate date = gcal.newCalendarDate(null);
        date.setDate(year, month + 1, day);
        if (gcal.validate(date) == false) {
            throw new IllegalArgumentException();
        }

        // bug-for-bug compatible argument checking
        if (dayOfWeek < java.util.GregorianCalendar.SUNDAY
            || dayOfWeek > java.util.GregorianCalendar.SATURDAY) {
            throw new IllegalArgumentException();
        }

        if (transitions == null) {
            return getLastRawOffset();
        }

        long dateInMillis = gcal.getTime(date) + milliseconds;
        dateInMillis -= (long) rawOffset; // make it UTC
        return getOffsets(dateInMillis, null, UTC_TIME);
    }

    /**
     * Sets the base time zone offset from GMT. This operation
     * modifies all the transitions of this ZoneInfo object, including
     * historical ones, if applicable.
     *
     * @param offsetMillis the base time zone offset to GMT.
     * @see getRawOffset
     */
    public synchronized void setRawOffset(int offsetMillis) {
        if (offsetMillis == rawOffset + rawOffsetDiff) {
            return;
        }
        rawOffsetDiff = offsetMillis - rawOffset;
        if (lastRule != null) {
            lastRule.setRawOffset(offsetMillis);
        }
        dirty = true;
    }

    /**
     * Returns the GMT offset of the current date. This GMT offset
     * value is not modified during Daylight Saving Time.
     *
     * @return the GMT offset value in milliseconds to add to UTC time
     * to get local standard time
     */
    public int getRawOffset() {
        if (!willGMTOffsetChange) {
            return rawOffset + rawOffsetDiff;
        }

        int[] offsets = new int[2];
        getOffsets(System.currentTimeMillis(), offsets, UTC_TIME);
        return offsets[0];
    }

    public boolean isDirty() {
        return dirty;
    }

    private int getLastRawOffset() {
        return rawOffset + rawOffsetDiff;
    }

    /**
     * Queries if this time zone uses Daylight Saving Time in the last known rule.
     */
    public boolean useDaylightTime() {
        return (simpleTimeZoneParams != null);
    }

    /**
     * Queries if the specified date is in Daylight Saving Time.
     */
    public boolean inDaylightTime(Date date) {
        if (date == null) {
            throw new NullPointerException();
        }

        if (transitions == null) {
            return false;
        }

        long utc = date.getTime() - rawOffsetDiff;
        int index = getTransitionIndex(utc, UTC_TIME);

        // before transitions in the transition table
        if (index < 0) {
            return false;
        }

        // the time is in the table range.
        if (index < transitions.length) {
            return (transitions[index] & DST_MASK) != 0;
        }

        // beyond the transition table
        SimpleTimeZone tz = getLastRule();
        if (tz != null) {
            return tz.inDaylightTime(date);
        }
        return false;
    }

    /**
     * Returns the amount of time in milliseconds that the clock is advanced
     * during daylight saving time is in effect in its last daylight saving time rule.
     *
     * @return the number of milliseconds the time is advanced with respect to
     * standard time when daylight saving time is in effect.
     */
    public int getDSTSavings() {
        return dstSavings;
    }

//    /**
//     * @return the last year in the transition table or -1 if this
//     * time zone doesn't observe any daylight saving time.
//     */
//    public int getMaxTransitionYear() {
//      if (transitions == null) {
//          return -1;
//      }
//      long val = transitions[transitions.length - 1];
//      int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff;
//      val = (val >> TRANSITION_NSHIFT) + offset;
//      CalendarDate lastDate = Gregorian.getCalendarDate(val);
//      return lastDate.getYear();
//    }

    /**
     * Returns a string representation of this time zone.
     * @return the string
     */
    public String toString() {
        return getClass().getName() +
            "[id=\"" + getID() + "\"" +
            ",offset=" + getLastRawOffset() +
            ",dstSavings=" + dstSavings +
            ",useDaylight=" + useDaylightTime() +
            ",transitions=" + ((transitions != null) ? transitions.length : 0) +
            ",lastRule=" + (lastRule == null ? getLastRuleInstance() : lastRule) +
            "]";
    }

    /**
     * Gets all available IDs supported in the Java run-time.
     *
     * @return an array of time zone IDs.
     */
    public static String[] getAvailableIDs() {
        List<String> idList = ZoneInfoFile.getZoneIDs();
        List<String> excluded = ZoneInfoFile.getExcludedZones();
        if (excluded != null) {
            // List all zones from the idList and excluded lists
            List<String> list = new ArrayList<String>(idList.size() + excluded.size());
            list.addAll(idList);
            list.addAll(excluded);
            idList = list;
        }
        String[] ids = new String[idList.size()];
        return idList.toArray(ids);
    }

    /**
     * Gets all available IDs that have the same value as the
     * specified raw GMT offset.
     *
     * @param rawOffset the GMT offset in milliseconds. This
     * value should not include any daylight saving time.
     *
     * @return an array of time zone IDs.
     */
    public static String[] getAvailableIDs(int rawOffset) {
        String[] result;
        List<String> matched = new ArrayList<String>();
        List<String> IDs = ZoneInfoFile.getZoneIDs();
        int[] rawOffsets = ZoneInfoFile.getRawOffsets();

    loop:
        for (int index = 0; index < rawOffsets.length; index++) {
            if (rawOffsets[index] == rawOffset) {
                byte[] indices = ZoneInfoFile.getRawOffsetIndices();
                for (int i = 0; i < indices.length; i++) {
                    if (indices[i] == index) {
                        matched.add(IDs.get(i++));
                        while (i < indices.length && indices[i] == index) {
                            matched.add(IDs.get(i++));
                        }
                        break loop;
                    }
                }
            }
        }

        // We need to add any zones from the excluded zone list that
        // currently have the same GMT offset as the specified
        // rawOffset. The zones returned by this method may not be
        // correct as of return to the caller if any GMT offset
        // transition is happening during this GMT offset checking...
        List<String> excluded = ZoneInfoFile.getExcludedZones();
        if (excluded != null) {
            for (String id : excluded) {
                TimeZone zi = getTimeZone(id);
                if (zi != null && zi.getRawOffset() == rawOffset) {
                    matched.add(id);
                }
            }
        }

        result = new String[matched.size()];
        matched.toArray(result);
        return result;
    }

    /**
     * Gets the ZoneInfo for the given ID.
     *
     * @param ID the ID for a ZoneInfo. See TimeZone for detail.
     *
     * @return the specified ZoneInfo object, or null if there is no
     * time zone of the ID.
     */
    public static TimeZone getTimeZone(String ID) {
        String givenID = null;

        /*
         * If old JDK compatibility is specified, get the old alias
         * name.
         */
        if (USE_OLDMAPPING) {
            String compatibleID = TzIDOldMapping.MAP.get(ID);
            if (compatibleID != null) {
                givenID = ID;
                ID = compatibleID;
            }
        }

        ZoneInfo zi = ZoneInfoFile.getZoneInfo(ID);
        if (zi == null) {
            // if we can't create an object for the ID, try aliases.
            try {
                Map<String, String> map = getAliasTable();
                String alias = ID;
                while ((alias = map.get(alias)) != null) {
                    zi = ZoneInfoFile.getZoneInfo(alias);
                    if (zi != null) {
                        zi.setID(ID);
                        zi = ZoneInfoFile.addToCache(ID, zi);
                        zi = (ZoneInfo) zi.clone();
                        break;
                    }
                }
            } catch (Exception e) {
                // ignore exceptions
            }
        }

        if (givenID != null && zi != null) {
            zi.setID(givenID);
        }
        return zi;
    }

    private transient SimpleTimeZone lastRule;

    /**
     * Returns a SimpleTimeZone object representing the last GMT
     * offset and DST schedule or null if this time zone doesn't
     * observe DST.
     */
    private synchronized SimpleTimeZone getLastRule() {
        if (lastRule == null) {
            lastRule = getLastRuleInstance();
        }
        return lastRule;
    }

    /**
     * Returns a SimpleTimeZone object that represents the last
     * known daylight saving time rules.
     *
     * @return a SimpleTimeZone object or null if this time zone
     * doesn't observe DST.
     */
    public SimpleTimeZone getLastRuleInstance() {
        if (simpleTimeZoneParams == null) {
            return null;
        }
        if (simpleTimeZoneParams.length == 10) {
            return new SimpleTimeZone(getLastRawOffset(), getID(),
                                      simpleTimeZoneParams[0],
                                      simpleTimeZoneParams[1],
                                      simpleTimeZoneParams[2],
                                      simpleTimeZoneParams[3],
                                      simpleTimeZoneParams[4],
                                      simpleTimeZoneParams[5],
                                      simpleTimeZoneParams[6],
                                      simpleTimeZoneParams[7],
                                      simpleTimeZoneParams[8],
                                      simpleTimeZoneParams[9],
                                      dstSavings);
        }
        return new SimpleTimeZone(getLastRawOffset(), getID(),
                                  simpleTimeZoneParams[0],
                                  simpleTimeZoneParams[1],
                                  simpleTimeZoneParams[2],
                                  simpleTimeZoneParams[3],
                                  simpleTimeZoneParams[4],
                                  simpleTimeZoneParams[5],
                                  simpleTimeZoneParams[6],
                                  simpleTimeZoneParams[7],
                                  dstSavings);
    }

    /**
     * Returns a copy of this <code>ZoneInfo</code>.
     */
    public Object clone() {
        ZoneInfo zi = (ZoneInfo) super.clone();
        zi.lastRule = null;
        return zi;
    }

    /**
     * Returns a hash code value calculated from the GMT offset and
     * transitions.
     * @return a hash code of this time zone
     */
    public int hashCode() {
        return getLastRawOffset() ^ checksum;
    }

    /**
     * Compares the equity of two ZoneInfo objects.
     *
     * @param obj the object to be compared with
     * @return true if given object is same as this ZoneInfo object,
     * false otherwise.
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof ZoneInfo)) {
            return false;
        }
        ZoneInfo that = (ZoneInfo) obj;
        return (getID().equals(that.getID())
                && (getLastRawOffset() == that.getLastRawOffset())
                && (checksum == that.checksum));
    }

    /**
     * Returns true if this zone has the same raw GMT offset value and
     * transition table as another zone info. If the specified
     * TimeZone object is not a ZoneInfo instance, this method returns
     * true if the specified TimeZone object has the same raw GMT
     * offset value with no daylight saving time.
     *
     * @param other the ZoneInfo object to be compared with
     * @return true if the given <code>TimeZone</code> has the same
     * GMT offset and transition information; false, otherwise.
     */
    public boolean hasSameRules(TimeZone other) {
        if (this == other) {
            return true;
        }
        if (other == null) {
            return false;
        }
        if (!(other instanceof ZoneInfo)) {
            if (getRawOffset() != other.getRawOffset()) {
                return false;
            }
            // if both have the same raw offset and neither observes
            // DST, they have the same rule.
            if ((transitions == null)
                && (useDaylightTime() == false)
                && (other.useDaylightTime() == false)) {
                return true;
            }
            return false;
        }
        if (getLastRawOffset() != ((ZoneInfo)other).getLastRawOffset()) {
            return false;
        }
        return (checksum == ((ZoneInfo)other).checksum);
    }

    private static SoftReference<Map> aliasTable;

    /**
     * Returns a Map from alias time zone IDs to their standard
     * time zone IDs.
     *
     * @return the Map that holds the mappings from alias time zone IDs
     *    to their standard time zone IDs, or null if
     *    <code>ZoneInfoMappings</code> file is not available.
     */
    public synchronized static Map<String, String> getAliasTable() {
        Map<String, String> aliases = null;

        SoftReference<Map> cache = aliasTable;
        if (cache != null) {
            aliases = cache.get();
            if (aliases != null) {
                return aliases;
            }
        }

        aliases = ZoneInfoFile.getZoneAliases();
        if (aliases != null) {
            aliasTable = new SoftReference<Map>(aliases);
        }
        return aliases;
    }

    private void readObject(ObjectInputStream stream)
            throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        // We don't know how this object from 1.4.x or earlier has
        // been mutated. So it should always be marked as `dirty'.
        dirty = true;
    }
}
