/*   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.schema;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.XmlOptions.BeanMethod;
import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.impl.repackage.Repackager;

import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.*;

/**
 * Prints the java code for a single schema type
 */
public final class SchemaTypeCodePrinter implements SchemaCodePrinter {

    static final String INDEX_CLASSNAME = "TypeSystemHolder";
    private static final String MAX_SPACES = "                                        ";
    private static final int INDENT_INCREMENT = 4;

    private Writer _writer;
    private int _indent;
    private XmlOptions opt;

    public SchemaTypeCodePrinter() {
        _indent = 0;
    }

    void indent() {
        _indent += INDENT_INCREMENT;
    }

    void outdent() {
        _indent -= INDENT_INCREMENT;
    }

    void emit(String s, BeanMethod method) throws IOException {
        Set<BeanMethod> partMet = opt == null ? null : opt.getCompilePartialMethod();
        if ((partMet == null || partMet.contains(method))) {
            emit(s);
        }
    }

    void emit(String s) throws IOException {
        if (!s.trim().isEmpty()) {
            int indent = _indent;

            if (indent > MAX_SPACES.length() / 2) {
                indent = MAX_SPACES.length() / 4 + indent / 2;
            }

            if (indent > MAX_SPACES.length()) {
                indent = MAX_SPACES.length();
            }

            _writer.write(MAX_SPACES.substring(0, indent));
        }
        try {
            _writer.write(s);
        } catch (CharacterCodingException cce) {
            _writer.write(makeSafe(s));
        }
        _writer.write(System.lineSeparator());
    }

    private static String makeSafe(String s) {
        Charset charset = Charset.forName(System.getProperty("file.encoding"));
        CharsetEncoder cEncoder = charset.newEncoder();
        StringBuilder result = new StringBuilder();
        int i;
        for (i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!cEncoder.canEncode(c)) {
                break;
            }
        }
        for (; i < s.length(); i++) {
            char c = s.charAt(i);
            if (cEncoder.canEncode(c)) {
                result.append(c);
            } else {
                String hexValue = Integer.toHexString(c);
                switch (hexValue.length()) {
                    case 1:
                        result.append("\\u000").append(hexValue);
                        break;
                    case 2:
                        result.append("\\u00").append(hexValue);
                        break;
                    case 3:
                        result.append("\\u0").append(hexValue);
                        break;
                    case 4:
                        result.append("\\u").append(hexValue);
                        break;
                    default:
                        throw new IllegalStateException();
                }
            }
        }
        return result.toString();
    }

    @Override
    public void printType(Writer writer, SchemaType sType, XmlOptions opt) throws IOException {
        this.opt = opt;
        _writer = writer;
        printTopComment(sType);
        printPackage(sType, true);
        emit("");
        emit("import "+ElementFactory.class.getName()+";");
        emit("import " + AbstractDocumentFactory.class.getName() + ";");
        emit("import " + DocumentFactory.class.getName() + ";");
        emit("import " + SimpleTypeFactory.class.getName() + ";");
        emit("");
        printInnerType(sType, sType.getTypeSystem());
        _writer.flush();
    }

    @Override
    public void printTypeImpl(Writer writer, SchemaType sType, XmlOptions opt) throws IOException {
        this.opt = opt;
        _writer = writer;
        printTopComment(sType);
        printPackage(sType, false);
        emit("");
        emit("import javax.xml.namespace.QName;");
        emit("import org.apache.xmlbeans.QNameSet;");
        emit("");
        printInnerTypeImpl(sType, sType.getTypeSystem(), false);
    }

    /**
     * Since not all schema types have java types, this skips
     * over any that don't and gives you the nearest java base type.
     */
    String findJavaType(SchemaType sType) {
        while (sType.getFullJavaName() == null) {
            sType = sType.getBaseType();
        }

        return sType.getFullJavaName();
    }

    static String prettyQName(QName qname) {
        if (qname == null) {
            return "";
        }
        String result = qname.getLocalPart();
        if (qname.getNamespaceURI() != null) {
            result += "(@" + qname.getNamespaceURI() + ")";
        }
        return result;
    }

    void printInnerTypeJavaDoc(SchemaType sType) throws IOException {
        QName name = sType.getName();
        if (name == null) {
            if (sType.isDocumentType()) {
                name = sType.getDocumentElementName();
            } else if (sType.isAttributeType()) {
                name = sType.getAttributeTypeAttributeName();
            } else if (sType.getContainerField() != null) {
                name = sType.getContainerField().getName();
            }
        }

        emit("/**");
        if (sType.isDocumentType()) {
            emit(" * A document containing one " + prettyQName(name) + " element.");
        } else if (sType.isAttributeType()) {
            emit(" * A document containing one " + prettyQName(name) + " attribute.");
        } else if (name != null) {
            emit(" * An XML " + prettyQName(name) + ".");
        } else {
            emit(" * An anonymous inner XML type.");
        }
        emit(" *");
        switch (sType.getSimpleVariety()) {
            case SchemaType.NOT_SIMPLE:
                emit(" * This is a complex type.");
                break;
            case SchemaType.ATOMIC:
                emit(" * This is an atomic type that is a restriction of " + getFullJavaName(sType) + ".");
                break;
            case SchemaType.LIST:
                emit(" * This is a list type whose items are " + sType.getListItemType().getFullJavaName() + ".");
                break;
            case SchemaType.UNION:
                emit(" * This is a union type. Instances are of one of the following types:");
                SchemaType[] members = sType.getUnionConstituentTypes();
                for (SchemaType member : members) {
                    emit(" *     " + member.getFullJavaName());
                }
                break;
        }
        emit(" */");
    }

    private String getFullJavaName(SchemaType sType) {

        SchemaTypeImpl sTypeI = (SchemaTypeImpl) sType;
        String ret = sTypeI.getFullJavaName();

        while (sTypeI != null && sTypeI.isRedefinition()) {
            ret = sTypeI.getFullJavaName();
            sTypeI = (SchemaTypeImpl) sTypeI.getBaseType();
        }
        return ret;
    }

    private String getUserTypeStaticHandlerMethod(boolean encode, SchemaTypeImpl stype) {
        String unqualifiedName = stype.getName().getLocalPart();
        if (unqualifiedName.length() < 2) {
            unqualifiedName = unqualifiedName.toUpperCase(Locale.ROOT);
        } else {
            unqualifiedName = unqualifiedName.substring(0, 1).toUpperCase(Locale.ROOT) + unqualifiedName.substring(1);
        }

        if (encode) {
            return stype.getUserTypeHandlerName() + ".encode" + unqualifiedName;
        } else {
            return stype.getUserTypeHandlerName() + ".decode" + unqualifiedName;
        }
    }


    public static String indexClassForSystem(SchemaTypeSystem system) {
        String name = system.getName();
        return name + "." + INDEX_CLASSNAME;
    }

    void printStaticTypeDeclaration(SchemaType sType, SchemaTypeSystem system) throws IOException {
        // Only need full factories for top-level types
        Class<?> factoryClass;
        if (sType.isAnonymousType() && !sType.isDocumentType() && !sType.isAttributeType()) {
            factoryClass = ElementFactory.class;
        } else if (sType.isSimpleType()) {
            factoryClass = SimpleTypeFactory.class;
        } else if (sType.isAbstract()) {
            factoryClass = AbstractDocumentFactory.class;
        } else {
            factoryClass = DocumentFactory.class;
        }

        String factoryName = factoryClass.getSimpleName();

        String fullName = sType.getFullJavaName().replace('$', '.');
        String sysName = sType.getTypeSystem().getName();


        emit(factoryName + "<" + fullName + "> Factory = new " + factoryName +
             "<>(" + sysName + ".TypeSystemHolder.typeSystem, \"" + ((SchemaTypeSystemImpl) system).handleForType(sType) + "\");"
         );
        emit("org.apache.xmlbeans.SchemaType type = Factory.getType();");
        emit("");
    }

    void printInnerType(SchemaType sType, SchemaTypeSystem system) throws IOException {
        emit("");

        printInnerTypeJavaDoc(sType);

        startInterface(sType);

        printStaticTypeDeclaration(sType, system);

        if (sType.isSimpleType()) {
            if (sType.hasStringEnumValues()) {
                printStringEnumeration(sType);
            }
        } else {
            if (sType.getContentType() == SchemaType.SIMPLE_CONTENT && sType.hasStringEnumValues()) {
                printStringEnumeration(sType);
            }

            SchemaProperty[] props = getDerivedProperties(sType);

            for (SchemaProperty prop : props) {
                printPropertyGetters(prop);

                if (!prop.isReadOnly()) {
                    printPropertySetters(prop);
                }
            }

        }

        printNestedInnerTypes(sType, system);

        endBlock();
    }

    void printNestedInnerTypes(SchemaType sType, SchemaTypeSystem system) throws IOException {
        boolean redefinition = sType.getName() != null &&
                               sType.getName().equals(sType.getBaseType().getName());
        while (sType != null) {
            SchemaType[] anonTypes = sType.getAnonymousTypes();
            for (SchemaType anonType : anonTypes) {
                if (anonType.isSkippedAnonymousType()) {
                    printNestedInnerTypes(anonType, system);
                } else {
                    printInnerType(anonType, system);
                }
            }
            // For redefinition other than by extension for complex types, go ahead and print
            // the anonymous types in the base
            if (!redefinition ||
                (sType.getDerivationType() != SchemaType.DT_EXTENSION && !sType.isSimpleType())) {
                break;
            }
            sType = sType.getBaseType();
        }
    }

    void printTopComment(SchemaType sType) throws IOException {
        emit("/*");
        if (sType.getName() != null) {
            emit(" * XML Type:  " + sType.getName().getLocalPart());
            emit(" * Namespace: " + sType.getName().getNamespaceURI());
        } else {
            QName thename = null;

            if (sType.isDocumentType()) {
                thename = sType.getDocumentElementName();
                emit(" * An XML document type.");
            } else if (sType.isAttributeType()) {
                thename = sType.getAttributeTypeAttributeName();
                emit(" * An XML attribute type.");
            } else {
                assert false;
            }

            assert (thename != null);

            emit(" * Localname: " + thename.getLocalPart());
            emit(" * Namespace: " + thename.getNamespaceURI());
        }
        emit(" * Java type: " + sType.getFullJavaName());
        emit(" *");
        emit(" * Automatically generated - do not modify.");
        emit(" */");
    }

    void printPackage(SchemaType sType, boolean intf) throws IOException {
        String fqjn;
        if (intf) {
            fqjn = sType.getFullJavaName();
        } else {
            fqjn = sType.getFullJavaImplName();
        }

        int lastdot = fqjn.lastIndexOf('.');
        if (lastdot < 0) {
            return;
        }
        String pkg = fqjn.substring(0, lastdot);
        emit("package " + pkg + ";");
    }

    void startInterface(SchemaType sType) throws IOException {
        String shortName = sType.getShortJavaName();

        String baseInterface = findJavaType(sType.getBaseType());

        emit("public interface " + shortName + " extends " + baseInterface + getExtensionInterfaces(sType));
        emit("{");
        indent();
        emitSpecializedAccessors(sType);
    }

    private static String getExtensionInterfaces(SchemaType sType) {
        SchemaTypeImpl sImpl = getImpl(sType);
        if (sImpl == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        InterfaceExtension[] exts = sImpl.getInterfaceExtensions();
        if (exts != null) {
            for (InterfaceExtension ext : exts) {
                sb.append(", ").append(ext.getInterface());
            }
        }

        return sb.toString();
    }

    private static SchemaTypeImpl getImpl(SchemaType sType) {
        if (sType instanceof SchemaTypeImpl) {
            return (SchemaTypeImpl) sType;
        } else {
            return null;
        }
    }

    private void emitSpecializedAccessors(SchemaType sType) throws IOException {
        if (sType.getSimpleVariety() == SchemaType.ATOMIC &&
            sType.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_DECIMAL) {
            int bits = sType.getDecimalSize();
            int parentBits = sType.getBaseType().getDecimalSize();
            if (bits != parentBits || sType.getBaseType().getFullJavaName() == null) {
                switch (bits) {
                    case SchemaType.SIZE_BIG_INTEGER:
                        emit("java.math.BigInteger getBigIntegerValue();", BeanMethod.GET);
                        emit("void setBigIntegerValue(java.math.BigInteger bi);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_LONG:
                        emit("long getLongValue();", BeanMethod.GET);
                        emit("void setLongValue(long l);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_INT:
                        emit("int getIntValue();", BeanMethod.GET);
                        emit("void setIntValue(int i);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_SHORT:
                        emit("short getShortValue();", BeanMethod.GET);
                        emit("void setShortValue(short s);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_BYTE:
                        emit("byte getByteValue();", BeanMethod.GET);
                        emit("void setByteValue(byte b);", BeanMethod.SET);
                        break;
                }
            }
        }

        if (sType.getSimpleVariety() == SchemaType.UNION) {
            emit("java.lang.Object getObjectValue();", BeanMethod.GET);
            emit("void setObjectValue(java.lang.Object val);", BeanMethod.SET);
            emit("org.apache.xmlbeans.SchemaType instanceType();", BeanMethod.INSTANCE_TYPE);
            SchemaType ctype = sType.getUnionCommonBaseType();
            if (ctype != null && ctype.getSimpleVariety() != SchemaType.UNION) {
                emitSpecializedAccessors(ctype);
            }
        }

        if (sType.getSimpleVariety() == SchemaType.LIST) {
            emit("java.util.List getListValue();", BeanMethod.GET_LIST);
            emit("java.util.List xgetListValue();", BeanMethod.XGET_LIST);
            emit("void setListValue(java.util.List<?> list);", BeanMethod.SET_LIST);
        }
    }

    void startBlock() {
        // emit("{");
        indent();
    }

    void endBlock() throws IOException {
        outdent();
        emit("}");
    }

    void printJavaDoc(String sentence, BeanMethod method) throws IOException {
        Set<BeanMethod> partMet = opt == null ? null : opt.getCompilePartialMethod();
        if ((partMet == null || partMet.contains(method))) {
            printJavaDoc(sentence);
        }
    }

    void printJavaDoc(String sentence) throws IOException {
        emit("");
        emit("/**");
        emit(" * " + sentence);
        emit(" */");
    }

    public static String javaStringEscape(String str) {
        // forbidden: \n, \r, \", \\.
        test:
        {
            for (int i = 0; i < str.length(); i++) {
                switch (str.charAt(i)) {
                    case '\n':
                    case '\r':
                    case '\"':
                    case '\\':
                        break test;
                }
            }
            return str;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            switch (ch) {
                default:
                    sb.append(ch);
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                case '\"':
                    sb.append("\\\"");
                    break;
                case '\\':
                    sb.append("\\\\");
                    break;
            }
        }
        return sb.toString();
    }

    void printStringEnumeration(SchemaType sType) throws IOException {
        SchemaType baseEnumType = sType.getBaseEnumType();
        String baseEnumClass = baseEnumType.getFullJavaName();
        boolean hasBase = hasBase(sType);

        if (!hasBase) {
            emit("");
            emit("org.apache.xmlbeans.StringEnumAbstractBase getEnumValue();", BeanMethod.GET);
            emit("void setEnumValue(org.apache.xmlbeans.StringEnumAbstractBase e);", BeanMethod.SET);
        }

        emit("");
        SchemaStringEnumEntry[] entries = sType.getStringEnumEntries();
        HashSet<String> seenValues = new HashSet<>();
        HashSet<String> repeatValues = new HashSet<>();
        for (SchemaStringEnumEntry entry : entries) {
            String enumValue = entry.getString();
            if (seenValues.contains(enumValue)) {
                repeatValues.add(enumValue);
                continue;
            } else {
                seenValues.add(enumValue);
            }
            String constName = entry.getEnumName();
            if (hasBase) {
                emit("static final " + baseEnumClass + ".Enum " + constName + " = " + baseEnumClass + "." + constName + ";");
            } else {
                emit("static final Enum " + constName + " = Enum.forString(\"" + javaStringEscape(enumValue) + "\");");
            }
        }
        emit("");
        for (SchemaStringEnumEntry entry : entries) {
            if (repeatValues.contains(entry.getString())) {
                continue;
            }
            String constName = "INT_" + entry.getEnumName();
            if (hasBase) {
                emit("static final int " + constName + " = " + baseEnumClass + "." + constName + ";");
            } else {
                emit("static final int " + constName + " = Enum." + constName + ";");
            }
        }
        if (!hasBase) {
            emit("");
            emit("/**");
            emit(" * Enumeration value class for " + baseEnumClass + ".");
            emit(" * These enum values can be used as follows:");
            emit(" * <pre>");
            emit(" * enum.toString(); // returns the string value of the enum");
            emit(" * enum.intValue(); // returns an int value, useful for switches");
            if (entries.length > 0) {
                emit(" * // e.g., case Enum.INT_" + entries[0].getEnumName());
            }
            emit(" * Enum.forString(s); // returns the enum value for a string");
            emit(" * Enum.forInt(i); // returns the enum value for an int");
            emit(" * </pre>");
            emit(" * Enumeration objects are immutable singleton objects that");
            emit(" * can be compared using == object equality. They have no");
            emit(" * public constructor. See the constants defined within this");
            emit(" * class for all the valid values.");
            emit(" */");
            emit("static final class Enum extends org.apache.xmlbeans.StringEnumAbstractBase");
            emit("{");
            indent();
            emit("/**");
            emit(" * Returns the enum value for a string, or null if none.");
            emit(" */");
            emit("public static Enum forString(java.lang.String s)");
            emit("    { return (Enum)table.forString(s); }");
            emit("/**");
            emit(" * Returns the enum value corresponding to an int, or null if none.");
            emit(" */");
            emit("public static Enum forInt(int i)");
            emit("    { return (Enum)table.forInt(i); }");
            emit("");
            emit("private Enum(java.lang.String s, int i)");
            emit("    { super(s, i); }");
            emit("");
            for (SchemaStringEnumEntry entry : entries) {
                String constName = "INT_" + entry.getEnumName();
                int intValue = entry.getIntValue();
                emit("static final int " + constName + " = " + intValue + ";");
            }
            emit("");
            emit("public static final org.apache.xmlbeans.StringEnumAbstractBase.Table table =");
            emit("    new org.apache.xmlbeans.StringEnumAbstractBase.Table");
            emit("(");
            indent();
            emit("new Enum[]");
            emit("{");
            indent();
            for (SchemaStringEnumEntry entry : entries) {
                String enumValue = entry.getString();
                String constName = "INT_" + entry.getEnumName();
                emit("new Enum(\"" + javaStringEscape(enumValue) + "\", " + constName + "),");
            }
            outdent();
            emit("}");
            outdent();
            emit(");");
            emit("private static final long serialVersionUID = 1L;");
            emit("private java.lang.Object readResolve() { return forInt(intValue()); } ");
            outdent();
            emit("}");
        }
    }

    private boolean hasBase(SchemaType sType) {
        boolean hasBase;
        SchemaType baseEnumType = sType.getBaseEnumType();
        if (baseEnumType.isAnonymousType() && baseEnumType.isSkippedAnonymousType()) {
            if (sType.getContentBasedOnType() != null) {
                hasBase = sType.getContentBasedOnType().getBaseType() != baseEnumType;
            } else {
                hasBase = sType.getBaseType() != baseEnumType;
            }
        } else {
            hasBase = baseEnumType != sType;
        }
        return hasBase;
    }

    String xmlTypeForProperty(SchemaProperty sProp) {
        SchemaType sType = sProp.javaBasedOnType();
        return findJavaType(sType).replace('$', '.');
    }

    static boolean xmlTypeForPropertyIsUnion(SchemaProperty sProp) {
        SchemaType sType = sProp.javaBasedOnType();
        return (sType.isSimpleType() && sType.getSimpleVariety() == SchemaType.UNION);
    }

    static boolean isJavaPrimitive(int javaType) {
        return (javaType >= SchemaProperty.JAVA_FIRST_PRIMITIVE && (javaType <= SchemaProperty.JAVA_LAST_PRIMITIVE));
    }

    /**
     * Returns the wrapped type for a java primitive.
     */
    static String javaWrappedType(int javaType) {
        switch (javaType) {
            case SchemaProperty.JAVA_BOOLEAN:
                return "java.lang.Boolean";
            case SchemaProperty.JAVA_FLOAT:
                return "java.lang.Float";
            case SchemaProperty.JAVA_DOUBLE:
                return "java.lang.Double";
            case SchemaProperty.JAVA_BYTE:
                return "java.lang.Byte";
            case SchemaProperty.JAVA_SHORT:
                return "java.lang.Short";
            case SchemaProperty.JAVA_INT:
                return "java.lang.Integer";
            case SchemaProperty.JAVA_LONG:
                return "java.lang.Long";

            // anything else is not a java primitive
            default:
                assert false;
                throw new IllegalStateException();
        }
    }

    String javaTypeForProperty(SchemaProperty sProp) {
        // The type to use is the XML object....
        if (sProp.getJavaTypeCode() == SchemaProperty.XML_OBJECT) {
            SchemaType sType = sProp.javaBasedOnType();
            return findJavaType(sType).replace('$', '.');
        }

        if (sProp.getJavaTypeCode() == SchemaProperty.JAVA_USER) {
            return ((SchemaTypeImpl) sProp.getType()).getUserTypeName();
        }

        switch (sProp.getJavaTypeCode()) {
            case SchemaProperty.JAVA_BOOLEAN:
                return "boolean";
            case SchemaProperty.JAVA_FLOAT:
                return "float";
            case SchemaProperty.JAVA_DOUBLE:
                return "double";
            case SchemaProperty.JAVA_BYTE:
                return "byte";
            case SchemaProperty.JAVA_SHORT:
                return "short";
            case SchemaProperty.JAVA_INT:
                return "int";
            case SchemaProperty.JAVA_LONG:
                return "long";

            case SchemaProperty.JAVA_BIG_DECIMAL:
                return "java.math.BigDecimal";
            case SchemaProperty.JAVA_BIG_INTEGER:
                return "java.math.BigInteger";
            case SchemaProperty.JAVA_STRING:
                return "java.lang.String";
            case SchemaProperty.JAVA_BYTE_ARRAY:
                return "byte[]";
            case SchemaProperty.JAVA_GDATE:
                return "org.apache.xmlbeans.GDate";
            case SchemaProperty.JAVA_GDURATION:
                return "org.apache.xmlbeans.GDuration";
            case SchemaProperty.JAVA_DATE:
                return "java.util.Date";
            case SchemaProperty.JAVA_QNAME:
                return "javax.xml.namespace.QName";
            case SchemaProperty.JAVA_LIST:
                return "java.util.List";
            case SchemaProperty.JAVA_CALENDAR:
                return "java.util.Calendar";

            case SchemaProperty.JAVA_ENUM:
                SchemaType sType = sProp.javaBasedOnType();
                if (sType.getSimpleVariety() == SchemaType.UNION) {
                    sType = sType.getUnionCommonBaseType();
                }
                assert sType.getBaseEnumType() != null;
                if (hasBase(sType)) {
                    return findJavaType(sType.getBaseEnumType()).replace('$', '.') + ".Enum";
                } else {
                    return findJavaType(sType).replace('$', '.') + ".Enum";
                }

            case SchemaProperty.JAVA_OBJECT:
                return "java.lang.Object";

            default:
                assert (false);
                throw new IllegalStateException();
        }
    }

    void printPropertyGetters(SchemaProperty prop) throws IOException {
        String propertyName = prop.getJavaPropertyName();
        int javaType = prop.getJavaTypeCode();
        String type = javaTypeForProperty(prop);
        String xtype = xmlTypeForProperty(prop);
        boolean nillable = prop.hasNillable() != SchemaProperty.NEVER;
        boolean several = prop.extendsJavaArray();

        String propdesc = "\"" + prop.getName().getLocalPart() + "\"" + (prop.isAttribute() ? " attribute" : " element");
        boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);

        if (prop.extendsJavaSingleton()) {
            printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc, BeanMethod.GET);
            emit(type + " get" + propertyName + "();", BeanMethod.GET);

            if (!xmltype) {
                printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc, BeanMethod.XGET);
                emit(xtype + " xget" + propertyName + "();", BeanMethod.XGET);
            }

            if (nillable) {
                printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc, BeanMethod.IS_NIL);
                emit("boolean isNil" + propertyName + "();", BeanMethod.IS_NIL);
            }
        }

        if (prop.extendsJavaOption()) {
            printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc, BeanMethod.IS_SET);
            emit("boolean isSet" + propertyName + "();", BeanMethod.IS_SET);
        }

        if (several) {
            String arrayName = propertyName + "Array";

            String wrappedType = type;
            if (isJavaPrimitive(javaType)) {
                wrappedType = javaWrappedType(javaType);
            }

            printJavaDoc("Gets a List of " + propdesc + "s", BeanMethod.GET_LIST);
            emit("java.util.List<" + wrappedType + "> get" + propertyName + "List();", BeanMethod.GET_LIST);

            printJavaDoc("Gets array of all " + propdesc + "s", BeanMethod.GET_ARRAY);
            emit(type + "[] get" + arrayName + "();", BeanMethod.GET_ARRAY);

            printJavaDoc("Gets ith " + propdesc, BeanMethod.GET_IDX);
            emit(type + " get" + arrayName + "(int i);", BeanMethod.GET_IDX);

            if (!xmltype) {
                printJavaDoc("Gets (as xml) a List of " + propdesc + "s", BeanMethod.XGET_LIST);
                emit("java.util.List<" + xtype + "> xget" + propertyName + "List();", BeanMethod.XGET_LIST);

                printJavaDoc("Gets (as xml) array of all " + propdesc + "s", BeanMethod.XGET_ARRAY);
                emit(xtype + "[] xget" + arrayName + "();", BeanMethod.XGET_ARRAY);

                printJavaDoc("Gets (as xml) ith " + propdesc, BeanMethod.XGET_IDX);
                emit(xtype + " xget" + arrayName + "(int i);", BeanMethod.XGET_IDX);
            }

            if (nillable) {
                printJavaDoc("Tests for nil ith " + propdesc, BeanMethod.IS_NIL_IDX);
                emit("boolean isNil" + arrayName + "(int i);", BeanMethod.IS_NIL_IDX);
            }

            printJavaDoc("Returns number of " + propdesc, BeanMethod.SIZE_OF_ARRAY);
            emit("int sizeOf" + arrayName + "();", BeanMethod.SIZE_OF_ARRAY);
        }
    }

    void printPropertySetters(SchemaProperty prop) throws IOException {
        QName qName = prop.getName();
        boolean isAttr = prop.isAttribute();
        String propertyName = prop.getJavaPropertyName();
        int javaType = prop.getJavaTypeCode();
        String type = javaTypeForProperty(prop);
        String xtype = xmlTypeForProperty(prop);
        boolean nillable = prop.hasNillable() != SchemaProperty.NEVER;
        boolean optional = prop.extendsJavaOption();
        boolean several = prop.extendsJavaArray();
        boolean singleton = prop.extendsJavaSingleton();

        String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName));
        if (safeVarName.equals("i")) {
            safeVarName = "iValue";
        }
        boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);

        String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");

        if (singleton) {
            printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc, BeanMethod.SET);
            emit("void set" + propertyName + "(" + type + " " + safeVarName + ");", BeanMethod.SET);

            if (!xmltype) {
                printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc, BeanMethod.XSET);
                emit("void xset" + propertyName + "(" + xtype + " " + safeVarName + ");", BeanMethod.XSET);
            }

            if (xmltype && !several) {
                printJavaDoc("Appends and returns a new empty " + propdesc, BeanMethod.ADD_NEW);
                emit(xtype + " addNew" + propertyName + "();", BeanMethod.ADD_NEW);
            }

            if (nillable) {
                printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc, BeanMethod.SET_NIL);
                emit("void setNil" + propertyName + "();", BeanMethod.SET_NIL);
            }
        }

        if (optional) {
            printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc, BeanMethod.UNSET);
            emit("void unset" + propertyName + "();", BeanMethod.UNSET);
        }

        if (several) {
            String arrayName = propertyName + "Array";

            printJavaDoc("Sets array of all " + propdesc, BeanMethod.SET_ARRAY);
            emit("void set" + arrayName + "(" + type + "[] " + safeVarName + "Array);", BeanMethod.SET_ARRAY);

            printJavaDoc("Sets ith " + propdesc, BeanMethod.SET_IDX);
            emit("void set" + arrayName + "(int i, " + type + " " + safeVarName + ");", BeanMethod.SET_IDX);

            if (!xmltype) {
                printJavaDoc("Sets (as xml) array of all " + propdesc, BeanMethod.XSET_ARRAY);
                emit("void xset" + arrayName + "(" + xtype + "[] " + safeVarName + "Array);", BeanMethod.XSET_ARRAY);

                printJavaDoc("Sets (as xml) ith " + propdesc, BeanMethod.XSET_IDX);
                emit("void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ");", BeanMethod.XSET_IDX);
            }

            if (nillable) {
                printJavaDoc("Nils the ith " + propdesc, BeanMethod.SET_NIL_IDX);
                emit("void setNil" + arrayName + "(int i);", BeanMethod.SET_NIL_IDX);
            }

            if (!xmltype) {
                printJavaDoc("Inserts the value as the ith " + propdesc, BeanMethod.INSERT_IDX);
                emit("void insert" + propertyName + "(int i, " + type + " " + safeVarName + ");", BeanMethod.INSERT_IDX);

                printJavaDoc("Appends the value as the last " + propdesc, BeanMethod.ADD);
                emit("void add" + propertyName + "(" + type + " " + safeVarName + ");", BeanMethod.ADD);
            }

            printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc, BeanMethod.INSERT_NEW_IDX);
            emit(xtype + " insertNew" + propertyName + "(int i);", BeanMethod.INSERT_NEW_IDX);

            printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc, BeanMethod.ADD_NEW);
            emit(xtype + " addNew" + propertyName + "();", BeanMethod.ADD_NEW);

            printJavaDoc("Removes the ith " + propdesc, BeanMethod.REMOVE_IDX);
            emit("void remove" + propertyName + "(int i);", BeanMethod.REMOVE_IDX);
        }
    }

    String getAtomicRestrictionType(SchemaType sType) {
        SchemaType pType = sType.getPrimitiveType();
        switch (pType.getBuiltinTypeCode()) {
            case SchemaType.BTC_ANY_SIMPLE:
                return "org.apache.xmlbeans.impl.values.XmlAnySimpleTypeImpl";
            case SchemaType.BTC_BOOLEAN:
                return "org.apache.xmlbeans.impl.values.JavaBooleanHolderEx";
            case SchemaType.BTC_BASE_64_BINARY:
                return "org.apache.xmlbeans.impl.values.JavaBase64HolderEx";
            case SchemaType.BTC_HEX_BINARY:
                return "org.apache.xmlbeans.impl.values.JavaHexBinaryHolderEx";
            case SchemaType.BTC_ANY_URI:
                return "org.apache.xmlbeans.impl.values.JavaUriHolderEx";
            case SchemaType.BTC_QNAME:
                return "org.apache.xmlbeans.impl.values.JavaQNameHolderEx";
            case SchemaType.BTC_NOTATION:
                return "org.apache.xmlbeans.impl.values.JavaNotationHolderEx";
            case SchemaType.BTC_FLOAT:
                return "org.apache.xmlbeans.impl.values.JavaFloatHolderEx";
            case SchemaType.BTC_DOUBLE:
                return "org.apache.xmlbeans.impl.values.JavaDoubleHolderEx";
            case SchemaType.BTC_DECIMAL:
                switch (sType.getDecimalSize()) {
                    default:
                        assert (false);
                    case SchemaType.SIZE_BIG_DECIMAL:
                        return "org.apache.xmlbeans.impl.values.JavaDecimalHolderEx";
                    case SchemaType.SIZE_BIG_INTEGER:
                        return "org.apache.xmlbeans.impl.values.JavaIntegerHolderEx";
                    case SchemaType.SIZE_LONG:
                        return "org.apache.xmlbeans.impl.values.JavaLongHolderEx";
                    case SchemaType.SIZE_INT:
                    case SchemaType.SIZE_SHORT:
                    case SchemaType.SIZE_BYTE:
                        return "org.apache.xmlbeans.impl.values.JavaIntHolderEx";
                }
            case SchemaType.BTC_STRING:
                if (sType.hasStringEnumValues()) {
                    return "org.apache.xmlbeans.impl.values.JavaStringEnumerationHolderEx";
                } else {
                    return "org.apache.xmlbeans.impl.values.JavaStringHolderEx";
                }

            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 "org.apache.xmlbeans.impl.values.JavaGDateHolderEx";

            case SchemaType.BTC_DURATION:
                return "org.apache.xmlbeans.impl.values.JavaGDurationHolderEx";
            default:
                assert (false) : "unrecognized primitive type";
                return null;
        }
    }

    static SchemaType findBaseType(SchemaType sType) {
        while (sType.getFullJavaName() == null) {
            sType = sType.getBaseType();
        }
        return sType;
    }

    String getBaseClass(SchemaType sType) {
        SchemaType baseType = findBaseType(sType.getBaseType());

        switch (sType.getSimpleVariety()) {
            case SchemaType.NOT_SIMPLE:
                // non-simple-content: inherit from base type impl
                if (!XmlObject.type.equals(baseType)) {
                    return baseType.getFullJavaImplName();
                }
                return "org.apache.xmlbeans.impl.values.XmlComplexContentImpl";

            case SchemaType.ATOMIC:
                // We should only get called for restrictions
                assert (!sType.isBuiltinType());
                return getAtomicRestrictionType(sType);

            case SchemaType.LIST:
                return "org.apache.xmlbeans.impl.values.XmlListImpl";

            case SchemaType.UNION:
                return "org.apache.xmlbeans.impl.values.XmlUnionImpl";

            default:
                throw new IllegalStateException();
        }
    }

    void printConstructor(SchemaType sType, String shortName) throws IOException {
        emit("");
        emit("public " + shortName + "(org.apache.xmlbeans.SchemaType sType) {");
        startBlock();
        emit("super(sType" + (sType.getSimpleVariety() == SchemaType.NOT_SIMPLE ?
            "" :
            ", " + !sType.isSimpleType()) +
             ");");
        endBlock();

        if (sType.getSimpleVariety() != SchemaType.NOT_SIMPLE) {
            emit("");
            emit("protected " + shortName + "(org.apache.xmlbeans.SchemaType sType, boolean b) {");
            startBlock();
            emit("super(sType, b);");
            endBlock();
        }
    }

    void startClass(SchemaType sType, boolean isInner) throws IOException {
        String shortName = sType.getShortJavaImplName();
        String baseClass = getBaseClass(sType);
        StringBuilder interfaces = new StringBuilder();
        interfaces.append(sType.getFullJavaName().replace('$', '.'));

        if (sType.getSimpleVariety() == SchemaType.UNION) {
            SchemaType[] memberTypes = sType.getUnionMemberTypes();
            for (SchemaType memberType : memberTypes) {
                interfaces.append(", ").append(memberType.getFullJavaName().replace('$', '.'));
            }
        }

        emit("public " + (isInner ? "static " : "") + "class " + shortName +
             " extends " + baseClass + " implements " + interfaces.toString() + " {");

        startBlock();

        emit("private static final long serialVersionUID = 1L;");
    }

    void makeAttributeDefaultValue(String jtargetType, SchemaProperty prop, String identifier) throws IOException {
        String fullName = jtargetType;
        if (fullName == null) {
            fullName = prop.javaBasedOnType().getFullJavaName().replace('$', '.');
        }

        emit("target = (" + fullName + ")get_default_attribute_value(" + identifier + ");");
    }

    void makeMissingValue(int javaType) throws IOException {
        switch (javaType) {
            case SchemaProperty.JAVA_BOOLEAN:
                emit("return false;");
                break;

            case SchemaProperty.JAVA_FLOAT:
                emit("return 0.0f;");
                break;

            case SchemaProperty.JAVA_DOUBLE:
                emit("return 0.0;");
                break;

            case SchemaProperty.JAVA_BYTE:
            case SchemaProperty.JAVA_SHORT:
            case SchemaProperty.JAVA_INT:
                emit("return 0;");
                break;

            case SchemaProperty.JAVA_LONG:
                emit("return 0L;");
                break;

            default:
            case SchemaProperty.XML_OBJECT:
            case SchemaProperty.JAVA_BIG_DECIMAL:
            case SchemaProperty.JAVA_BIG_INTEGER:
            case SchemaProperty.JAVA_STRING:
            case SchemaProperty.JAVA_BYTE_ARRAY:
            case SchemaProperty.JAVA_GDATE:
            case SchemaProperty.JAVA_GDURATION:
            case SchemaProperty.JAVA_DATE:
            case SchemaProperty.JAVA_QNAME:
            case SchemaProperty.JAVA_LIST:
            case SchemaProperty.JAVA_CALENDAR:
            case SchemaProperty.JAVA_ENUM:
            case SchemaProperty.JAVA_OBJECT:
                emit("return null;");
                break;
        }
    }

    void printJGetArrayValue(int javaType, String type, SchemaTypeImpl stype, String setIdentifier) throws IOException {
        String em;
        switch (javaType) {
            case SchemaProperty.XML_OBJECT:
                em ="XmlObjectArray(#ID#, new " + type + "[0]);";
                break;

            case SchemaProperty.JAVA_ENUM:
                em = "EnumArray(#ID#, " + type + "[]::new);";
                break;

            case SchemaProperty.JAVA_BOOLEAN:
                em = "BooleanArray(#ID#);";
                break;

            case SchemaProperty.JAVA_FLOAT:
                em = "FloatArray(#ID#);";
                break;

            case SchemaProperty.JAVA_DOUBLE:
                em = "DoubleArray(#ID#);";
                break;

            case SchemaProperty.JAVA_BYTE:
                em = "ByteArray(#ID#);";
                break;

            case SchemaProperty.JAVA_SHORT:
                em = "ShortArray(#ID#);";
                break;

            case SchemaProperty.JAVA_INT:
                em = "IntArray(#ID#);";
                break;

            case SchemaProperty.JAVA_LONG:
                em = "LongArray(#ID#);";
                break;

            case SchemaProperty.JAVA_BIG_DECIMAL:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getBigDecimalValue, java.math.BigDecimal[]::new);";
                break;

            case SchemaProperty.JAVA_BIG_INTEGER:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getBigIntegerValue, java.math.BigInteger[]::new);";
                break;

            case SchemaProperty.JAVA_STRING:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getStringValue, String[]::new);";
                break;

            case SchemaProperty.JAVA_BYTE_ARRAY:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getByteArrayValue, byte[][]::new);";
                break;

            case SchemaProperty.JAVA_CALENDAR:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getCalendarValue, java.util.Calendar[]::new);";
                break;

            case SchemaProperty.JAVA_DATE:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getDateValue, java.util.Date[]::new);";
                break;

            case SchemaProperty.JAVA_GDATE:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getGDateValue, org.apache.xmlbeans.GDate[]::new);";
                break;

            case SchemaProperty.JAVA_GDURATION:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getGDurationValue, org.apache.xmlbeans.GDuration[]::new);";
                break;

            case SchemaProperty.JAVA_QNAME:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getQNameValue, javax.xml.namespace.QName[]::new);";
                break;

            case SchemaProperty.JAVA_LIST:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getListValue, java.util.List[]::new);";
                break;

            case SchemaProperty.JAVA_OBJECT:
                em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getObjectValue, java.util.Object[]::new);";
                break;

            case SchemaProperty.JAVA_USER:
                // TOOD: replace lambda with method reference
                em = "ObjectArray(#ID#, e -> " + getUserTypeStaticHandlerMethod(false, stype) + "(e), " + stype.getUserTypeName() + "[]::new);";
                break;

            default:
                throw new IllegalStateException();
        }
        emit("return get" +em.replace("#ID#", setIdentifier), BeanMethod.GET_ARRAY);
    }

    void printJGetValue(int javaType, String type, SchemaTypeImpl stype) throws IOException {
        String em;
        switch (javaType) {
            case SchemaProperty.XML_OBJECT:
                em = "target";
                break;

            case SchemaProperty.JAVA_BOOLEAN:
                em = "target.getBooleanValue()";
                break;

            case SchemaProperty.JAVA_FLOAT:
                em = "target.getFloatValue()";
                break;

            case SchemaProperty.JAVA_DOUBLE:
                em = "target.getDoubleValue()";
                break;

            case SchemaProperty.JAVA_BYTE:
                em = "target.getByteValue()";
                break;

            case SchemaProperty.JAVA_SHORT:
                em = "target.getShortValue()";
                break;

            case SchemaProperty.JAVA_INT:
                em = "target.getIntValue()";
                break;

            case SchemaProperty.JAVA_LONG:
                em = "target.getLongValue()";
                break;

            case SchemaProperty.JAVA_BIG_DECIMAL:
                em = "target.getBigDecimalValue()";
                break;

            case SchemaProperty.JAVA_BIG_INTEGER:
                em = "target.getBigIntegerValue()";
                break;

            case SchemaProperty.JAVA_STRING:
                em = "target.getStringValue()";
                break;

            case SchemaProperty.JAVA_BYTE_ARRAY:
                em = "target.getByteArrayValue()";
                break;

            case SchemaProperty.JAVA_GDATE:
                em = "target.getGDateValue()";
                break;

            case SchemaProperty.JAVA_GDURATION:
                em = "target.getGDurationValue()";
                break;

            case SchemaProperty.JAVA_CALENDAR:
                em = "target.getCalendarValue()";
                break;

            case SchemaProperty.JAVA_DATE:
                em = "target.getDateValue()";
                break;

            case SchemaProperty.JAVA_QNAME:
                em = "target.getQNameValue()";
                break;

            case SchemaProperty.JAVA_LIST:
                em = "target.getListValue()";
                break;

            case SchemaProperty.JAVA_ENUM:
                em = "(" + type + ")target.getEnumValue()";
                break;

            case SchemaProperty.JAVA_OBJECT:
                em = "target.getObjectValue()";
                break;

            case SchemaProperty.JAVA_USER:
                em = getUserTypeStaticHandlerMethod(false, stype) + "(target)";
                break;

            default:
                throw new IllegalStateException();
        }
        emit("return " + em + ";");
    }

    void printJSetValue(int javaType, String safeVarName, SchemaTypeImpl stype) throws IOException {
        String em;
        switch (javaType) {
            case SchemaProperty.XML_OBJECT:
                em = "target.set(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_BOOLEAN:
                em = "target.setBooleanValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_FLOAT:
                em = "target.setFloatValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_DOUBLE:
                em = "target.setDoubleValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_BYTE:
                em = "target.setByteValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_SHORT:
                em = "target.setShortValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_INT:
                em = "target.setIntValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_LONG:
                em = "target.setLongValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_BIG_DECIMAL:
                em = "target.setBigDecimalValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_BIG_INTEGER:
                em = "target.setBigIntegerValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_STRING:
                em = "target.setStringValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_BYTE_ARRAY:
                em = "target.setByteArrayValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_GDATE:
                em = "target.setGDateValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_GDURATION:
                em = "target.setGDurationValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_CALENDAR:
                em = "target.setCalendarValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_DATE:
                em = "target.setDateValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_QNAME:
                em = "target.setQNameValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_LIST:
                em = "target.setListValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_ENUM:
                em = "target.setEnumValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_OBJECT:
                em = "target.setObjectValue(#VARNAME#)";
                break;

            case SchemaProperty.JAVA_USER:
                em = getUserTypeStaticHandlerMethod(true, stype) + "(#VARNAME#, target)";
                break;

            default:
                throw new IllegalStateException();
        }
        emit(em.replace("#VARNAME#", safeVarName) + ";");
    }

    String getIdentifier(Map<QName, Integer> qnameMap, QName qName) {
        return "PROPERTY_QNAME[" + qnameMap.get(qName) + "]";
    }

    String getSetIdentifier(Map<QName, Integer> qnameMap, QName qName, Map<QName, Integer> qsetMap) {
        Integer ord = qsetMap.get(qName);
        return ord == null ? getIdentifier(qnameMap, qName) : "PROPERTY_QSET["+ ord + "]";
    }

    void printStaticFields(SchemaProperty[] properties, Map<QName, Integer> qnameMap, Map<QName, Integer> qsetMap) throws IOException {
        if (properties.length == 0) {
            return;
        }

        int countQSet = 0;
        emit("");
        emit("private static final QName[] PROPERTY_QNAME = {");
        indent();
        for (SchemaProperty prop : properties) {
            final QName name = prop.getName();
            qnameMap.put(name, qnameMap.size());
            emit("new QName(\"" + name.getNamespaceURI() + "\", \"" + name.getLocalPart() + "\"),");
            countQSet = Math.max(countQSet, (prop.acceptedNames() == null ? 0 : prop.acceptedNames().length));
        }
        outdent();
        emit("};");
        emit("");

        if (countQSet > 1) {
            emit("private static final QNameSet[] PROPERTY_QSET = {");
            for (SchemaProperty prop : properties) {
                final QName name = prop.getName();
                final QName[] qnames = prop.acceptedNames();
                if (qnames != null && qnames.length > 1) {
                    qsetMap.put(name, qsetMap.size());
                    emit("QNameSet.forArray( new QName[] { ");
                    indent();
                    for (QName qname : qnames) {
                        emit("new QName(\"" + qname.getNamespaceURI() + "\", \"" + qname.getLocalPart() + "\"),");
                    }
                    outdent();
                    emit("}),");
                }
            }
            emit("};");
        }
    }

    void emitImplementationPreamble() throws IOException {
        emit("synchronized (monitor())");
        emit("{");
        indent();
        emit("check_orphaned();");
    }

    void emitImplementationPostamble() throws IOException {
        outdent();
        emit("}");
    }

    void emitAddTarget(String identifier, boolean isAttr, String xtype)
        throws IOException {
        if (isAttr) {
            emit("target = (" + xtype + ")get_store().add_attribute_user(" + identifier + ");");
        } else {
            emit("target = (" + xtype + ")get_store().add_element_user(" + identifier + ");");
        }
    }

    void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException {
        emitPre(sType, opType, identifier, isAttr, "-1");
    }

    void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException {
        SchemaTypeImpl sImpl = getImpl(sType);
        if (sImpl == null) {
            return;
        }

        PrePostExtension ext = sImpl.getPrePostExtension();
        if (ext != null) {
            if (ext.hasPreCall()) {
                emit("if ( " + ext.getStaticHandler() + ".preSet(" + prePostOpString(opType) + ", this, " + identifier + ", " + isAttr + ", " + index + ")) {");
                startBlock();
            }
        }
    }

    void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException {
        emitPost(sType, opType, identifier, isAttr, "-1");
    }

    void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException {
        SchemaTypeImpl sImpl = getImpl(sType);
        if (sImpl == null) {
            return;
        }

        PrePostExtension ext = sImpl.getPrePostExtension();
        if (ext != null) {
            if (ext.hasPreCall()) {
                endBlock();
            }

            if (ext.hasPostCall()) {
                emit(ext.getStaticHandler() + ".postSet(" + prePostOpString(opType) + ", this, " + identifier + ", " + isAttr + ", " + index + ");");
            }
        }
    }

    String prePostOpString(int opType) {
        switch (opType) {
            default:
                assert false;

            case PrePostExtension.OPERATION_SET:
                return "org.apache.xmlbeans.PrePostExtension.OPERATION_SET";

            case PrePostExtension.OPERATION_INSERT:
                return "org.apache.xmlbeans.PrePostExtension.OPERATION_INSERT";

            case PrePostExtension.OPERATION_REMOVE:
                return "org.apache.xmlbeans.PrePostExtension.OPERATION_REMOVE";
        }
    }

    private static final int NOTHING = 1;
    private static final int ADD_NEW_VALUE = 3;
    private static final int THROW_EXCEPTION = 4;

    void emitGetTarget(String setIdentifier,
                       String identifier,
                       boolean isAttr,
                       String index,
                       int nullBehaviour,
                       String xtype)
        throws IOException {
        assert setIdentifier != null && identifier != null;

        emit(xtype + " target = null;");

        if (isAttr) {
            emit("target = (" + xtype + ")get_store().find_attribute_user(" + identifier + ");");
        } else {
            emit("target = (" + xtype + ")get_store().find_element_user(" + setIdentifier + ", " + index + ");");
        }

        if (nullBehaviour == NOTHING) {
            return;
        }

        emit("if (target == null) {");

        startBlock();

        switch (nullBehaviour) {
            case ADD_NEW_VALUE:
                // target already emited, no need for emitDeclareTarget(false, xtype);
                emitAddTarget(identifier, isAttr, xtype);
                break;

            case THROW_EXCEPTION:
                emit("throw new IndexOutOfBoundsException();");
                break;

            default:
                assert false : "Bad behaviour type: " + nullBehaviour;
        }

        endBlock();
    }

    void printListGetterImpl(String propdesc, String propertyName, String wrappedType, boolean xmltype, boolean xget)
    throws IOException {
        Set<BeanMethod> bmList = (opt == null) ? null : opt.getCompilePartialMethod();
        if (bmList != null && !bmList.contains(xget ? BeanMethod.XGET_LIST : BeanMethod.GET_LIST)) {
            return;
        }

        String arrayName = propertyName + "Array";

        printJavaDoc("Gets " + (xget ? "(as xml) " : "") + "a List of " + propdesc + "s");
        if (!opt.isCompileNoAnnotations()) {
            emit("@Override");
        }
        emit("public java.util.List<" + wrappedType + "> " + (xget ? "xget" : "get") + propertyName + "List() {");
        startBlock();

        emitImplementationPreamble();

        emit("return new org.apache.xmlbeans.impl.values.JavaList" + ((xmltype || xget) ? "Xml" : "") + "Object<>(");
        indent();
        if (bmList == null || bmList.contains(xget ? BeanMethod.XGET_IDX : BeanMethod.GET_IDX)) {
            emit("this::" + (xget ? "xget" : "get") + arrayName + ",");
        } else {
            emit("null,");
        }
        if (bmList == null || bmList.contains(xget ? BeanMethod.XSET_IDX : BeanMethod.SET_IDX)) {
            emit("this::" + (xget ? "xset" : "set") + arrayName + ",");
        } else {
            emit("null,");
        }
        if (bmList == null || bmList.contains((xmltype || xget) ? BeanMethod.INSERT_NEW_IDX : BeanMethod.INSERT_IDX)) {
            emit("this::insert" + ((xmltype || xget) ? "New" : "") + propertyName + ",");
        } else {
            emit("null,");
        }
        if (bmList == null || bmList.contains(BeanMethod.REMOVE_IDX)) {
            emit("this::remove" + propertyName + ",");
        } else {
            emit("null,");
        }
        if (bmList == null || bmList.contains(BeanMethod.SIZE_OF_ARRAY)) {
            emit("this::sizeOf" + arrayName);
        } else {
            emit("null");
        }
        outdent();
        emit(");");

        emitImplementationPostamble();
        endBlock();
    }

    void printGetterImpls(SchemaProperty prop, Map<QName, Integer> qnameMap, Map<QName, Integer> qsetMap)
    throws IOException {
        final QName qName = prop.getName();
        final String identifier = getIdentifier(qnameMap, qName);
        final String setIdentifier = getSetIdentifier(qnameMap, qName, qsetMap);
        final boolean several = prop.extendsJavaArray();
        final boolean nillable = prop.hasNillable() != SchemaProperty.NEVER;
        final String type = javaTypeForProperty(prop);
        final String xtype = xmlTypeForProperty(prop);
        final int javaType = prop.getJavaTypeCode();
        final boolean isAttr = prop.isAttribute();
        final String propertyName = prop.getJavaPropertyName();

        String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
        boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
        String jtargetType = (xmlTypeForPropertyIsUnion(prop) || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype;

        Set<BeanMethod> bmList = (opt == null) ? null : opt.getCompilePartialMethod();


        if (prop.extendsJavaSingleton()) {
            if (bmList == null || bmList.contains(BeanMethod.GET)) {
                // Value getProp()
                printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + type + " get" + propertyName + "() {");
                startBlock();
                emitImplementationPreamble();

                emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, jtargetType);

                if (isAttr && (prop.hasDefault() == SchemaProperty.CONSISTENTLY ||
                               prop.hasFixed() == SchemaProperty.CONSISTENTLY)) {
                    emit("if (target == null) {");
                    startBlock();
                    makeAttributeDefaultValue(jtargetType, prop, identifier);
                    endBlock();
                }
                emit("if (target == null) {");
                startBlock();
                makeMissingValue(javaType);
                endBlock();

                printJGetValue(javaType, type, (SchemaTypeImpl) prop.getType());

                emitImplementationPostamble();

                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XGET))) {
                // Value xgetProp()
                printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + xtype + " xget" + propertyName + "() {");
                startBlock();
                emitImplementationPreamble();
                emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype);

                if (isAttr && (prop.hasDefault() == SchemaProperty.CONSISTENTLY ||
                               prop.hasFixed() == SchemaProperty.CONSISTENTLY)) {
                    emit("if (target == null) {");
                    startBlock();
                    makeAttributeDefaultValue(xtype, prop, identifier);
                    endBlock();
                }

                emit("return target;");
                emitImplementationPostamble();
                endBlock();
            }

            if (nillable && (bmList == null || bmList.contains(BeanMethod.IS_NIL))) {
                // boolean isNilProp()
                printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public boolean isNil" + propertyName + "() {");
                startBlock();
                emitImplementationPreamble();
                emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype);

                emit("if (target == null) return false;");
                emit("return target.isNil();");
                emitImplementationPostamble();
                endBlock();
            }
        }

        if (prop.extendsJavaOption() && (bmList == null || bmList.contains(BeanMethod.IS_SET))) {
            // boolean isSetProp()
            printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc);
            if (!opt.isCompileNoAnnotations()) {
                emit("@Override");
            }
            emit("public boolean isSet" + propertyName + "() {");

            startBlock();
            emitImplementationPreamble();

            if (isAttr) {
                emit("return get_store().find_attribute_user(" + identifier + ") != null;");
            } else {
                emit("return get_store().count_elements(" + setIdentifier + ") != 0;");
            }

            emitImplementationPostamble();
            endBlock();
        }

        if (several) {
            String arrayName = propertyName + "Array";

            // use boxed type if the java type is a primitive and jdk1.5
            // jdk1.5 will box/unbox for us
            String wrappedType = type;
            if (isJavaPrimitive(javaType)) {
                wrappedType = javaWrappedType(javaType);
            }

            printListGetterImpl(propdesc, propertyName, wrappedType, xmltype, false);

            if (bmList == null || bmList.contains(BeanMethod.GET_ARRAY)) {
                // Value[] getProp()
                printJavaDoc("Gets array of all " + propdesc + "s");
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + type + "[] get" + arrayName + "() {");
                startBlock();

                printJGetArrayValue(javaType, type, (SchemaTypeImpl) prop.getType(), setIdentifier);

                endBlock();
            }

            if (bmList == null || bmList.contains(BeanMethod.GET_IDX)) {
                // Value getProp(int i)
                printJavaDoc("Gets ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + type + " get" + arrayName + "(int i) {");
                startBlock();
                emitImplementationPreamble();

                emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
                printJGetValue(javaType, type, (SchemaTypeImpl) prop.getType());

                emitImplementationPostamble();
                endBlock();
            }

            if (!xmltype) {
                printListGetterImpl(propdesc, propertyName, xtype, false, true);
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XGET_ARRAY))) {
                // Value[] xgetProp()
                printJavaDoc("Gets (as xml) array of all " + propdesc + "s");
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + xtype + "[] xget" + arrayName + "() {");
                startBlock();
                emit("return xgetArray(" + setIdentifier + ", " + xtype + "[]::new);");
                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XGET_IDX))) {
                // Value xgetProp(int i)
                printJavaDoc("Gets (as xml) ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + xtype + " xget" + arrayName + "(int i) {");
                startBlock();
                emitImplementationPreamble();
                emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
                emit("return target;");
                emitImplementationPostamble();
                endBlock();
            }

            if (nillable && (bmList == null || bmList.contains(BeanMethod.IS_NIL_IDX))) {
                // boolean isNil(int i);
                printJavaDoc("Tests for nil ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public boolean isNil" + arrayName + "(int i) {");
                startBlock();
                emitImplementationPreamble();
                emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
                emit("return target.isNil();");
                emitImplementationPostamble();
                endBlock();
            }

            // int countProp();
            if (bmList == null || bmList.contains(BeanMethod.SIZE_OF_ARRAY)) {
                printJavaDoc("Returns number of " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public int sizeOf" + arrayName + "() {");
                startBlock();
                emitImplementationPreamble();
                emit("return get_store().count_elements(" + setIdentifier + ");");
                emitImplementationPostamble();
                endBlock();
            }
        }
    }

    void printSetterImpls(SchemaProperty prop, Map<QName, Integer> qnameMap, Map<QName, Integer> qsetMap, SchemaType sType)
    throws IOException {
        final QName qName = prop.getName();
        final String identifier = getIdentifier(qnameMap, qName);
        final String setIdentifier = getSetIdentifier(qnameMap, qName, qsetMap);
        final boolean several = prop.extendsJavaArray();
        final boolean nillable = prop.hasNillable() != SchemaProperty.NEVER;
        final String type = javaTypeForProperty(prop);
        final String xtype = xmlTypeForProperty(prop);
        final int javaType = prop.getJavaTypeCode();
        final boolean isAttr = prop.isAttribute();
        final String propertyName = prop.getJavaPropertyName();
        Set<BeanMethod> bmList = (opt == null) ? null : opt.getCompilePartialMethod();

        String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName));
        safeVarName = NameUtil.nonExtraKeyword(safeVarName);

        boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
        boolean isobj = (javaType == SchemaProperty.JAVA_OBJECT);
        boolean isSubstGroup = !Objects.equals(identifier, setIdentifier);
        String jtargetType = (xmlTypeForPropertyIsUnion(prop) || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype;

        String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");

        if (prop.extendsJavaSingleton()) {
            if (bmList == null || bmList.contains(BeanMethod.SET)) {
                // void setProp(Value v);
                printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void set" + propertyName + "(" + type + " " + safeVarName + ") {");
                startBlock();
                if (xmltype && !isSubstGroup && !isAttr) {
                    emitPre(sType, PrePostExtension.OPERATION_SET, identifier, false, several ? "0" : "-1");
                    emit("generatedSetterHelperImpl(" + safeVarName + ", " + setIdentifier + ", 0, " +
                         "org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_SINGLETON);");
                    emitPost(sType, PrePostExtension.OPERATION_SET, identifier, false, several ? "0" : "-1");
                } else {
                    emitImplementationPreamble();
                    emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                    emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, jtargetType);
                    printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType());
                    emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                    emitImplementationPostamble();
                }
                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XSET))) {
                // void xsetProp(Value v)
                printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void xset" + propertyName + "(" + xtype + " " + safeVarName + ") {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype);
                emit("target.set(" + safeVarName + ");");
                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                emitImplementationPostamble();
                endBlock();

            }

            if (xmltype && !several && (bmList == null || bmList.contains(BeanMethod.ADD_NEW))) {
                // Value addNewProp()
                printJavaDoc("Appends and returns a new empty " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + xtype + " addNew" + propertyName + "() {");
                startBlock();
                emitImplementationPreamble();
                emit(xtype + " target = null;");
                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                emitAddTarget(identifier, isAttr, xtype);
                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                emit("return target;");
                emitImplementationPostamble();
                endBlock();
            }

            if (nillable && (bmList == null || bmList.contains(BeanMethod.SET_NIL))) {
                printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void setNil" + propertyName + "() {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype);
                emit("target.setNil();");
                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                emitImplementationPostamble();
                endBlock();
            }
        }

        if (prop.extendsJavaOption() && (bmList == null || bmList.contains(BeanMethod.UNSET))) {
            printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc);
            if (!opt.isCompileNoAnnotations()) {
                emit("@Override");
            }
            emit("public void unset" + propertyName + "() {");
            startBlock();
            emitImplementationPreamble();
            emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1");
            if (isAttr) {
                emit("get_store().remove_attribute(" + identifier + ");");
            } else {
                emit("get_store().remove_element(" + setIdentifier + ", 0);");
            }
            emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1");
            emitImplementationPostamble();
            endBlock();
        }

        if (several) {
            String arrayName = propertyName + "Array";

            if (bmList == null || bmList.contains(BeanMethod.SET_ARRAY)) {
                if (xmltype) {
                    printJavaDoc("Sets array of all " + propdesc + "  WARNING: This method is not atomicaly synchronized.");
                    if (!opt.isCompileNoAnnotations()) {
                        emit("@Override");
                    }
                    emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array) {");
                    startBlock();
                    // do not use synchronize (monitor()) {  and GlobalLock inside  } !!! deadlock
                    //emitImplementationPreamble();
                    emit("check_orphaned();");
                    emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);

                    if (isobj) {
                        if (!isSubstGroup) {
                            emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");");
                        } else {
                            emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");");
                        }
                    } else {
                        if (!isSubstGroup) {
                            emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");");
                        } else {
                            emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");");
                        }
                    }

                    emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
                    //emitImplementationPostamble();  to avoid deadlock
                    endBlock();
                } else {
                    printJavaDoc("Sets array of all " + propdesc);
                    if (!opt.isCompileNoAnnotations()) {
                        emit("@Override");
                    }
                    emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array) {");
                    startBlock();
                    emitImplementationPreamble();
                    emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);

                    if (isobj) {
                        if (!isSubstGroup) {
                            emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");");
                        } else {
                            emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");");
                        }
                    } else if (prop.getJavaTypeCode() == SchemaProperty.JAVA_USER) {
                        if (!isSubstGroup) {
                            emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ");");
                            emit("for ( int i = 0 ; i < dests.length ; i++ ) {");
                            emit("    " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl) prop.getType())
                                 + "(" + safeVarName + "Array[i], dests[i]);");
                            emit("}");
                        } else {
                            emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ", " + setIdentifier + ");");
                            emit("for ( int i = 0 ; i < dests.length ; i++ ) {");
                            emit("    " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl) prop.getType())
                                 + "(" + safeVarName + "Array[i], dests[i]);");
                            emit("}");
                        }
                    } else {
                        if (!isSubstGroup) {
                            emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");");
                        } else {
                            emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");");
                        }
                    }

                    emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
                    emitImplementationPostamble();
                    endBlock();
                }
            }

            if (bmList == null || bmList.contains(BeanMethod.SET_IDX)) {
                printJavaDoc("Sets ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void set" + arrayName + "(int i, " + type + " " + safeVarName + ") {");
                startBlock();
                if (xmltype && !isSubstGroup) {
                    emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                    emit("generatedSetterHelperImpl(" + safeVarName + ", " + setIdentifier + ", i, " +
                         "org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_ARRAYITEM);");
                    emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                } else {
                    emitImplementationPreamble();
                    emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                    emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
                    printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType());
                    emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                    emitImplementationPostamble();
                }
                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XSET_ARRAY))) {
                printJavaDoc("Sets (as xml) array of all " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void xset" + arrayName + "(" + xtype + "[]" + safeVarName + "Array) {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
                emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");");
                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
                emitImplementationPostamble();
                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XSET_IDX))) {
                printJavaDoc("Sets (as xml) ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ") {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
                emit("target.set(" + safeVarName + ");");
                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                emitImplementationPostamble();
                endBlock();
            }

            if (nillable && (bmList == null || bmList.contains(BeanMethod.SET_NIL_IDX))) {
                printJavaDoc("Nils the ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void setNil" + arrayName + "(int i) {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
                emit("target.setNil();");
                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                emitImplementationPostamble();
                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.INSERT_IDX))) {
                printJavaDoc("Inserts the value as the ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void insert" + propertyName + "(int i, " + type + " " + safeVarName + ") {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                emit(jtargetType + " target = ");
                indent();
                if (!isSubstGroup) {
                    emit("(" + jtargetType + ")get_store().insert_element_user(" + identifier + ", i);");
                } else // This is a subst group case
                {
                    emit("(" + jtargetType + ")get_store().insert_element_user(" + setIdentifier + ", " +
                         identifier + ", i);");
                }
                outdent();
                printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType());
                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                emitImplementationPostamble();
                endBlock();
            }

            if (!xmltype && (bmList == null || bmList.contains(BeanMethod.ADD))) {
                printJavaDoc("Appends the value as the last " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void add" + propertyName + "(" + type + " " + safeVarName + ") {");
                startBlock();
                emitImplementationPreamble();
                emit(jtargetType + " target = null;");
                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                emitAddTarget(identifier, isAttr, jtargetType);
                printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType());
                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                emitImplementationPostamble();
                endBlock();
            }

            if (bmList == null || bmList.contains(BeanMethod.INSERT_NEW_IDX)) {
                printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + xtype + " insertNew" + propertyName + "(int i) {");
                startBlock();
                emitImplementationPreamble();
                emit(xtype + " target = null;");
                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                if (!isSubstGroup) {
                    emit("target = (" + xtype + ")get_store().insert_element_user(" + identifier + ", i);");
                } else // This is a subst group case
                {
                    emit("target = (" + xtype + ")get_store().insert_element_user(" +
                         setIdentifier + ", " + identifier + ", i);");
                }
                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                emit("return target;");
                emitImplementationPostamble();
                endBlock();
            }

            if (bmList == null || bmList.contains(BeanMethod.ADD_NEW)) {
                printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public " + xtype + " addNew" + propertyName + "() {");
                startBlock();
                emitImplementationPreamble();
                emit(xtype + " target = null;");
                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                emitAddTarget(identifier, isAttr, xtype);
                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                emit("return target;");
                emitImplementationPostamble();
                endBlock();
            }

            if (bmList == null || bmList.contains(BeanMethod.REMOVE_IDX)) {
                printJavaDoc("Removes the ith " + propdesc);
                if (!opt.isCompileNoAnnotations()) {
                    emit("@Override");
                }
                emit("public void remove" + propertyName + "(int i) {");
                startBlock();
                emitImplementationPreamble();
                emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i");
                emit("get_store().remove_element(" + setIdentifier + ", i);");
                emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i");
                emitImplementationPostamble();
                endBlock();
            }
        }
    }

    SchemaProperty[] getSchemaProperties(SchemaType sType) {
        if (sType.getContentType() != SchemaType.SIMPLE_CONTENT) {
            // complex content type implementations derive from base type impls
            // so derived property impls can be reused
            return getDerivedProperties(sType);
        }

        // simple content types impls derive directly from "holder" impls
        // in order to handle the case (for ints or string enums e.g.) where
        // there is a simple type restriction.  So property getters need to
        // be implemented "from scratch" for each derived complex type
        // Moreover, attribute or element properties can be removed via restriction,
        // but we still need to implement them because this class is supposed to
        // also implement all the interfaces
        SchemaType baseType = sType.getBaseType();
        List<SchemaProperty> extraProperties = null;
        while (!baseType.isSimpleType() && !baseType.isBuiltinType()) {
            for (SchemaProperty baseProperty : baseType.getDerivedProperties()) {
                if (!(baseProperty.isAttribute() && sType.getAttributeProperty(baseProperty.getName()) != null)) {
                    if (extraProperties == null) {
                        extraProperties = new ArrayList<>();
                    }
                    extraProperties.add(baseProperty);
                }
            }
            baseType = baseType.getBaseType();
        }

        SchemaProperty[] properties = sType.getProperties();
        if (extraProperties == null) {
            return properties;
        }

        Collections.addAll(extraProperties, properties);
        return extraProperties.toArray(new SchemaProperty[0]);
    }

    void printInnerTypeImpl(
        SchemaType sType, SchemaTypeSystem system, boolean isInner) throws IOException {
        String shortName = sType.getShortJavaImplName();

        printInnerTypeJavaDoc(sType);

        startClass(sType, isInner);

        printConstructor(sType, shortName);

        printExtensionImplMethods(sType);

        if (!sType.isSimpleType()) {
            SchemaProperty[] properties = getSchemaProperties(sType);
            Map<QName, Integer> qnameMap = new HashMap<>();
            Map<QName, Integer> qsetMap = new HashMap<>();
            printStaticFields(properties, qnameMap, qsetMap);

            for (SchemaProperty prop : properties) {
                printGetterImpls(prop, qnameMap, qsetMap);

                if (!prop.isReadOnly()) {
                    printSetterImpls(prop, qnameMap, qsetMap, sType);
                }
            }
        }

        printNestedTypeImpls(sType, system);

        endBlock();
    }

    private SchemaProperty[] getDerivedProperties(SchemaType sType) {
        // We have to see if this is redefined, because if it is we have
        // to include all properties associated to its supertypes
        QName name = sType.getName();
        if (name != null && name.equals(sType.getBaseType().getName())) {
            SchemaType sType2 = sType.getBaseType();
            // Walk all the redefined types and record any properties
            // not present in sType, because the redefined types do not
            // have a generated class to represent them
            SchemaProperty[] props = sType.getDerivedProperties();
            Map<QName, SchemaProperty> propsByName = new LinkedHashMap<>();
            for (SchemaProperty prop : props) {
                propsByName.put(prop.getName(), prop);
            }
            while (sType2 != null && name.equals(sType2.getName())) {
                props = sType2.getDerivedProperties();
                for (SchemaProperty prop : props) {
                    if (!propsByName.containsKey(prop.getName())) {
                        propsByName.put(prop.getName(), prop);
                    }
                }
                sType2 = sType2.getBaseType();
            }
            return propsByName.values().toArray(new SchemaProperty[0]);
        } else {
            return sType.getDerivedProperties();
        }
    }

    private void printExtensionImplMethods(SchemaType sType) throws IOException {
        SchemaTypeImpl sImpl = getImpl(sType);
        if (sImpl == null) {
            return;
        }

        InterfaceExtension[] exts = sImpl.getInterfaceExtensions();
        if (exts != null) {
            for (InterfaceExtension ext : exts) {
                InterfaceExtension.MethodSignature[] methods = ext.getMethods();
                if (methods != null) {
                    for (InterfaceExtension.MethodSignature method : methods) {
                        printJavaDoc("Implementation method for interface " + ext.getStaticHandler());
                        printInterfaceMethodDecl(method);
                        startBlock();
                        printInterfaceMethodImpl(ext.getStaticHandler(), method);
                        endBlock();
                    }
                }
            }
        }
    }

    void printInterfaceMethodDecl(InterfaceExtension.MethodSignature method) throws IOException {
        StringBuilder decl = new StringBuilder(60);

        decl.append("public ").append(method.getReturnType());
        decl.append(" ").append(method.getName()).append("(");

        String[] paramTypes = method.getParameterTypes();
        for (int i = 0; i < paramTypes.length; i++) {
            if (i != 0) {
                decl.append(", ");
            }
            decl.append(paramTypes[i]).append(" p").append(i);
        }

        decl.append(")");

        String[] exceptions = method.getExceptionTypes();
        for (int i = 0; i < exceptions.length; i++) {
            decl.append(i == 0 ? " throws " : ", ").append(exceptions[i]);
        }

        decl.append(" {");

        emit(decl.toString());
    }

    void printInterfaceMethodImpl(String handler, InterfaceExtension.MethodSignature method) throws IOException {
        StringBuilder impl = new StringBuilder(60);

        if (!method.getReturnType().equals("void")) {
            impl.append("return ");
        }

        impl.append(handler).append(".").append(method.getName()).append("(this");

        String[] params = method.getParameterTypes();
        for (int i = 0; i < params.length; i++) {
            impl.append(", p").append(i);
        }

        impl.append(");");

        emit(impl.toString());
    }

    void printNestedTypeImpls(SchemaType sType, SchemaTypeSystem system) throws IOException {
        boolean redefinition = sType.getName() != null &&
                               sType.getName().equals(sType.getBaseType().getName());
        while (sType != null) {
            SchemaType[] anonTypes = sType.getAnonymousTypes();
            for (SchemaType anonType : anonTypes) {
                if (anonType.isSkippedAnonymousType()) {
                    printNestedTypeImpls(anonType, system);
                } else {
                    printInnerTypeImpl(anonType, system, true);
                }
            }
            // For redefinition by extension, go ahead and print the anonymous
            // types in the base
            if (!redefinition ||
                (sType.getDerivationType() != SchemaType.DT_EXTENSION && !sType.isSimpleType())) {
                break;
            }
            sType = sType.getBaseType();
        }
    }

    public void printHolder(Writer writer, SchemaTypeSystem system, XmlOptions opt, Repackager repackager) throws IOException {
        _writer = writer;

        String sysPack = system.getName();
        if (repackager != null) {
            sysPack = repackager.repackage(new StringBuffer(sysPack)).toString();
        }
        emit("package "+sysPack+";");
        emit("");
        emit("import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl;");
        emit("");
        emit("public final class TypeSystemHolder extends SchemaTypeSystemImpl {");
        indent();
        emit("public static final TypeSystemHolder typeSystem = new TypeSystemHolder();");
        emit("");
        emit("private TypeSystemHolder() {");
        indent();
        emit("super(TypeSystemHolder.class);");
        outdent();
        emit("}");
        outdent();
        emit("}");
    }
}
