/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans.impl.xsd2inst;

/*
 * TODO:
*  Comment on enumerations?
*  Comment on facets?
*  Have a verbose option?
*  Have a sample data option, would create valid instance with sample data?
*  Add the pattern facet; this is tricky, considering the relationship with length
*/

import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.SchemaParticle;
import org.apache.xmlbeans.SchemaLocalElement;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.GDuration;
import org.apache.xmlbeans.GDurationBuilder;
import org.apache.xmlbeans.GDate;
import org.apache.xmlbeans.GDateBuilder;
import org.apache.xmlbeans.XmlAnySimpleType;
import org.apache.xmlbeans.SimpleValue;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlInteger;
import org.apache.xmlbeans.XmlDate;
import org.apache.xmlbeans.XmlDateTime;
import org.apache.xmlbeans.XmlTime;
import org.apache.xmlbeans.XmlGYear;
import org.apache.xmlbeans.XmlGYearMonth;
import org.apache.xmlbeans.XmlGMonth;
import org.apache.xmlbeans.XmlGMonthDay;
import org.apache.xmlbeans.XmlGDay;
import org.apache.xmlbeans.XmlDecimal;
import org.apache.xmlbeans.XmlDuration;
import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
import org.apache.xmlbeans.soap.SOAPArrayType;
import org.apache.xmlbeans.impl.util.Base64;
import org.apache.xmlbeans.impl.util.HexBin;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;

import javax.xml.namespace.QName;

public class SampleXmlUtil
{
    private boolean _soapEnc;
    private static final int MAX_ELEMENTS = 1000;
    private int _nElements;

    private SampleXmlUtil(boolean soapEnc)
    {
        _soapEnc = soapEnc;
    }

    public static String createSampleForType(SchemaType sType)
    {
        XmlObject object = XmlObject.Factory.newInstance();
        XmlCursor cursor = object.newCursor();
        // Skip the document node
        cursor.toNextToken();
        // Using the type and the cursor, call the utility method to get a
        // sample XML payload for that Schema element
        new SampleXmlUtil(false).createSampleForType(sType, cursor);
        // Cursor now contains the sample payload
        // Pretty print the result.  Note that the cursor is positioned at the
        // end of the doc so we use the original xml object that the cursor was
        // created upon to do the xmlText() against.
        XmlOptions options = new XmlOptions();
        options.put(XmlOptions.SAVE_PRETTY_PRINT);
        options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 2);
        options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES);
        String result = object.xmlText(options);
        return result;
    }

    Random _picker = new Random(1);

    /**
     * Cursor position
     * Before:
     * <theElement>^</theElement>
     * After:
     * <theElement><lots of stuff/>^</theElement>
     */
    private void createSampleForType(SchemaType stype, XmlCursor xmlc)
    {
        if (_typeStack.contains( stype ))
            return;

        _typeStack.add( stype );
        
        try
        {
            if (stype.isSimpleType() || stype.isURType())
            {
                processSimpleType(stype, xmlc);
                return;
            }
            
            // complex Type
            // <theElement>^</theElement>
            processAttributes(stype, xmlc);
            
            // <theElement attri1="string">^</theElement>
            switch (stype.getContentType())
            {
                case SchemaType.NOT_COMPLEX_TYPE :
                case SchemaType.EMPTY_CONTENT :
                    // noop
                    break;
                case SchemaType.SIMPLE_CONTENT :
                    {
                        processSimpleType(stype, xmlc);
                    }
                    break;
                case SchemaType.MIXED_CONTENT :
                    xmlc.insertChars(pick(WORDS) + " ");
                    if (stype.getContentModel() != null)
                    {
                        processParticle(stype.getContentModel(), xmlc, true);
                    }
                    xmlc.insertChars(pick(WORDS));
                    break;
                case SchemaType.ELEMENT_CONTENT :
                    if (stype.getContentModel() != null)
                    {
                        processParticle(stype.getContentModel(), xmlc, false);
                    }
                    break;
            }
        }
        finally
        {
            _typeStack.remove( _typeStack.size() - 1 );
        }
    }

    private void processSimpleType(SchemaType stype, XmlCursor xmlc)
    {
        String sample = sampleDataForSimpleType(stype);
        xmlc.insertChars(sample);
    }
    
    private String sampleDataForSimpleType(SchemaType sType)
    {
        if (XmlObject.type.equals(sType))
            return "anyType";
        
        if (XmlAnySimpleType.type.equals(sType))
            return "anySimpleType";
        
        if (sType.getSimpleVariety() == SchemaType.LIST)
        {
            SchemaType itemType = sType.getListItemType();
            StringBuilder sb = new StringBuilder();
            int length = pickLength(sType);
            if (length > 0)
                sb.append(sampleDataForSimpleType(itemType));
            for (int i = 1; i < length; i += 1)
            {
                sb.append(' ');
                sb.append(sampleDataForSimpleType(itemType));
            }
            return sb.toString(); 
        }
        
        if (sType.getSimpleVariety() == SchemaType.UNION)
        {
            SchemaType[] possibleTypes = sType.getUnionConstituentTypes();
            if (possibleTypes.length == 0)
                return "";
            return sampleDataForSimpleType(possibleTypes[pick(possibleTypes.length)]);
        }
        
        XmlAnySimpleType[] enumValues = sType.getEnumerationValues();
        if (enumValues != null && enumValues.length > 0)
        {
            return enumValues[pick(enumValues.length)].getStringValue();
        }
        
        switch (sType.getPrimitiveType().getBuiltinTypeCode())
        {
            default:
            case SchemaType.BTC_NOT_BUILTIN:
                return "";
            
            case SchemaType.BTC_ANY_TYPE:
            case SchemaType.BTC_ANY_SIMPLE:
                return "anything";
                
            case SchemaType.BTC_BOOLEAN:
                return pick(2) == 0 ? "true" : "false";
                
            case SchemaType.BTC_BASE_64_BINARY:
            {
                String result = null;
                try
                {   result = new String(Base64.encode(formatToLength(pick(WORDS), sType).getBytes("utf-8"))); }
                catch (java.io.UnsupportedEncodingException e)
                {  /* Can't possibly happen */ }
                return result;
            }
                
            case SchemaType.BTC_HEX_BINARY:
                return HexBin.encode(formatToLength(pick(WORDS), sType));
                
            case SchemaType.BTC_ANY_URI:
                return formatToLength("http://www." + pick(DNS1) + "." + pick(DNS2) + "/" + pick(WORDS) + "/" + pick(WORDS), sType);
                
            case SchemaType.BTC_QNAME:
                return formatToLength("qname", sType);
                
            case SchemaType.BTC_NOTATION:
                return formatToLength("notation", sType);
                
            case SchemaType.BTC_FLOAT:
                return "1.5E2";
            case SchemaType.BTC_DOUBLE:
                return "1.051732E7";
            case SchemaType.BTC_DECIMAL:
                switch (closestBuiltin(sType).getBuiltinTypeCode())
                {
                    case SchemaType.BTC_SHORT:
                        return formatDecimal("1", sType);
                    case SchemaType.BTC_UNSIGNED_SHORT:
                        return formatDecimal("5", sType);
                    case SchemaType.BTC_BYTE:
                        return formatDecimal("2", sType);
                    case SchemaType.BTC_UNSIGNED_BYTE:
                        return formatDecimal("6", sType);
                    case SchemaType.BTC_INT:
                        return formatDecimal("3", sType);
                    case SchemaType.BTC_UNSIGNED_INT:
                        return formatDecimal("7", sType);
                    case SchemaType.BTC_LONG:
                        return formatDecimal("10", sType);
                    case SchemaType.BTC_UNSIGNED_LONG:
                        return formatDecimal("11", sType);
                    case SchemaType.BTC_INTEGER:
                        return formatDecimal("100", sType);
                    case SchemaType.BTC_NON_POSITIVE_INTEGER:
                        return formatDecimal("-200", sType);
                    case SchemaType.BTC_NEGATIVE_INTEGER:
                        return formatDecimal("-201", sType);
                    case SchemaType.BTC_NON_NEGATIVE_INTEGER:
                        return formatDecimal("200", sType);
                    case SchemaType.BTC_POSITIVE_INTEGER:
                        return formatDecimal("201", sType);
                    default:
                    case SchemaType.BTC_DECIMAL:
                        return formatDecimal("1000.00", sType);
                }
                
            case SchemaType.BTC_STRING:
                {
                    String result;
                    switch (closestBuiltin(sType).getBuiltinTypeCode())
                    {
                        case SchemaType.BTC_STRING:
                        case SchemaType.BTC_NORMALIZED_STRING:
                            result = "string";
                            break;
                            
                        case SchemaType.BTC_TOKEN:
                            result = "token";
                            break;
                            
                        default:
                            result = "string";
                            break;
                    }
                        
                    return formatToLength(result, sType);
                }

            case SchemaType.BTC_DURATION:
                return formatDuration(sType);
                
            case SchemaType.BTC_DATE_TIME:
            case SchemaType.BTC_TIME:
            case SchemaType.BTC_DATE:
            case SchemaType.BTC_G_YEAR_MONTH:
            case SchemaType.BTC_G_YEAR:
            case SchemaType.BTC_G_MONTH_DAY:
            case SchemaType.BTC_G_DAY:
            case SchemaType.BTC_G_MONTH:
                return formatDate(sType);
        }
    }
    
    // a bit from the Aenid
    public static final String[] WORDS = new String[]
    {
    "ipsa", "iovis", "rapidum", "iaculata", "e", "nubibus", "ignem",
    "disiecitque", "rates", "evertitque", "aequora", "ventis",
    "illum", "exspirantem", "transfixo", "pectore", "flammas",
    "turbine", "corripuit", "scopuloque", "infixit", "acuto",
    "ast", "ego", "quae", "divum", "incedo", "regina", "iovisque",
    "et", "soror", "et", "coniunx", "una", "cum", "gente", "tot", "annos",
    "bella", "gero", "et", "quisquam", "numen", "iunonis", "adorat",
    "praeterea", "aut", "supplex", "aris", "imponet", "honorem",
    "talia", "flammato", "secum", "dea", "corde", "volutans",
    "nimborum", "in", "patriam", "loca", "feta", "furentibus", "austris",
    "aeoliam", "venit", "hic", "vasto", "rex", "aeolus", "antro",
    "luctantis", "ventos", "tempestatesque", "sonoras",
    "imperio", "premit", "ac", "vinclis", "et", "carcere", "frenat",
    "illi", "indignantes", "magno", "cum", "murmure", "montis",
    "circum", "claustra", "fremunt", "celsa", "sedet", "aeolus", "arce",
    "sceptra", "tenens", "mollitque", "animos", "et", "temperat", "iras",
    "ni", "faciat", "maria", "ac", "terras", "caelumque", "profundum",
    "quippe", "ferant", "rapidi", "secum", "verrantque", "per", "auras",
    "sed", "pater", "omnipotens", "speluncis", "abdidit", "atris",
    "hoc", "metuens", "molemque", "et", "montis", "insuper", "altos",
    "imposuit", "regemque", "dedit", "qui", "foedere", "certo",
    "et", "premere", "et", "laxas", "sciret", "dare", "iussus", "habenas",
    };
    
    
    
    private static final String[] DNS1 = new String[] { "corp", "your", "my", "sample", "company", "test", "any" };
    private static final String[] DNS2 = new String[] { "com", "org", "com", "gov", "org", "com", "org", "com", "edu" };
                                                       
    private int pick(int n)
    {
        return _picker.nextInt(n);
    }
    
    private String pick(String[] a)
    {
        return a[pick(a.length)];
    }
    
    private String pick(String[] a, int count)
    {
        if (count <= 0)
            return "";
            
        int i = pick(a.length);
        StringBuilder sb = new StringBuilder(a[i]);
        while (count-- > 0)
        {
            i += 1;
            if (i >= a.length)
                i = 0;
            sb.append(' ');
            sb.append(a[i]);
        }
        return sb.toString();
    }
    
    private String pickDigits(int digits)
    {
        StringBuilder sb = new StringBuilder();
        while (digits-- > 0)
            sb.append(Integer.toString(pick(10)));
        return sb.toString();
    }

    private int pickLength(SchemaType sType)
    {
        XmlInteger length = (XmlInteger) sType.getFacet(SchemaType.FACET_LENGTH);
        if (length != null)
            return length.getBigIntegerValue().intValue();
        XmlInteger min    = (XmlInteger) sType.getFacet(SchemaType.FACET_MIN_LENGTH);
        XmlInteger max    = (XmlInteger) sType.getFacet(SchemaType.FACET_MAX_LENGTH);
        int minInt, maxInt;
        if (min == null)
            minInt = 0;
        else
            minInt = min.getBigIntegerValue().intValue();
        if (max == null)
            maxInt = Integer.MAX_VALUE;
        else
            maxInt = max.getBigIntegerValue().intValue();
        // We try to keep the length of the array within reasonable limits,
        // at least 1 item and at most 3 if possible
        if (minInt == 0 && maxInt >= 1)
            minInt = 1;
        if (maxInt > minInt + 2)
            maxInt = minInt + 2;
        if (maxInt < minInt)
            maxInt = minInt;
        return minInt + pick(maxInt-minInt);
    }

    /**
     * Formats a given string to the required length, using the following operations:
     * - append the source string to itself as necessary to pass the minLength;
     * - truncate the result of previous step, if necessary, to keep it within minLength.
     */
    private String formatToLength(String s, SchemaType sType)
    {
        String result = s;
        try
        {
            SimpleValue min = (SimpleValue)sType.getFacet(SchemaType.FACET_LENGTH);
            if (min == null)
                min = (SimpleValue)sType.getFacet(SchemaType.FACET_MIN_LENGTH);
            if (min != null)
            {
                int len = min.getIntValue();
                while (result.length() < len)
                    result = result + result;
            }
            SimpleValue max = (SimpleValue)sType.getFacet(SchemaType.FACET_LENGTH);
            if (max == null)
                max = (SimpleValue)sType.getFacet(SchemaType.FACET_MAX_LENGTH);
            if (max != null)
            {
                int len = max.getIntValue();
                if (result.length() > len)
                    result = result.substring(0, len);
            }
        }
        catch (Exception e) // intValue can be out of range
        {
        }
        return result;
    }

    private String formatDecimal(String start, SchemaType sType)
    {
        BigDecimal result = new BigDecimal(start);
        XmlDecimal xmlD;
        xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
        BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null;
        xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
        BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null;
        boolean minInclusive = true, maxInclusive = true;
        xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
        if (xmlD != null)
        {
            BigDecimal minExcl = xmlD.getBigDecimalValue();
            if (min == null || min.compareTo(minExcl) < 0)
            {
                min = minExcl;
                minInclusive = false;
            }
        }
        xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
        if (xmlD != null)
        {
            BigDecimal maxExcl = xmlD.getBigDecimalValue();
            if (max == null || max.compareTo(maxExcl) > 0)
            {
                max = maxExcl;
                maxInclusive = false;
            }
        }
        xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS);
        int totalDigits = -1;
        if (xmlD != null)
        {
            totalDigits = xmlD.getBigDecimalValue().intValue();

            StringBuilder sb = new StringBuilder(totalDigits);
            for (int i = 0; i < totalDigits; i++)
                sb.append('9');
            BigDecimal digitsLimit = new BigDecimal(sb.toString());
            if (max != null && max.compareTo(digitsLimit) > 0)
            {
                max = digitsLimit;
                maxInclusive = true;
            }
            digitsLimit = digitsLimit.negate();
            if (min != null && min.compareTo(digitsLimit) < 0)
            {
                min = digitsLimit;
                minInclusive = true;
            }
        }

        int sigMin = min == null ? 1 : result.compareTo(min);
        int sigMax = max == null ? -1 : result.compareTo(max);
        boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive;
        boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive;

        // Compute the minimum increment
        xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS);
        int fractionDigits = -1;
        BigDecimal increment;
        if (xmlD == null)
            increment = new BigDecimal(1);
        else
        {
            fractionDigits = xmlD.getBigDecimalValue().intValue();
            if (fractionDigits > 0)
            {
                StringBuilder sb = new StringBuilder("0.");
                for (int i = 1; i < fractionDigits; i++)
                    sb.append('0');
                sb.append('1');
                increment = new BigDecimal(sb.toString());
            }
            else
                increment = new BigDecimal(1.0);
        }

        if (minOk && maxOk)
        {
            // OK 
        }
        else if (minOk && !maxOk)
        {
            // TOO BIG
            if (maxInclusive)
                result = max;
            else
                result = max.subtract(increment);
        }
        else if (!minOk && maxOk)
        {
            // TOO SMALL
            if (minInclusive)
                result = min;
            else
                result = min.add(increment);
        }
        else
        {
            // MIN > MAX!!
        }

        // We have the number
        // Adjust the scale according to the totalDigits and fractionDigits
        int digits = 0;
        BigDecimal ONE = new BigDecimal(BigInteger.ONE);
        for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++)
            n = n.movePointLeft(1);

        if (fractionDigits > 0)
            if (totalDigits >= 0)
                result = result.setScale(Math.max(fractionDigits, totalDigits - digits));
            else
                result = result.setScale(fractionDigits);
        else if (fractionDigits == 0)
            result = result.setScale(0);

        return result.toString();
    }

    private String formatDuration(SchemaType sType)
    {
        XmlDuration d =
            (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
        GDuration minInclusive = null;
        if (d != null)
            minInclusive = d.getGDurationValue();

        d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
        GDuration maxInclusive = null;
        if (d != null)
            maxInclusive = d.getGDurationValue();

        d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
        GDuration minExclusive = null;
        if (d != null)
            minExclusive = d.getGDurationValue();

        d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
        GDuration maxExclusive = null;
        if (d != null)
            maxExclusive = d.getGDurationValue();

        GDurationBuilder gdurb = new GDurationBuilder();
        BigInteger min, max;

        gdurb.setSecond(pick(800000));
        gdurb.setMonth(pick(20));

        // Years
        // Months
        // Days
        // Hours
        // Minutes
        // Seconds
        // Fractions
        if (minInclusive != null)
        {
            if (gdurb.getYear() < minInclusive.getYear())
                gdurb.setYear(minInclusive.getYear());
            if (gdurb.getMonth() < minInclusive.getMonth())
                gdurb.setMonth(minInclusive.getMonth());
            if (gdurb.getDay() < minInclusive.getDay())
                gdurb.setDay(minInclusive.getDay());
            if (gdurb.getHour() < minInclusive.getHour())
                gdurb.setHour(minInclusive.getHour());
            if (gdurb.getMinute() < minInclusive.getMinute())
                gdurb.setMinute(minInclusive.getMinute());
            if (gdurb.getSecond() < minInclusive.getSecond())
                gdurb.setSecond(minInclusive.getSecond());
            if (gdurb.getFraction().compareTo(minInclusive.getFraction()) < 0)
                gdurb.setFraction(minInclusive.getFraction());
        }

        if (maxInclusive != null)
        {
            if (gdurb.getYear() > maxInclusive.getYear())
                gdurb.setYear(maxInclusive.getYear());
            if (gdurb.getMonth() > maxInclusive.getMonth())
                gdurb.setMonth(maxInclusive.getMonth());
            if (gdurb.getDay() > maxInclusive.getDay())
                gdurb.setDay(maxInclusive.getDay());
            if (gdurb.getHour() > maxInclusive.getHour())
                gdurb.setHour(maxInclusive.getHour());
            if (gdurb.getMinute() > maxInclusive.getMinute())
                gdurb.setMinute(maxInclusive.getMinute());
            if (gdurb.getSecond() > maxInclusive.getSecond())
                gdurb.setSecond(maxInclusive.getSecond());
            if (gdurb.getFraction().compareTo(maxInclusive.getFraction()) > 0)
                gdurb.setFraction(maxInclusive.getFraction());
        }

        if (minExclusive != null)
        {
            if (gdurb.getYear() <= minExclusive.getYear())
                gdurb.setYear(minExclusive.getYear()+1);
            if (gdurb.getMonth() <= minExclusive.getMonth())
                gdurb.setMonth(minExclusive.getMonth()+1);
            if (gdurb.getDay() <= minExclusive.getDay())
                gdurb.setDay(minExclusive.getDay()+1);
            if (gdurb.getHour() <= minExclusive.getHour())
                gdurb.setHour(minExclusive.getHour()+1);
            if (gdurb.getMinute() <= minExclusive.getMinute())
                gdurb.setMinute(minExclusive.getMinute()+1);
            if (gdurb.getSecond() <= minExclusive.getSecond())
                gdurb.setSecond(minExclusive.getSecond()+1);
            if (gdurb.getFraction().compareTo(minExclusive.getFraction()) <= 0)
                gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal(0.001)));
        }

        if (maxExclusive != null)
        {
            if (gdurb.getYear() > maxExclusive.getYear())
                gdurb.setYear(maxExclusive.getYear());
            if (gdurb.getMonth() > maxExclusive.getMonth())
                gdurb.setMonth(maxExclusive.getMonth());
            if (gdurb.getDay() > maxExclusive.getDay())
                gdurb.setDay(maxExclusive.getDay());
            if (gdurb.getHour() > maxExclusive.getHour())
                gdurb.setHour(maxExclusive.getHour());
            if (gdurb.getMinute() > maxExclusive.getMinute())
                gdurb.setMinute(maxExclusive.getMinute());
            if (gdurb.getSecond() > maxExclusive.getSecond())
                gdurb.setSecond(maxExclusive.getSecond());
            if (gdurb.getFraction().compareTo(maxExclusive.getFraction()) > 0)
                gdurb.setFraction(maxExclusive.getFraction());
        }

        gdurb.normalize();
        return gdurb.toString();
    }

    private String formatDate(SchemaType sType)
    {
        GDateBuilder gdateb = new GDateBuilder(new Date(1000L * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365 * 24 * 60 * 60 * 1000));
        GDate min = null, max = null;
        GDate temp;

        // Find the min and the max according to the type
        switch (sType.getPrimitiveType().getBuiltinTypeCode())
        {
            case SchemaType.BTC_DATE_TIME:
            {
                XmlDateTime x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_TIME:
            {
                XmlTime x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_DATE:
            {
                XmlDate x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_G_YEAR_MONTH:
            {
                XmlGYearMonth x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_G_YEAR:
            {
                XmlGYear x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_G_MONTH_DAY:
            {
                XmlGMonthDay x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_G_DAY:
            {
                XmlGDay x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
            case SchemaType.BTC_G_MONTH:
            {
                XmlGMonth x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
                if (x != null)
                    min = x.getGDateValue();
                x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
                if (x != null)
                    if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
                        min = x.getGDateValue();

                x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
                if (x != null)
                    max = x.getGDateValue();
                x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
                if (x != null)
                    if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
                        max = x.getGDateValue();
                break;
            }
        }

        if (min != null && max == null)
        {
            if (min.compareToGDate(gdateb) >= 0)
            {
                // Reset the date to min + (1-8) hours
                Calendar c = gdateb.getCalendar();
                c.add(Calendar.HOUR_OF_DAY, pick(8));
                gdateb = new GDateBuilder(c);
            }
        }
        else if (min == null && max != null)
        {
            if (max.compareToGDate(gdateb) <= 0)
            {
                // Reset the date to max - (1-8) hours
                Calendar c = gdateb.getCalendar();
                c.add(Calendar.HOUR_OF_DAY, 0-pick(8));
                gdateb = new GDateBuilder(c);
            }
        }
        else if (min != null && max != null)
        {
            if (min.compareToGDate(gdateb) >= 0 || max.compareToGDate(gdateb) <= 0)
            {
                // Find a date between the two
                Calendar c = min.getCalendar();
                Calendar cmax = max.getCalendar();
                c.add(Calendar.HOUR_OF_DAY, 1);
                if (c.after(cmax))
                {
                    c.add(Calendar.HOUR_OF_DAY, -1);
                    c.add(Calendar.MINUTE, 1);
                    if (c.after(cmax))
                    {
                        c.add(Calendar.MINUTE, -1);
                        c.add(Calendar.SECOND, 1);
                        if (c.after(cmax))
                        {
                            c.add(Calendar.SECOND, -1);
                            c.add(Calendar.MILLISECOND, 1);
                            if (c.after(cmax))
                                c.add(Calendar.MILLISECOND, -1);
                        }
                    }
                }
                gdateb = new GDateBuilder(c);
            }
        }

        gdateb.setBuiltinTypeCode(sType.getPrimitiveType().getBuiltinTypeCode());
        if (pick(2) == 0)
            gdateb.clearTimeZone();
        return gdateb.toString();
    }

    private SchemaType closestBuiltin(SchemaType sType)
    {
        while (!sType.isBuiltinType())
            sType = sType.getBaseType();
        return sType;
    }

    /**
     * Cracks a combined QName of the form URL:localname
     */
    public static QName crackQName(String qName)
    {
        String ns;
        String name;

        int index = qName.lastIndexOf( ':' );
        if (index >= 0)
        {
            ns   = qName.substring( 0, index );
            name = qName.substring( index + 1);
        }
        else
        {
            ns   = "";
            name = qName;
        }

        return new QName(ns, name);
    }


    /**
     * Cursor position:
     * Before this call:
     * <outer><foo/>^</outer>  (cursor at the ^)
     * After this call:
     * <<outer><foo/><bar/>som text<etc/>^</outer>
     */
    private void processParticle(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    {
        int loop = determineMinMaxForSample(sp, xmlc);

        while (loop-- > 0)
        {
            switch (sp.getParticleType())
            {
                case (SchemaParticle.ELEMENT) :
                    processElement(sp, xmlc, mixed);
                    break;
                case (SchemaParticle.SEQUENCE) :
                    processSequence(sp, xmlc, mixed);
                    break;
                case (SchemaParticle.CHOICE) :
                    processChoice(sp, xmlc, mixed);
                    break;
                case (SchemaParticle.ALL) :
                    processAll(sp, xmlc, mixed);
                    break;
                case (SchemaParticle.WILDCARD) :
                    processWildCard(sp, xmlc, mixed);
                    break;
                default :
                    // throw new Exception("No Match on Schema Particle Type: " + String.valueOf(sp.getParticleType()));
            }
        }
    }

    private int determineMinMaxForSample(SchemaParticle sp, XmlCursor xmlc)
    {
        int minOccurs = sp.getIntMinOccurs();
        int maxOccurs = sp.getIntMaxOccurs();
        
        if (minOccurs == maxOccurs)
            return minOccurs;
        
        int result = minOccurs;
        if (result == 0 && _nElements < MAX_ELEMENTS)
            result = 1;
        
        if (sp.getParticleType() != SchemaParticle.ELEMENT)
            return result;
        
        // it probably only makes sense to put comments in front of individual elements that repeat
        
        if (sp.getMaxOccurs() == null)
        {
            // xmlc.insertComment("The next " + getItemNameOrType(sp, xmlc) + " may be repeated " + minOccurs + " or more times");
            if (minOccurs == 0)
                xmlc.insertComment("Zero or more repetitions:");
            else
                xmlc.insertComment(minOccurs + " or more repetitions:");
        }
        else if (sp.getIntMaxOccurs() > 1)
        {
            xmlc.insertComment(minOccurs + " to " + String.valueOf(sp.getMaxOccurs()) + " repetitions:");
        }
        else
        {
            xmlc.insertComment("Optional:");
        }
        return result;
    }

    /*
     Return a name for the element or the particle type to use in the comment for minoccurs, max occurs
    */
    private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc)
    {
        String elementOrTypeName = null;
        if (sp.getParticleType() == SchemaParticle.ELEMENT)
        {
            elementOrTypeName = "Element (" + sp.getName().getLocalPart() + ")";
        }
        else
        {
            elementOrTypeName = printParticleType(sp.getParticleType());
        }
        return elementOrTypeName;
    }

    private void processElement(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    {
        // cast as schema local element
        SchemaLocalElement element = (SchemaLocalElement) sp;
        /// ^  -> <elemenname></elem>^
        if (_soapEnc)
            xmlc.insertElement(element.getName().getLocalPart()); // soap encoded? drop namespaces.
        else
            xmlc.insertElement(element.getName().getLocalPart(), element.getName().getNamespaceURI());
        _nElements++;
        /// -> <elem>^</elem>
        xmlc.toPrevToken();
        // -> <elem>stuff^</elem>

        createSampleForType(element.getType(), xmlc);
        // -> <elem>stuff</elem>^
        xmlc.toNextToken();

    }

    private void moveToken(int numToMove, XmlCursor xmlc)
    {
        for (int i = 0; i < Math.abs(numToMove); i++)
        {
            if (numToMove < 0)
            {
                xmlc.toPrevToken();
            }
            else
            {
                xmlc.toNextToken();
            }
        }
    }
    
    private static final String formatQName(XmlCursor xmlc, QName qName)
    {
        XmlCursor parent = xmlc.newCursor();
        parent.toParent();
        String prefix = parent.prefixForNamespace(qName.getNamespaceURI());
        parent.dispose();
        String name;
        if (prefix == null || prefix.length() == 0)
            name = qName.getLocalPart();
        else
            name = prefix + ":" + qName.getLocalPart();
        return name;
    }
    
    private static final QName HREF = new QName("href"); 
    private static final QName ID = new QName("id"); 
    private static final QName XSI_TYPE = new QName("http://www.w3.org/2001/XMLSchema-instance", "type"); 
    private static final QName ENC_ARRAYTYPE = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType");
    private static final QName ENC_OFFSET = new QName("http://schemas.xmlsoap.org/soap/encoding/", "offset");
    
    private static final Set SKIPPED_SOAP_ATTRS = new HashSet(Arrays.asList(new QName[] { HREF, ID, ENC_OFFSET}));
    private void processAttributes(SchemaType stype, XmlCursor xmlc)
    {
        if (_soapEnc)
        {
            QName typeName = stype.getName();
            if (typeName != null)
            {
                xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(xmlc, typeName));
            }
        }
        
        SchemaProperty[] attrProps = stype.getAttributeProperties();
        for (int i = 0; i < attrProps.length; i++)
        {
            SchemaProperty attr = attrProps[i];
            if (_soapEnc)
            {
                if (SKIPPED_SOAP_ATTRS.contains(attr.getName()))
                    continue;
                if (ENC_ARRAYTYPE.equals(attr.getName()))
                {
                    SOAPArrayType arrayType = ((SchemaWSDLArrayType)stype.getAttributeModel().getAttribute(attr.getName())).getWSDLArrayType();
                    if (arrayType != null)
                        xmlc.insertAttributeWithValue(attr.getName(), formatQName(xmlc, arrayType.getQName()) + arrayType.soap11DimensionString());
                    continue;
                }
            }
            String defaultValue = attr.getDefaultText();
            xmlc.insertAttributeWithValue(attr.getName(), defaultValue == null ?
                sampleDataForSimpleType(attr.getType()) : defaultValue);
        }
    }

    private void processSequence(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    {
        SchemaParticle[] spc = sp.getParticleChildren();
        for (int i=0; i < spc.length; i++)
        {
            /// <parent>maybestuff^</parent>
            processParticle(spc[i], xmlc, mixed);
            //<parent>maybestuff...morestuff^</parent>
            if (mixed && i < spc.length-1)
                xmlc.insertChars(pick(WORDS));
        }
    }

    private void processChoice(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    {
        SchemaParticle[] spc = sp.getParticleChildren();
        xmlc.insertComment("You have a CHOICE of the next " + String.valueOf(spc.length) + " items at this level");
        for (int i=0; i < spc.length; i++)
        {
            processParticle(spc[i], xmlc, mixed);
        }
    }

    private void processAll(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    {
        SchemaParticle[] spc = sp.getParticleChildren();
        // xmlc.insertComment("You may enter the following " + String.valueOf(spc.length) + " items in any order");
        for (int i=0; i < spc.length; i++)
        {
            processParticle(spc[i], xmlc, mixed);
            if (mixed && i < spc.length-1)
                xmlc.insertChars(pick(WORDS));
        }
    }

    private void processWildCard(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    {
        xmlc.insertComment("You may enter ANY elements at this point");
        xmlc.insertElement("AnyElement");
    }

    /**
     * This method will get the base type for the schema type
     */
    
    private static QName getClosestName(SchemaType sType)
    {
        while (sType.getName() == null)
            sType = sType.getBaseType();

        return sType.getName();
    }

    private String printParticleType(int particleType)
    {
        StringBuilder returnParticleType = new StringBuilder();
        returnParticleType.append("Schema Particle Type: ");

        switch (particleType)
        {
            case SchemaParticle.ALL :
                returnParticleType.append("ALL\n");
                break;
            case SchemaParticle.CHOICE :
                returnParticleType.append("CHOICE\n");
                break;
            case SchemaParticle.ELEMENT :
                returnParticleType.append("ELEMENT\n");
                break;
            case SchemaParticle.SEQUENCE :
                returnParticleType.append("SEQUENCE\n");
                break;
            case SchemaParticle.WILDCARD :
                returnParticleType.append("WILDCARD\n");
                break;
            default :
                returnParticleType.append("Schema Particle Type Unknown");
                break;
        }

        return returnParticleType.toString();
    }

    private ArrayList _typeStack = new ArrayList();
}
