//##header
//#ifndef FOUNDATION
/*
 *******************************************************************************
 * Copyright (C) 2006, Google, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/DateTimePatternGenerator.java,v $
 * $Date: 2006/09/24 23:23:00 $
 * $Revision: 1.10 $
 *
 *******************************************************************************
 */
package com.ibm.icu.text;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import org.unicode.cldr.util.Utility;

import com.ibm.icu.impl.CalendarData;
import com.ibm.icu.impl.PatternTokenizer;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.Freezable;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;

/**
 * This class provides flexible generation of date format patterns, like
 * "yy-MM-dd". The user can build up the generator by adding successive
 * patterns. Once that is done, a query can be made using a "skeleton", which is
 * a pattern which just includes the desired fields and lengths. The generator
 * will return the "best fit" pattern corresponding to that skeleton.
 * <p>
 * The main method people will use is getBestPattern(String skeleton), since
 * normally this class is pre-built with data from a particular locale. However,
 * generators can be built directly from other data as well.
 * <pre>
 * // some simple use cases
 * Date sampleDate = new Date(99, 9, 13, 23, 58, 59);
 * ULocale locale = ULocale.GERMANY;
 * TimeZone zone = TimeZone.getTimeZone(&quot;Europe/Paris&quot;);
 * 
 * // make from locale
 * 
 * DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(locale);
 * SimpleDateFormat format = new SimpleDateFormat(gen.getBestPattern(&quot;MMMddHmm&quot;),
 *     locale);
 * format.setTimeZone(zone);
 * assertEquals(&quot;simple format: MMMddHmm&quot;, 
 *     &quot;8:58 14. Okt&quot;,
 *     format.format(sampleDate));
 * // (a generator can be built from scratch, but that is not a typical use case)
 * 
 * // modify the generator by adding patterns
 * DateTimePatternGenerator.PatternInfo returnInfo = new DateTimePatternGenerator.PatternInfo();
 * gen.add(&quot;d'. von' MMMM&quot;, true, returnInfo);
 * // the returnInfo is mostly useful for debugging problem cases
 * format.applyPattern(gen.getBestPattern(&quot;MMMMddHmm&quot;));
 * assertEquals(&quot;modified format: MMMddHmm&quot;,
 *     &quot;8:58 14. von Oktober&quot;,
 *     format.format(sampleDate));
 * 
 * // get a pattern and modify it
 * format = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.FULL,
 *     DateFormat.FULL, locale);
 * format.setTimeZone(zone);
 * String pattern = format.toPattern();
 * assertEquals(&quot;full-date&quot;,
 *     &quot;Donnerstag, 14. Oktober 1999 8:58 Uhr GMT+02:00&quot;,
 *     format.format(sampleDate));
 * 
 * // modify it to change the zone.
 * String newPattern = gen.replaceFieldTypes(pattern, &quot;vvvv&quot;);
 * format.applyPattern(newPattern);
 * assertEquals(&quot;full-date, modified zone&quot;,
 *     &quot;Donnerstag, 14. Oktober 1999 8:58 Uhr Frankreich&quot;,
 *     format.format(sampleDate));
 * </pre>
 * @draft ICU 3.6
 * @provisional This API might change or be removed in a future release.
 */
public class DateTimePatternGenerator implements Freezable, Cloneable {
    // debugging flags
    //static boolean SHOW_DISTANCE = false;
    // TODO add hack to fix months for CJK, as per bug 1099
    // http://dev.icu-project.org/cgi-bin/locale-bugs/incoming?findid=1099
    
    /**
     * Create empty generator, to be constructed with add(...) etc.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public static DateTimePatternGenerator newInstance() {
        return new DateTimePatternGenerator();
    }
    
    /**
     * Only for use by subclasses
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    protected DateTimePatternGenerator() {         
    }
    
    /**
     * Construct a flexible generator according to data for a given locale.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public static DateTimePatternGenerator getInstance() {
        return getInstance(ULocale.getDefault());
    }
    
    /**
     * Construct a flexible generator according to data for a given locale.
     * @param uLocale
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public static DateTimePatternGenerator getInstance(ULocale uLocale) {
        DateTimePatternGenerator result = new DateTimePatternGenerator();
        String lang = uLocale.getLanguage();
        if (lang.equals("zh") || lang.equals("ko") || lang.equals("ja")) {
          result.chineseMonthHack = true;
        }
        PatternInfo returnInfo = new PatternInfo();
        String hackPattern = null;
        // first load with the ICU patterns
        for (int i = DateFormat.FULL; i <= DateFormat.SHORT; ++i) {
            SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(i, uLocale);
            result.add(df.toPattern(), false, returnInfo);
            df = (SimpleDateFormat) DateFormat.getTimeInstance(i, uLocale);
            result.add(df.toPattern(), false, returnInfo);
            // HACK for hh:ss
            if (i == DateFormat.MEDIUM) {
                hackPattern = df.toPattern();
            }
        }
        UResourceBundle rb = UResourceBundle.getBundleInstance("com.ibm.icu.impl.data.DateData$MyDateResources", uLocale);
        //ResourceBundle rb = ResourceBundle.getBundle("com.ibm.icu.impl.data.DateData$MyDateResources", ULocale.FRENCH.toLocale());
        for (Enumeration en = rb.getKeys(); en.hasMoreElements();) {
            String key = (String) en.nextElement();
            String value = rb.getString(key);
            String [] keyParts = key.split("/");
            if (keyParts[0].equals("pattern")) {
                result.add(value, false, returnInfo);
            } else if  (keyParts[0].equals("append")) {
                result.setAppendItemFormats(getAppendFormatNumber(keyParts[1]), value);
            } else if  (keyParts[0].equals("field")) {
                result.setAppendItemNames(getAppendNameNumber(keyParts[1]), value);
            }
        }
        
        // assume it is always big endian (ok for CLDR right now)
        // some languages didn't add mm:ss or HH:mm, so put in a hack to compute that from the short time.
        if (hackPattern != null) {
            hackTimes(result, returnInfo, hackPattern);
        }
        
        // set the datetime pattern. This is ugly code -- there should be a public interface for this
        Calendar cal = Calendar.getInstance(uLocale);
        CalendarData calData = new CalendarData(uLocale, cal.getType());
        String[] patterns = calData.get("DateTimePatterns").getStringArray();
        result.setDateTimeFormat(patterns[8]);
        
        // decimal point for seconds
        DecimalFormatSymbols dfs = new DecimalFormatSymbols(uLocale);
        result.setDecimal(String.valueOf(dfs.getDecimalSeparator()));
        return result;
    }
    
    private static void hackTimes(DateTimePatternGenerator result, PatternInfo returnInfo, String hackPattern) {
        result.fp.set(hackPattern);
        String mmss = new String();
        // to get mm:ss, we strip all but mm literal ss
        boolean gotMm = false;
        for (int i = 0; i < result.fp.items.size(); ++i) {
            Object item = result.fp.items.get(i);
            if (item instanceof String) {
                if (gotMm) {
                    mmss += result.fp.quoteLiteral(item.toString());
                }
            } else {
                char ch = item.toString().charAt(0);
                if (ch == 'm') {
                    gotMm = true;
                    mmss += item;
                } else if (ch == 's') {
                    if (!gotMm) {
                        break; // failed
                    }
                    mmss += item;
                    result.add(mmss, false, returnInfo);
                    break;
                } else if (gotMm || ch == 'z' || ch == 'Z' || ch == 'v' || ch == 'V') {
                    break; // failed
                }
            }
        }
        // to get hh:mm, we strip (literal ss) and (literal S)
        // the easiest way to do this is to mark the stuff we want to nuke, then remove it in a second pass.
        BitSet variables = new BitSet();
        BitSet nuke = new BitSet();
        for (int i = 0; i < result.fp.items.size(); ++i) {
            Object item = result.fp.items.get(i);
            if (item instanceof VariableField) {
                variables.set(i);
                char ch = item.toString().charAt(0);
                if (ch == 's' || ch == 'S') {
                    nuke.set(i);
                    for (int j = i-1; j >= 0; ++j) {
                        if (variables.get(j)) break;
                        nuke.set(i);
                    }
                }
            }
        }
        String hhmm = getFilteredPattern(result.fp, nuke);
        result.add(hhmm, false, returnInfo);
    }
    
    private static String getFilteredPattern(FormatParser fp, BitSet nuke) {
        String result = new String();
        for (int i = 0; i < fp.items.size(); ++i) {
            if (nuke.get(i)) continue;
            Object item = fp.items.get(i);
            if (item instanceof String) {
                result += fp.quoteLiteral(item.toString());
            } else {
                result += item.toString();
            }
        }
        return result;
    }
    
    private static int getAppendNameNumber(String string) {
        for (int i = 0; i < CLDR_FIELD_NAME.length; ++i) {
            if (CLDR_FIELD_NAME[i].equals(string)) return i;
        }
        return -1;
    }
    
    private static int getAppendFormatNumber(String string) {
        for (int i = 0; i < CLDR_FIELD_APPEND.length; ++i) {
            if (CLDR_FIELD_APPEND[i].equals(string)) return i;
        }
        return -1;
        
    }
    
    /**
     * Return the best pattern matching the input skeleton. It is guaranteed to
     * have all of the fields in the skeleton.
     * 
     * @param skeleton
     *            The skeleton is a pattern containing only the variable fields.
     *            For example, "MMMdd" and "mmhh" are skeletons.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getBestPattern(String skeleton) {
      if (chineseMonthHack) {
        skeleton = skeleton.replaceAll("MMM+", "MM");
      }
        //if (!isComplete) complete();
        current.set(skeleton, fp);
        String best = getBestRaw(current, -1, _distanceInfo);
        if (_distanceInfo.missingFieldMask == 0 && _distanceInfo.extraFieldMask == 0) {
            // we have a good item. Adjust the field types
            return adjustFieldTypes(best, current, false);
        }
        int neededFields = current.getFieldMask();
        // otherwise break up by date and time.
        String datePattern = getBestAppending(neededFields & DATE_MASK);
        String timePattern = getBestAppending(neededFields & TIME_MASK);
        
        if (datePattern == null) return timePattern == null ? "" : timePattern;
        if (timePattern == null) return datePattern;
        return MessageFormat.format(getDateTimeFormat(), new Object[]{datePattern, timePattern});
    }
    
    /**
     * PatternInfo supplies output parameters for add(...). It is used because
     * Java doesn't have real output parameters. It is treated like a struct (eg
     * Point), so all fields are public.
     * 
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public static final class PatternInfo { // struct for return information
        /**
         * @draft ICU 3.6
         * @provisional This API might change or be removed in a future release.
         */
        public static final int OK = 0;
        
        /**
         * @draft ICU 3.6
         * @provisional This API might change or be removed in a future release.
         */
        public static final int BASE_CONFLICT = 1;
        
        /**
         * @draft ICU 3.6
         * @provisional This API might change or be removed in a future release.
         */
        public static final int CONFLICT = 2;
        
        /**
         * @draft ICU 3.6
         * @provisional This API might change or be removed in a future release.
         */
        public int status;
        
        /**
         * @draft ICU 3.6
         * @provisional This API might change or be removed in a future release.
         */
        public String conflictingPattern;
        
        /**
         * Simple constructor, since this is treated like a struct.
         * @draft ICU 3.6
         * @provisional This API might change or be removed in a future release.
         */
        public PatternInfo() {
        }
    }
    
    static Transliterator fromHex = Transliterator.getInstance("hex-any");
    
    /**
     * Adds a pattern to the generator. If the pattern has the same skeleton as
     * an existing pattern, and the override parameter is set, then the previous
     * value is overriden. Otherwise, the previous value is retained. In either
     * case, the conflicting information is returned in PatternInfo.
     * <p>
     * Note that single-field patterns (like "MMM") are automatically added, and
     * don't need to be added explicitly!
     * 
     * @param override
     *            when existing values are to be overridden use true, otherwise
     *            use false.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public DateTimePatternGenerator add(String pattern, boolean override, PatternInfo returnInfo) {
        checkFrozen();
        if (pattern.indexOf("\\u") >= 0) {
            String oldPattern = pattern;
            pattern = fromHex.transliterate(pattern);
        }
        DateTimeMatcher matcher = new DateTimeMatcher().set(pattern, fp);
        String basePattern = matcher.getBasePattern();
        String previousPatternWithSameBase = (String)basePattern_pattern.get(basePattern);
        if (previousPatternWithSameBase != null) {
            returnInfo.status = PatternInfo.BASE_CONFLICT;
            returnInfo.conflictingPattern = previousPatternWithSameBase;
            if (!override) return this;
        }
        String previousValue = (String)skeleton2pattern.get(matcher);
        if (previousValue != null) {
            returnInfo.status = PatternInfo.CONFLICT;
            returnInfo.conflictingPattern = previousValue;
            if (!override) return this;
        }
        returnInfo.status = PatternInfo.OK;
        returnInfo.conflictingPattern = "";
        skeleton2pattern.put(matcher, pattern);
        basePattern_pattern.put(basePattern, pattern);
        return this;
    }
    
    /**
     * Utility to return a unique skeleton from a given pattern. For example,
     * both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd".
     * 
     * @param pattern
     *            Input pattern, such as "dd/MMM"
     * @return skeleton, such as "MMMdd"
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getSkeleton(String pattern) {
        synchronized (this) { // synchronized since a getter must be thread-safe
            current.set(pattern, fp);
            return current.toString();
        }
    }
    
    /**
     * Utility to return a unique base skeleton from a given pattern. This is
     * the same as the skeleton, except that differences in length are minimized
     * so as to only preserve the difference between string and numeric form. So
     * for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd"
     * (notice the single d).
     * 
     * @param pattern
     *            Input pattern, such as "dd/MMM"
     * @return skeleton, such as "MMMdd"
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getBaseSkeleton(String pattern) {
        synchronized (this) { // synchronized since a getter must be thread-safe
            current.set(pattern, fp);
            return current.getBasePattern();
        }
    }
    
    /**
     * Return a list of all the skeletons (in canonical form) from this class,
     * and the patterns that they map to.
     * 
     * @param result
     *            an output Map in which to place the mapping from skeleton to
     *            pattern. If you want to see the internal order being used,
     *            supply a LinkedHashMap. If the input value is null, then a
     *            LinkedHashMap is allocated.
     *            <p>
     *            <i>Issue: an alternate API would be to just return a list of
     *            the skeletons, and then have a separate routine to get from
     *            skeleton to pattern.</i>
     * @return the input Map containing the values.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public Map getSkeletons(Map result) {
        if (result == null) result = new LinkedHashMap();
        for (Iterator it = skeleton2pattern.keySet().iterator(); it.hasNext();) {
            DateTimeMatcher item = (DateTimeMatcher) it.next();
            String pattern = (String) skeleton2pattern.get(item);
            if (CANONICAL_SET.contains(pattern)) continue;
            result.put(item.toString(), pattern);
        }
        return result;
    }
    
    /**
     * Return a list of all the base skeletons (in canonical form) from this class
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public Set getBaseSkeletons(Set result) {
        if (result == null) result = new HashSet();
        result.addAll(basePattern_pattern.keySet());
        return result;
    }
    
    /**
     * Adjusts the field types (width and subtype) of a pattern to match what is
     * in a skeleton. That is, if you supply a pattern like "d-M H:m", and a
     * skeleton of "MMMMddhhmm", then the input pattern is adjusted to be
     * "dd-MMMM hh:mm". This is used internally to get the best match for the
     * input skeleton, but can also be used externally.
     * 
     * @param pattern
     *            input pattern
     * @param skeleton
     * @return pattern adjusted to match the skeleton fields widths and
     *         subtypes.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String replaceFieldTypes(String pattern, String skeleton) {
        synchronized (this) { // synchronized since a getter must be thread-safe
            return adjustFieldTypes(pattern, current.set(skeleton, fp), false);
        }
    }
    
    /**
     * The date time format is a message format pattern used to compose date and
     * time patterns. The default value is "{0} {1}", where {0} will be replaced
     * by the date pattern and {1} will be replaced by the time pattern.
     * <p>
     * This is used when the input skeleton contains both date and time fields,
     * but there is not a close match among the added patterns. For example,
     * suppose that this object was created by adding "dd-MMM" and "hh:mm", and
     * its datetimeFormat is the default "{0} {1}". Then if the input skeleton
     * is "MMMdhmm", there is not an exact match, so the input skeleton is
     * broken up into two components "MMMd" and "hmm". There are close matches
     * for those two skeletons, so the result is put together with this pattern,
     * resulting in "d-MMM h:mm".
     * 
     * @param dateTimeFormat
     *            message format pattern, here {0} will be replaced by the date
     *            pattern and {1} will be replaced by the time pattern.
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public void setDateTimeFormat(String dateTimeFormat) {
        checkFrozen();
        this.dateTimeFormat = dateTimeFormat;
    }
    
    /**
     * Getter corresponding to setDateTimeFormat.
     * 
     * @return pattern
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getDateTimeFormat() {
        return dateTimeFormat;
    }
    
    /**
     * The decimal value is used in formatting fractions of seconds. If the
     * skeleton contains fractional seconds, then this is used with the
     * fractional seconds. For example, suppose that the input pattern is
     * "hhmmssSSSS", and the best matching pattern internally is "H:mm:ss", and
     * the decimal string is ",". Then the resulting pattern is modified to be
     * "H:mm:ss,SSSS"
     * 
     * @param decimal
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public void setDecimal(String decimal) {
        checkFrozen();
        this.decimal = decimal;
    }
    
    /**
     * Getter corresponding to setDecimal.
     * @return string corresponding to the decimal point
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getDecimal() {
        return decimal;
    }
    
    /**
     * Redundant patterns are those which if removed, make no difference in the
     * resulting getBestPattern values. This method returns a list of them, to
     * help check the consistency of the patterns used to build this generator.
     * 
     * @param output
     *            stores the redundant patterns that are removed. To get these
     *            in internal order, supply a LinkedHashSet. If null, a
     *            collection is allocated.
     * @return the collection with added elements.
     * @deprecated
     * @internal
     */
    public Collection getRedundants(Collection output) {
        synchronized (this) { // synchronized since a getter must be thread-safe
            if (output == null) output = new LinkedHashSet();
            for (Iterator it = skeleton2pattern.keySet().iterator(); it.hasNext();) {
                DateTimeMatcher current = (DateTimeMatcher) it.next();
                String pattern = (String) skeleton2pattern.get(current);
                if (CANONICAL_SET.contains(pattern)) continue;
                skipMatcher = current;
                String trial = getBestPattern(current.toString());
                if (trial.equals(pattern)) {
                    output.add(pattern);
                }
            }
            if (false) { // ordered
                DateTimePatternGenerator results = new DateTimePatternGenerator();
                PatternInfo pinfo = new PatternInfo();
                for (Iterator it = skeleton2pattern.keySet().iterator(); it.hasNext();) {
                    DateTimeMatcher current = (DateTimeMatcher) it.next();
                    String pattern = (String) skeleton2pattern.get(current);
                    if (CANONICAL_SET.contains(pattern)) continue;
                    //skipMatcher = current;
                    String trial = results.getBestPattern(current.toString());
                    if (trial.equals(pattern)) {
                        output.add(pattern);
                    } else {
                        results.add(pattern, false, pinfo);
                    }
                }
            }
            return output;
        }
    }
    
    // Field numbers, used for AppendItem functions
    
    /** 
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int ERA = 0;
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int YEAR = 1; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int QUARTER = 2; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int MONTH = 3;
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int WEEK_OF_YEAR = 4; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int WEEK_OF_MONTH = 5; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int WEEKDAY = 6; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int DAY = 7;
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int DAY_OF_YEAR = 8; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int DAY_OF_WEEK_IN_MONTH = 9; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int DAYPERIOD = 10;
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int HOUR = 11; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int MINUTE = 12; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int SECOND = 13; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int FRACTIONAL_SECOND = 14;
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int ZONE = 15; 
    
    /**
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    static final public int TYPE_LIMIT = 16;
    
    /**
     * An AppendItem format is a pattern used to append a field if there is no
     * good match. For example, suppose that the input skeleton is "GyyyyMMMd",
     * and there is no matching pattern internally, but there is a pattern
     * matching "yyyyMMMd", say "d-MM-yyyy". Then that pattern is used, plus the
     * G. The way these two are conjoined is by using the AppendItemFormat for G
     * (era). So if that value is, say "{0}, {1}" then the final resulting
     * pattern is "d-MM-yyyy, G".
     * <p>
     * There are actually three available variables: {0} is the pattern so far,
     * {1} is the element we are adding, and {2} is the name of the element.
     * <p>
     * This reflects the way that the CLDR data is organized.
     * 
     * @param field
     *            such as ERA
     * @param value
     *            pattern, such as "{0}, {1}"
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public void setAppendItemFormats(int field, String value) {
        checkFrozen();
        appendItemFormats[field] = value;
    }
    
    /**
     * Getter corresponding to setAppendItemFormats. Values below 0 or at or
     * above TYPE_LIMIT are illegal arguments.
     * 
     * @param field
     * @return append pattern for field
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getAppendItemFormats(int field) {
        return appendItemFormats[field];
    }
    
    /**
     * Sets the names of fields, eg "era" in English for ERA. These are only
     * used if the corresponding AppendItemFormat is used, and if it contains a
     * {2} variable.
     * <p>
     * This reflects the way that the CLDR data is organized.
     * 
     * @param field
     * @param value
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public void setAppendItemNames(int field, String value) {
        checkFrozen();
        appendItemNames[field] = value;
    }
    
    /**
     * Getter corresponding to setAppendItemNames. Values below 0 or at or above
     * TYPE_LIMIT are illegal arguments.
     * 
     * @param field
     * @return name for field
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public String getAppendItemNames(int field) {
        return appendItemNames[field];
    }
    
    /**
     * Determines whether a skeleton contains a single field
     * 
     * @param skeleton
     * @return true or not
     * @deprecated
     * @internal
     */
    public static boolean isSingleField(String skeleton) {
        char first = skeleton.charAt(0);
        for (int i = 1; i < skeleton.length(); ++i) {
            if (skeleton.charAt(i) != first) return false;
        }
        return true;
    }
    
    /**
     * Boilerplate for Freezable
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public boolean isFrozen() {
        return frozen;
    }
    
    /**
     * Boilerplate for Freezable
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public Object freeze() {
        frozen = true;
        return this;
    }
    
    /**
     * Boilerplate for Freezable
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public Object cloneAsThawed() {
        DateTimePatternGenerator result = (DateTimePatternGenerator) (this.clone());
        frozen = false;
        return result;
    }
    
    /**
     * Boilerplate
     * @draft ICU 3.6
     * @provisional This API might change or be removed in a future release.
     */
    public Object clone() {
        try {
            DateTimePatternGenerator result = (DateTimePatternGenerator) (super.clone());
            result.skeleton2pattern = (TreeMap) skeleton2pattern.clone();
            result.basePattern_pattern = (TreeMap) basePattern_pattern.clone();
            result.appendItemFormats = (String[]) appendItemFormats.clone();
            result.appendItemNames = (String[]) appendItemNames.clone();
            result.current = new DateTimeMatcher();
            result.fp = new FormatParser();
            result._distanceInfo = new DistanceInfo();
            
            result.frozen = false;
            return result;
        } catch (CloneNotSupportedException e) {
            throw new IllegalArgumentException("Internal Error");
        }
    }
    
    /**
     * Utility class for FormatParser. Immutable class.
     * @deprecated
     * @internal
     */
    public static class VariableField {
        private String string;
        /**
         * Create a variable field
         * @param string
         * @deprecated
         * @internal
         */
        public VariableField(String string) {
            this.string = string;
        }
        /**
         * Get the internal results
         * @deprecated
         * @internal
         */
        public String toString() {
            return string;
        }
    }
    
    /**
     * Class providing date formatting
     * @deprecated
     * @internal
     */
    static public class FormatParser {
        private transient PatternTokenizer tokenizer = new PatternTokenizer()
        .setSyntaxCharacters(new UnicodeSet("[a-zA-Z]"))
        //.setEscapeCharacters(new UnicodeSet("[^\\u0020-\\u007E]")) // WARNING: DateFormat doesn't accept \\uXXXX
        .setUsingQuote(true);
        private List items = new ArrayList();
        
        /**
         * Set the string to parse
         * @param string
         * @return this, for chaining
         * @deprecated
         * @internal
         */
        public FormatParser set(String string) {
            items.clear();
            if (string.length() == 0) return this;
            tokenizer.setPattern(string);
            StringBuffer buffer = new StringBuffer();
            StringBuffer variable = new StringBuffer();
            while (true) {
                buffer.setLength(0);
                int status = tokenizer.next(buffer);
                if (status == PatternTokenizer.DONE) break;
                if (status == PatternTokenizer.SYNTAX) {
                    if (variable.length() != 0 && buffer.charAt(0) != variable.charAt(0)) {
                        addVariable(variable);
                    }
                    variable.append(buffer);
                } else {
                    addVariable(variable);
                    items.add(buffer.toString());
                }
            }
            addVariable(variable);
            return this;
        }
        
        private void addVariable(StringBuffer variable) {
            if (variable.length() != 0) {
                items.add(new VariableField(variable.toString()));
                variable.setLength(0);
            }
        }
        
        /** Return a collection of fields. These will be a mixture of Strings and VariableFields. Any "a" variable field is removed.
         * @param output List to append the items to. If null, is allocated as an ArrayList.
         * @return list
         */
        private List getVariableFields(List output) {
            if (output == null) output = new ArrayList();
            main:
                for (Iterator it = items.iterator(); it.hasNext();) {
                    Object item = it.next();
                    if (item instanceof VariableField) {
                        String s = item.toString();
                        switch(s.charAt(0)) {
                        //case 'Q': continue main; // HACK
                        case 'a': continue main; // remove
                        }
                        output.add(s);
                    }
                }
            //System.out.println(output);
            return output;
        }
        
        /**
         * @return a string which is a concatenation of all the variable fields
         * @deprecated
         * @internal
         */
        public String getVariableFieldString() {
            List list = getVariableFields(null);
            StringBuffer result = new StringBuffer();
            for (Iterator it = list.iterator(); it.hasNext();) {
                String item = (String) it.next();
                result.append(item);
            }
            return result.toString();
        }
        
        /**
         * Returns modifiable list which is a mixture of Strings and VariableFields, in the order found during parsing.
         * @return modifiable list of items.
         * @deprecated
         * @internal
         */
        public List getItems() {
            return items;
        }
        
        /** Provide display form of formatted input
         * @return printable output string
         * @deprecated
         * @internal
         */
        public String toString() {
            return toString(0, items.size());
        }
        
        /**
         * Provide display form of formatted input
         * @param start item to start from
         * @param limit last item +1
         * @return printable output string
         * @deprecated
         * @internal
         */
        public String toString(int start, int limit) {
            StringBuffer result = new StringBuffer();
            for (int i = start; i < limit; ++i) {
                result.append(items.get(i).toString());
            }
            return result.toString();
        }
        
        /**
         * Internal method <p>
         * Returns true if it has a mixture of date and time fields
         * @return true or false
         * @deprecated
         * @internal
         */
        public boolean hasDateAndTimeFields() {
            int foundMask = 0;
            for (Iterator it = items.iterator(); it.hasNext();) {
                Object item = it.next();
                if (item instanceof VariableField) {
                    int type = getType(item);
                    foundMask |= 1 << type;    
                }
            }
            boolean isDate = (foundMask & DATE_MASK) != 0;
            boolean isTime = (foundMask & TIME_MASK) != 0;
            return isDate && isTime;
        }
        
        /**
         * Internal routine
         * @param value
         * @param result
         * @return list
         * @deprecated
         * @internal
         */
        public List getAutoPatterns(String value, List result) {
            if (result == null) result = new ArrayList();
            int fieldCount = 0;
            int minField = Integer.MAX_VALUE;
            int maxField = Integer.MIN_VALUE;
            for (Iterator it = items.iterator(); it.hasNext();) {
                Object item = it.next();
                if (item instanceof VariableField) {
                    try {
                        int type = getType(item);
                        if (minField > type) minField = type;
                        if (maxField < type) maxField = type;
                        if (type == ZONE || type == DAYPERIOD || type == WEEKDAY) return result; // skip anything with zones                    
                        fieldCount++;
                    } catch (Exception e) {
                        return result; // if there are any funny fields, return
                    }
                }
            }
            if (fieldCount < 3) return result; // skip
            // trim from start
            // trim first field IF there are no letters around it
            // and it is either the min or the max field
            // first field is either 0 or 1
            for (int i = 0; i < items.size(); ++i) {
                Object item = items.get(i);
                if (item instanceof VariableField) {
                    int type = getType(item);
                    if (type != minField && type != maxField) break;
                    
                    if (i > 0) {
                        Object previousItem = items.get(0);
                        if (alpha.containsSome(previousItem.toString())) break;
                    }
                    int start = i+1;
                    if (start < items.size()) {
                        Object nextItem = items.get(start);
                        if (nextItem instanceof String) {
                            if (alpha.containsSome(nextItem.toString())) break;
                            start++; // otherwise skip over string
                        }
                    }
                    result.add(toString(start, items.size()));
                    break;
                }
            }
            // now trim from end
            for (int i = items.size()-1; i >= 0; --i) {
                Object item = items.get(i);
                if (item instanceof VariableField) {
                    int type = getType(item);
                    if (type != minField && type != maxField) break;
                    if (i < items.size() - 1) {
                        Object previousItem = items.get(items.size() - 1);
                        if (alpha.containsSome(previousItem.toString())) break;
                    }
                    int end = i-1;
                    if (end > 0) {
                        Object nextItem = items.get(end);
                        if (nextItem instanceof String) {
                            if (alpha.containsSome(nextItem.toString())) break;
                            end--; // otherwise skip over string
                        }
                    }
                    result.add(toString(0, end+1));
                    break;
                }
            }
            
            return result;
        }
        
        private static UnicodeSet alpha = new UnicodeSet("[:alphabetic:]");
        
        private int getType(Object item) {
            String s = item.toString();
            int canonicalIndex = getCanonicalIndex(s);
            if (canonicalIndex < 0) {
                throw new IllegalArgumentException("Illegal field:\t"
                        + s);
            }
            int type = types[canonicalIndex][1];
            return type;
        }
        
        /**
         *  produce a quoted literal
         * @param string
         * @return string with quoted literals
         * @deprecated
         * @internal
         */
        public Object quoteLiteral(String string) {
            return tokenizer.quoteLiteral(string);
        }
        
        /**
         * Simple constructor, since this is treated like a struct.
         * @deprecated
         * @internal
         */
        public FormatParser() {
            super();
            // TODO Auto-generated constructor stub
        }
    }
    // ========= PRIVATES ============
    
    private TreeMap skeleton2pattern = new TreeMap(); // items are in priority order
    private TreeMap basePattern_pattern = new TreeMap(); // items are in priority order
    private String decimal = "?";
    private String dateTimeFormat = "{0} {1}";
    private String[] appendItemFormats = new String[TYPE_LIMIT];
    private String[] appendItemNames = new String[TYPE_LIMIT];
    {
        for (int i = 0; i < TYPE_LIMIT; ++i) {
            appendItemFormats[i] = "{0} \u251C{2}: {1}\u2524";
            appendItemNames[i] = "F" + i;
        }
    }
    
    private transient DateTimeMatcher current = new DateTimeMatcher();
    private transient FormatParser fp = new FormatParser();
    private transient DistanceInfo _distanceInfo = new DistanceInfo();
    private transient boolean isComplete = false;
    private transient DateTimeMatcher skipMatcher = null; // only used temporarily, for internal purposes
    private transient boolean frozen = false;
    
    private transient boolean chineseMonthHack = false;
    
    private static final int FRACTIONAL_MASK = 1<<FRACTIONAL_SECOND;
    private static final int SECOND_AND_FRACTIONAL_MASK = (1<<SECOND) | (1<<FRACTIONAL_SECOND);
    
    private void checkFrozen() {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify frozen object");
        }
    }
    
    /**
     * We only get called here if we failed to find an exact skeleton. We have broken it into date + time, and look for the pieces.
     * If we fail to find a complete skeleton, we compose in a loop until we have all the fields.
     */
    private String getBestAppending(int missingFields) {
        String resultPattern = null;
        if (missingFields != 0) {
            resultPattern = getBestRaw(current, missingFields, _distanceInfo);
            resultPattern = adjustFieldTypes(resultPattern, current, false);
            
            while (_distanceInfo.missingFieldMask != 0) { // precondition: EVERY single field must work!
                
                // special hack for SSS. If we are missing SSS, and we had ss but found it, replace the s field according to the 
                // number separator
                if ((_distanceInfo.missingFieldMask & SECOND_AND_FRACTIONAL_MASK) == FRACTIONAL_MASK
                        && (missingFields & SECOND_AND_FRACTIONAL_MASK) == SECOND_AND_FRACTIONAL_MASK) {
                    resultPattern = adjustFieldTypes(resultPattern, current, true);
                    _distanceInfo.missingFieldMask &= ~FRACTIONAL_MASK; // remove bit
                    continue;
                }
                
                int startingMask = _distanceInfo.missingFieldMask;
                String temp = getBestRaw(current, _distanceInfo.missingFieldMask, _distanceInfo);
                temp = adjustFieldTypes(temp, current, false);
                int foundMask = startingMask & ~_distanceInfo.missingFieldMask;
                int topField = getTopBitNumber(foundMask);
                resultPattern = MessageFormat.format(getAppendFormat(topField), new Object[]{resultPattern, temp, getAppendName(topField)});
            }
        }
        return resultPattern;
    }
    
    private String getAppendName(int foundMask) {
        return "'" + appendItemNames[foundMask] + "'";
    }
    private String getAppendFormat(int foundMask) {
        return appendItemFormats[foundMask];
    }
    
    /**
     * @param current2
     * @return
     */
    private String adjustSeconds(DateTimeMatcher current2) {
        // TODO Auto-generated method stub
        return null;
    }
    
    /**
     * @param foundMask
     * @return
     */
    private int getTopBitNumber(int foundMask) {
        int i = 0;
        while (foundMask != 0) {
            foundMask >>>= 1;
            ++i;
        }
        return i-1;
    }
    
    /**
     * 
     */
    private void complete() {
        PatternInfo patternInfo = new PatternInfo();
        // make sure that every valid field occurs once, with a "default" length
        for (int i = 0; i < CANONICAL_ITEMS.length; ++i) {
            char c = (char)types[i][0];
            add(String.valueOf(CANONICAL_ITEMS[i]), false, patternInfo);
        }
        isComplete = true;
    }
    {
        complete();
    }
    
    /**
     * 
     */
    private String getBestRaw(DateTimeMatcher source, int includeMask, DistanceInfo missingFields) {
//      if (SHOW_DISTANCE) System.out.println("Searching for: " + source.pattern 
//      + ", mask: " + showMask(includeMask));
        int bestDistance = Integer.MAX_VALUE;
        String bestPattern = "";
        DistanceInfo tempInfo = new DistanceInfo();
        for (Iterator it = skeleton2pattern.keySet().iterator(); it.hasNext();) {
            DateTimeMatcher trial = (DateTimeMatcher) it.next();
            if (trial.equals(skipMatcher)) continue;
            int distance = source.getDistance(trial, includeMask, tempInfo);
//          if (SHOW_DISTANCE) System.out.println("\tDistance: " + trial.pattern + ":\t" 
//          + distance + ",\tmissing fields: " + tempInfo);
            if (distance < bestDistance) {
                bestDistance = distance;
                bestPattern = (String) skeleton2pattern.get(trial);
                missingFields.setTo(tempInfo);
                if (distance == 0) break;
            }
        }
        return bestPattern;
    }
    
    /**
     * @param fixFractionalSeconds TODO
     * 
     */
    private String adjustFieldTypes(String pattern, DateTimeMatcher inputRequest, boolean fixFractionalSeconds) {
        fp.set(pattern);
        StringBuffer newPattern = new StringBuffer();
        for (Iterator it = fp.getItems().iterator(); it.hasNext();) {
            Object item = it.next();
            if (item instanceof String) {
                newPattern.append(fp.quoteLiteral((String)item));
            } else {
                String field = ((VariableField) item).string;
                int canonicalIndex = getCanonicalIndex(field);
                if (canonicalIndex < 0) {
                    continue; // don't adjust
                }
                int type = types[canonicalIndex][1];
                if (fixFractionalSeconds && type == SECOND) {
                    String newField = inputRequest.original[FRACTIONAL_SECOND];
                    field = field + decimal + newField;
                } else if (inputRequest.type[type] != 0) {
                    String newField = inputRequest.original[type];
                    // normally we just replace the field. However HOUR is special; we only change the length
                    if (type != HOUR) {
                        field = newField;
                    } else if (field.length() != newField.length()){
                        char c = field.charAt(0);
                        field = "";
                        for (int i = newField.length(); i > 0; --i) field += c;
                    }
                }
                newPattern.append(field);
            }
        }
        //if (SHOW_DISTANCE) System.out.println("\tRaw: " + pattern);
        return newPattern.toString();
    }
    
//  public static String repeat(String s, int count) {
//  StringBuffer result = new StringBuffer();
//  for (int i = 0; i < count; ++i) {
//  result.append(s);
//  }
//  return result.toString();
//  }
    
    /**
     * internal routine
     * @param pattern
     * @return field value
     * @deprecated
     * @internal
     */
    public String getFields(String pattern) {
        fp.set(pattern);
        StringBuffer newPattern = new StringBuffer();
        for (Iterator it = fp.getItems().iterator(); it.hasNext();) {
            Object item = it.next();
            if (item instanceof String) {
                newPattern.append(fp.quoteLiteral((String)item));
            } else {
                newPattern.append("{" + getName(item.toString()) + "}");
            }
        }
        return newPattern.toString();
    }
    
    private static String showMask(int mask) {
        String result = "";
        for (int i = 0; i < TYPE_LIMIT; ++i) {
            if ((mask & (1<<i)) == 0) continue;
            if (result.length() != 0) result += " | ";
            result += FIELD_NAME[i] + " ";
        }
        return result;
    }
    
    static private String[] CLDR_FIELD_APPEND = {
        "Era", "Year", "Quarter", "Month", "Week", "*", "Day-Of-Week", 
        "Day", "*", "*", "*", 
        "Hour", "Minute", "Second", "*", "Timezone"
    };
    
    static private String[] CLDR_FIELD_NAME = {
        "era", "year", "quarter", "month", "week", "*", "weekday", 
        "day", "*", "*", "dayperiod", 
        "hour", "minute", "second", "*", "zone"
    };
    
    static private String[] FIELD_NAME = {
        "Era", "Year", "Quarter", "Month", "Week_in_Year", "Week_in_Month", "Weekday", 
        "Day", "Day_Of_Year", "Day_of_Week_in_Month", "Dayperiod", 
        "Hour", "Minute", "Second", "Fractional_Second", "Zone"
    };
    
    
    static private String[] CANONICAL_ITEMS = {
        "G", "y", "Q", "M", "w", "W", "e", 
        "d", "D", "F", 
        "H", "m", "s", "S", "v"
    };
    
    static private Set CANONICAL_SET = new HashSet(Arrays.asList(CANONICAL_ITEMS));
    
    static final private int 
    DATE_MASK = (1<<DAYPERIOD) - 1,
    TIME_MASK = (1<<TYPE_LIMIT) - 1 - DATE_MASK;
    
    static final private int // numbers are chosen to express 'distance'
    DELTA = 0x10,
    NUMERIC = 0x100,
    NONE = 0,
    NARROW = -0x100,
    SHORT = -0x101,
    LONG = -0x102,
    EXTRA_FIELD =   0x10000,
    MISSING_FIELD = 0x1000;
    
    
    static private String getName(String s) {
        int i = getCanonicalIndex(s);
        String name = FIELD_NAME[types[i][1]];
        int subtype = types[i][2];
        boolean string = subtype < 0;
        if (string) subtype = -subtype;
        if (subtype < 0) name += ":S";
        else name += ":N";
        return name;
    }
    
    static private int getCanonicalIndex(String s) {
        int len = s.length();
        int ch = s.charAt(0);
        for (int i = 0; i < types.length; ++i) {
            int[] row = types[i];
            if (row[0] != ch) continue;
            if (row[3] > len) continue;
            if (row[row.length-1] < len) continue;
            return i;
        }
        return -1;
    }
    
    static private int[][] types = {
        // the order here makes a difference only when searching for single field.
        // format is:
        // pattern character, main type, weight, min length, weight
        {'G', ERA, SHORT, 1, 3},
        {'G', ERA, LONG, 4},
        
        {'y', YEAR, NUMERIC, 1, 20},
        {'Y', YEAR, NUMERIC + DELTA, 1, 20},
        {'u', YEAR, NUMERIC + 2*DELTA, 1, 20},
        
        {'Q', QUARTER, NUMERIC, 1, 2},
        {'Q', QUARTER, SHORT, 3},
        {'Q', QUARTER, LONG, 4},
        
        {'M', MONTH, NUMERIC, 1, 2},
        {'M', MONTH, SHORT, 3},
        {'M', MONTH, LONG, 4},
        {'M', MONTH, NARROW, 5},
        {'L', MONTH, NUMERIC + DELTA, 1, 2},
        {'L', MONTH, SHORT - DELTA, 3},
        {'L', MONTH, LONG - DELTA, 4},
        {'L', MONTH, NARROW - DELTA, 5},
        
        {'w', WEEK_OF_YEAR, NUMERIC, 1, 2},
        {'W', WEEK_OF_MONTH, NUMERIC + DELTA, 1},
        
        {'e', WEEKDAY, NUMERIC + DELTA, 1, 2},
        {'e', WEEKDAY, SHORT - DELTA, 3},
        {'e', WEEKDAY, LONG - DELTA, 4},
        {'e', WEEKDAY, NARROW - DELTA, 5},
        {'E', WEEKDAY, SHORT, 1, 3},
        {'E', WEEKDAY, LONG, 4},
        {'E', WEEKDAY, NARROW, 5},
        {'c', WEEKDAY, NUMERIC + 2*DELTA, 1, 2},
        {'c', WEEKDAY, SHORT - 2*DELTA, 3},
        {'c', WEEKDAY, LONG - 2*DELTA, 4},
        {'c', WEEKDAY, NARROW - 2*DELTA, 5},
        
        {'d', DAY, NUMERIC, 1, 2},
        {'D', DAY_OF_YEAR, NUMERIC + DELTA, 1, 3},
        {'F', DAY_OF_WEEK_IN_MONTH, NUMERIC + 2*DELTA, 1},
        {'g', DAY, NUMERIC + 3*DELTA, 1, 20}, // really internal use, so we don't care
        
        {'a', DAYPERIOD, SHORT, 1},
        
        {'H', HOUR, NUMERIC + 10*DELTA, 1, 2}, // 24 hour
        {'k', HOUR, NUMERIC + 11*DELTA, 1, 2},
        {'h', HOUR, NUMERIC, 1, 2}, // 12 hour
        {'K', HOUR, NUMERIC + DELTA, 1, 2},
        
        {'m', MINUTE, NUMERIC, 1, 2},
        
        {'s', SECOND, NUMERIC, 1, 2},
        {'S', FRACTIONAL_SECOND, NUMERIC + DELTA, 1, 1000},
        {'A', SECOND, NUMERIC + 2*DELTA, 1, 1000},
        
        {'v', ZONE, SHORT - 2*DELTA, 1},
        {'v', ZONE, LONG - 2*DELTA, 4},
        {'z', ZONE, SHORT, 1, 3},
        {'z', ZONE, LONG, 4},
        {'Z', ZONE, SHORT - DELTA, 1, 3},
        {'Z', ZONE, LONG - DELTA, 4},
    };
    
    private static class DateTimeMatcher implements Comparable {
        //private String pattern = null;
        private int[] type = new int[TYPE_LIMIT];
        private String[] original = new String[TYPE_LIMIT];
        private String[] baseOriginal = new String[TYPE_LIMIT];
        
        // just for testing; fix to make multi-threaded later
        // private static FormatParser fp = new FormatParser();
        
        public String toString() {
            StringBuffer result = new StringBuffer();
            for (int i = 0; i < TYPE_LIMIT; ++i) {
                if (original[i].length() != 0) result.append(original[i]);
            }
            return result.toString();
        }
        
        String getBasePattern() {
            StringBuffer result = new StringBuffer();
            for (int i = 0; i < TYPE_LIMIT; ++i) {
                if (baseOriginal[i].length() != 0) result.append(baseOriginal[i]);
            }
            return result.toString();
        }
        
        DateTimeMatcher set(String pattern, FormatParser fp) {
            if (pattern.indexOf("\\u") >= 0) {
                String oldPattern = pattern;
                pattern = fromHex.transliterate(pattern);
            }
            for (int i = 0; i < TYPE_LIMIT; ++i) {
                type[i] = NONE;
                original[i] = "";
                baseOriginal[i] = "";
            }
            fp.set(pattern);
            for (Iterator it = fp.getVariableFields(new ArrayList()).iterator(); it.hasNext();) {
                String field = (String) it.next();
                if (field.charAt(0) == 'a') continue; // skip day period, special cass
                int canonicalIndex = getCanonicalIndex(field);
                if (canonicalIndex < 0) {
                    throw new IllegalArgumentException("Illegal field:\t"
                            + field + "\t in " + pattern);
                }
                int[] row = types[canonicalIndex];
                int typeValue = row[1];
                if (original[typeValue].length() != 0) {
                    throw new IllegalArgumentException("Conflicting fields:\t"
                            + original[typeValue] + ", " + field + "\t in " + pattern);
                }
                original[typeValue] = field;
                char repeatChar = (char)row[0];
                int repeatCount = row[3];
                if (repeatCount > 3) repeatCount = 3; // hack to discard differences
                if ("GEzvQ".indexOf(repeatChar) >= 0) repeatCount = 1;
                baseOriginal[typeValue] = Utility.repeat(String.valueOf(repeatChar),repeatCount);
                int subTypeValue = row[2];
                if (subTypeValue > 0) subTypeValue += field.length();
                type[typeValue] = (byte) subTypeValue;
            }
            return this;
        }
        
        /**
         * 
         */
        int getFieldMask() {
            int result = 0;
            for (int i = 0; i < type.length; ++i) {
                if (type[i] != 0) result |= (1<<i);
            }
            return result;
        }
        
        /**
         * 
         */
        void extractFrom(DateTimeMatcher source, int fieldMask) {
            for (int i = 0; i < type.length; ++i) {
                if ((fieldMask & (1<<i)) != 0) {
                    type[i] = source.type[i];
                    original[i] = source.original[i];
                } else {
                    type[i] = NONE;
                    original[i] = "";
                }
            }
        }
        
        int getDistance(DateTimeMatcher other, int includeMask, DistanceInfo distanceInfo) {
            int result = 0;
            distanceInfo.clear();
            for (int i = 0; i < type.length; ++i) {
                int myType = (includeMask & (1<<i)) == 0 ? 0 : type[i];
                int otherType = other.type[i];
                if (myType == otherType) continue; // identical (maybe both zero) add 0
                if (myType == 0) { // and other is not
                    result += EXTRA_FIELD;
                    distanceInfo.addExtra(i);
                } else if (otherType == 0) { // and mine is not
                    result += MISSING_FIELD;
                    distanceInfo.addMissing(i);
                } else {
                    result += Math.abs(myType - otherType); // square of mismatch
                }
            }
            return result;
        }
        
        public int compareTo(Object o) {
            DateTimeMatcher that = (DateTimeMatcher) o;
            for (int i = 0; i < original.length; ++i) {
                int comp = original[i].compareTo(that.original[i]);
                if (comp != 0) return -comp;
            }
            return 0;
        }       
        
        public boolean equals(Object other) {
            if (other == null) return false;
            DateTimeMatcher that = (DateTimeMatcher) other;
            for (int i = 0; i < original.length; ++i) {
                if (!original[i].equals(that.original[i])) return false;
            }
            return true;
        }       
        public int hashCode() {
            int result = 0;
            for (int i = 0; i < original.length; ++i) {
                result ^= original[i].hashCode();
            }
            return result;
        }       
    }
    
    private static class DistanceInfo {
        int missingFieldMask;
        int extraFieldMask;
        void clear() {
            missingFieldMask = extraFieldMask = 0;
        }
        /**
         * 
         */
        void setTo(DistanceInfo other) {
            missingFieldMask = other.missingFieldMask;
            extraFieldMask = other.extraFieldMask;
        }
        void addMissing(int field) {
            missingFieldMask |= (1<<field);
        }
        void addExtra(int field) {
            extraFieldMask |= (1<<field);
        }
        public String toString() {
            return "missingFieldMask: " + DateTimePatternGenerator.showMask(missingFieldMask)
            + ", extraFieldMask: " + DateTimePatternGenerator.showMask(extraFieldMask);
        }
    }
}
//#endif
//eof
