/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.xsom.impl.util;

import com.sun.xml.xsom.XSAnnotation;
import com.sun.xml.xsom.XSAttGroupDecl;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSAttributeUse;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSContentType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSFacet;
import com.sun.xml.xsom.XSIdentityConstraint;
import com.sun.xml.xsom.XSListSimpleType;
import com.sun.xml.xsom.XSModelGroup;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSNotation;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSRestrictionSimpleType;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.XSType;
import com.sun.xml.xsom.XSUnionSimpleType;
import com.sun.xml.xsom.XSWildcard;
import com.sun.xml.xsom.XSXPath;
import com.sun.xml.xsom.impl.Const;
import com.sun.xml.xsom.visitor.XSSimpleTypeVisitor;
import com.sun.xml.xsom.visitor.XSTermVisitor;
import com.sun.xml.xsom.visitor.XSVisitor;
import org.xml.sax.Locator;

import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.Iterator;

/**
 * Generates approximated tree model for XML from a schema component. This is
 * not intended to be a fully-fledged round-trippable tree model.
 *
 * <h2>Usage of this class</h2>
 *
 * <ol> <li>Create a new instance.</li> <li>Call {@link #visit(XSSchemaSet)}
 * function on your schema set.</li>
 * <li>Retrieve the model using {@link #getModel()}. </li></ol>
 *
 * Every node in the resulting tree is a {@link SchemaTreeTraverser.SchemaTreeNode},
 * and the model itself is {@link SchemaTreeTraverser.SchemaTreeModel}. You can
 * use {@link SchemaTreeTraverser.SchemaTreeCellRenderer} as a cell renderer for
 * your tree.
 *
 * @author Kirill Grouchnikov (kirillcool@yahoo.com)
 */
public class SchemaTreeTraverser implements XSVisitor, XSSimpleTypeVisitor {
    /**
     * The associated tree model.
     */
    private SchemaTreeModel model;

    /**
     * The current node in the tree.
     */
    private SchemaTreeNode currNode;

    /**
     * Tree model for schema hierarchy tree.
     *
     * @author Kirill Grouchnikov
     */
    public static final class SchemaTreeModel extends DefaultTreeModel {
        private static final long serialVersionUID = 3202903011416748633L;
        /**
         * A simple constructor. Is made private to allow creating the root node
         * first.
         *
         * @param root The root node.
         */
        private SchemaTreeModel(SchemaRootNode root) {
            super(root);
        }

        /**
         * A factory method for creating a new empty tree.
         *
         * @return New empty tree model.
         */
        public static SchemaTreeModel getInstance() {
            SchemaRootNode root = new SchemaRootNode();
            return new SchemaTreeModel(root);
        }

        public void addSchemaNode(SchemaTreeNode node) {
            ((SchemaRootNode) this.root).add(node);
        }
    }

    /**
     * The node of the schema hierarchy tree.
     *
     * @author Kirill Grouchnikov
     */
    public static class SchemaTreeNode extends DefaultMutableTreeNode {
        private static final long serialVersionUID = 5119501381189181864L;
        /**
         * File name of the corresponding schema artifact.
         */
        private String fileName;

        /**
         * Line number of the corresponding schema artifact.
         */
        private int lineNumber;

        /**
         * The caption of the corresponding artifact.
         */
        private String artifactName;

        /**
         * Simple constructor.
         *
         * @param artifactName Artifact name.
         * @param locator      Artifact locator.
         */
        public SchemaTreeNode(String artifactName, Locator locator) {
            this.artifactName = artifactName;
            if (locator == null) {
                this.fileName = null;
            }
            else {
                String filename = locator.getSystemId();
                filename = filename.replaceAll("\u002520", " ");
                // strip leading protocol
                if (filename.startsWith("file:/")) {
                    filename = filename.substring(6);
                }

                this.fileName = filename;
                this.lineNumber = locator.getLineNumber() - 1;
            }
        }

        /**
         * Returns the caption for <code>this</code> node.
         *
         * @return The caption for <code>this</code> node.
         */
        public String getCaption() {
            return this.artifactName;
        }

        /**
         * @return Returns the file name of the corresponding schema artifact.
         */
        public String getFileName() {
            return fileName;
        }

        /**
         * @param fileName The file name of the corresponding schema artifact to
         *                 set.
         */
        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        /**
         * @return Returns the line number of the corresponding schema
         *         artifact.
         */
        public int getLineNumber() {
            return lineNumber;
        }

        /**
         * @param lineNumber The line number of the corresponding schema
         *                   artifact to set.
         */
        public void setLineNumber(int lineNumber) {
            this.lineNumber = lineNumber;
        }
    }

    /**
     * The root node of the schema hierarchy tree.
     *
     * @author Kirill Grouchnikov
     */
    public static class SchemaRootNode extends SchemaTreeNode {
        private static final long serialVersionUID = -4869737965361647583L;
        /**
         * A simple constructor.
         */
        public SchemaRootNode() {
            super("Schema set", null);
        }
    }


    /**
     * Sample cell renderer for the schema tree.
     *
     * @author Kirill Grouchnikov
     */
    public static class SchemaTreeCellRenderer extends JPanel implements
            TreeCellRenderer {
        private static final long serialVersionUID = 865538344984392435L;
        /**
         * The icon label.
         */
        protected final JLabel iconLabel;

        /**
         * The text label
         */
        protected final JLabel nameLabel;

        /**
         * The selection indicator.
         */
        private boolean isSelected;

        /**
         * Background color for selected cells (light brown).
         */
        public final Color selectedBackground = new Color(255, 244, 232);


        /**
         * Foreground color for selected cells, both text and border (dark
         * brown).
         */
        public final Color selectedForeground = new Color(64, 32, 0);

        /**
         * Default font for the text label.
         */
        public final Font nameFont = new Font("Arial", Font.BOLD, 12);


        /**
         * Simple constructor.
         */
        public SchemaTreeCellRenderer() {
            FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 1, 1);
            this.setLayout(fl);
            this.iconLabel = new JLabel();
            this.iconLabel.setOpaque(false);
            this.iconLabel.setBorder(null);
            this.add(this.iconLabel);

            // add some space
            this.add(Box.createHorizontalStrut(5));

            this.nameLabel = new JLabel();
            this.nameLabel.setOpaque(false);
            this.nameLabel.setBorder(null);
            this.nameLabel.setFont(nameFont);
            this.add(this.nameLabel);

            this.isSelected = false;

            this.setOpaque(false);
            this.setBorder(null);
        }

        /*
         * (non-Javadoc)
         *
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
         */
        public final void paintComponent(Graphics g) {
            int width = this.getWidth();
            int height = this.getHeight();
            if (this.isSelected) {
                g.setColor(selectedBackground);
                g.fillRect(0, 0, width - 1, height - 1);
                g.setColor(selectedForeground);
                g.drawRect(0, 0, width - 1, height - 1);
            }
            super.paintComponent(g);
        }

        /**
         * Sets values for the icon and text of <code>this</code> renderer.
         *
         * @param icon     Icon to show.
         * @param caption  Text to show.
         * @param selected Selection indicator. If <code>true</code>, the
         *                 renderer will be shown with different background and
         *                 border settings.
         */
        protected final void setValues(Icon icon, String caption,
                                       boolean selected) {

            this.iconLabel.setIcon(icon);
            this.nameLabel.setText(caption);

            this.isSelected = selected;
            if (selected) {
                this.nameLabel.setForeground(selectedForeground);
            }
            else {
                this.nameLabel.setForeground(Color.black);
            }
        }

        /* (non-Javadoc)
         * @see javax.swing.tree.TreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, java.lang.Object, boolean, boolean, boolean, int, boolean)
         */
        public final Component getTreeCellRendererComponent(JTree tree, Object value,
                                                            boolean selected, boolean expanded, boolean leaf, int row,
                                                            boolean hasFocus) {
            if (value instanceof SchemaTreeNode) {
                SchemaTreeNode stn = (SchemaTreeNode) value;

                this.setValues(null, stn.getCaption(), selected);
                return this;
            }
            throw new IllegalStateException("Unknown node");
        }
    }


    /**
     * Simple constructor.
     */
    public SchemaTreeTraverser() {
        this.model = SchemaTreeModel.getInstance();
        this.currNode = (SchemaTreeNode) this.model.getRoot();
    }

    /**
     * Retrieves the tree model of <code>this</code> traverser.
     *
     * @return Tree model of <code>this</code> traverser.
     */
    public SchemaTreeModel getModel() {
        return model;
    }

    /**
     * Visits the root schema set.
     *
     * @param s Root schema set.
     */
    public void visit(XSSchemaSet s) {
        for (XSSchema schema : s.getSchemas()) {
            schema(schema);
        }
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#schema(com.sun.xml.xsom.XSSchema)
     */
    public void schema(XSSchema s) {
        // QUICK HACK: don't print the built-in components
        if (s.getTargetNamespace().equals(Const.schemaNamespace)) {
            return;
        }

        SchemaTreeNode newNode = new SchemaTreeNode("Schema "
                + s.getLocator().getSystemId(), s.getLocator());
        this.currNode = newNode;
        this.model.addSchemaNode(newNode);

        for (XSAttGroupDecl groupDecl : s.getAttGroupDecls().values()) {
            attGroupDecl(groupDecl);
        }

        for (XSAttributeDecl attrDecl : s.getAttributeDecls().values()) {
            attributeDecl(attrDecl);
        }

        for (XSComplexType complexType : s.getComplexTypes().values()) {
            complexType(complexType);
        }

        for (XSElementDecl elementDecl : s.getElementDecls().values()) {
            elementDecl(elementDecl);
        }

        for (XSModelGroupDecl modelGroupDecl : s.getModelGroupDecls().values()) {
            modelGroupDecl(modelGroupDecl);
        }

        for (XSSimpleType simpleType : s.getSimpleTypes().values()) {
            simpleType(simpleType);
        }
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#attGroupDecl(com.sun.xml.xsom.XSAttGroupDecl)
     */
    public void attGroupDecl(XSAttGroupDecl decl) {
        SchemaTreeNode newNode = new SchemaTreeNode("Attribute group \""
                + decl.getName() + "\"", decl.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        Iterator itr;

        itr = decl.iterateAttGroups();
        while (itr.hasNext()) {
            dumpRef((XSAttGroupDecl) itr.next());
        }

        itr = decl.iterateDeclaredAttributeUses();
        while (itr.hasNext()) {
            attributeUse((XSAttributeUse) itr.next());
        }

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /**
     * Creates node of attribute group decalration reference.
     *
     * @param decl Attribute group decalration reference.
     */
    public void dumpRef(XSAttGroupDecl decl) {
        SchemaTreeNode newNode = new SchemaTreeNode("Attribute group ref \"{"
                + decl.getTargetNamespace() + "}" + decl.getName() + "\"", decl
                .getLocator());
        this.currNode.add(newNode);
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#attributeUse(com.sun.xml.xsom.XSAttributeUse)
     */
    public void attributeUse(XSAttributeUse use) {
        XSAttributeDecl decl = use.getDecl();

        String additionalAtts = "";

        if (use.isRequired()) {
            additionalAtts += " use=\"required\"";
        }
        if (use.getFixedValue() != null
                && use.getDecl().getFixedValue() == null) {
            additionalAtts += " fixed=\"" + use.getFixedValue() + "\"";
        }
        if (use.getDefaultValue() != null
                && use.getDecl().getDefaultValue() == null) {
            additionalAtts += " default=\"" + use.getDefaultValue() + "\"";
        }

        if (decl.isLocal()) {
            // this is anonymous attribute use
            dump(decl, additionalAtts);
        }
        else {
            // reference to a global one
            String str = MessageFormat.format(
                    "Attribute ref \"'{'{0}'}'{1}{2}\"", decl.getTargetNamespace(), decl.getName(),
                    additionalAtts);
            SchemaTreeNode newNode = new SchemaTreeNode(str, decl.getLocator());
            this.currNode.add(newNode);
        }
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#attributeDecl(com.sun.xml.xsom.XSAttributeDecl)
     */
    public void attributeDecl(XSAttributeDecl decl) {
        dump(decl, "");
    }

    /**
     * Creates node for attribute declaration with additional attributes.
     *
     * @param decl           Attribute declaration.
     * @param additionalAtts Additional attributes.
     */
    private void dump(XSAttributeDecl decl, String additionalAtts) {
        XSSimpleType type = decl.getType();

        String str = MessageFormat.format("Attribute \"{0}\"{1}{2}{3}{4}",
                decl.getName(),
                additionalAtts,
                type.isLocal() ? "" : MessageFormat.format(
                        " type=\"'{'{0}'}'{1}\"", type.getTargetNamespace(),
                        type.getName()),
                decl.getFixedValue() == null ? "" : " fixed=\""
            + decl.getFixedValue() + "\"",
                decl.getDefaultValue() == null ? "" : " default=\""
            + decl.getDefaultValue() + "\"");

        SchemaTreeNode newNode = new SchemaTreeNode(str, decl.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        if (type.isLocal()) {
            simpleType(type);
        }
        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSContentTypeVisitor#simpleType(com.sun.xml.xsom.XSSimpleType)
     */
    public void simpleType(XSSimpleType type) {

        String str = MessageFormat.format("Simple type {0}",
                type.isLocal() ? "" : " name=\""
                + type.getName() + "\"");

        SchemaTreeNode newNode = new SchemaTreeNode(str, type.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        type.visit((XSSimpleTypeVisitor) this);

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSSimpleTypeVisitor#listSimpleType(com.sun.xml.xsom.XSListSimpleType)
     */
    public void listSimpleType(XSListSimpleType type) {
        XSSimpleType itemType = type.getItemType();

        if (itemType.isLocal()) {
            SchemaTreeNode newNode = new SchemaTreeNode("List", type
                    .getLocator());
            this.currNode.add(newNode);
            this.currNode = newNode;
            simpleType(itemType);
            this.currNode = (SchemaTreeNode) this.currNode.getParent();
        }
        else {
            // global type
            String str = MessageFormat.format("List itemType=\"'{'{0}'}'{1}\"",
                    itemType.getTargetNamespace(),
                    itemType.getName());
            SchemaTreeNode newNode = new SchemaTreeNode(str, itemType
                    .getLocator());
            this.currNode.add(newNode);
        }
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSSimpleTypeVisitor#unionSimpleType(com.sun.xml.xsom.XSUnionSimpleType)
     */
    public void unionSimpleType(XSUnionSimpleType type) {
        final int len = type.getMemberSize();
        StringBuilder ref = new StringBuilder();

        for (int i = 0; i < len; i++) {
            XSSimpleType member = type.getMember(i);
            if (member.isGlobal()) {
                ref.append(MessageFormat.format(" '{'{0}'}'{1}",
                        member.getTargetNamespace(),
                        member.getName()));
            }
        }

        String name = (ref.length() == 0) ? "Union" : ("Union memberTypes=\""
                + ref + "\"");
        SchemaTreeNode newNode = new SchemaTreeNode(name, type.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        for (int i = 0; i < len; i++) {
            XSSimpleType member = type.getMember(i);
            if (member.isLocal()) {
                simpleType(member);
            }
        }
        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSSimpleTypeVisitor#restrictionSimpleType(com.sun.xml.xsom.XSRestrictionSimpleType)
     */
    public void restrictionSimpleType(XSRestrictionSimpleType type) {

        if (type.getBaseType() == null) {
            // don't print anySimpleType
            if (!type.getName().equals("anySimpleType")) {
                throw new InternalError();
            }
            if (!Const.schemaNamespace.equals(type.getTargetNamespace())) {
                throw new InternalError();
            }
            return;
        }

        XSSimpleType baseType = type.getSimpleBaseType();

        String str = MessageFormat.format("Restriction {0}",
                baseType.isLocal() ? "" : " base=\"{"
                + baseType.getTargetNamespace() + "}"
                + baseType.getName() + "\"");

        SchemaTreeNode newNode = new SchemaTreeNode(str, baseType.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        if (baseType.isLocal()) {
            simpleType(baseType);
        }

        Iterator itr = type.iterateDeclaredFacets();
        while (itr.hasNext()) {
            facet((XSFacet) itr.next());
        }

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#facet(com.sun.xml.xsom.XSFacet)
     */
    public void facet(XSFacet facet) {
        SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat.format(
                "{0} value=\"{1}\"", facet.getName(),
                facet.getValue()),
                facet.getLocator());
        this.currNode.add(newNode);
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#notation(com.sun.xml.xsom.XSNotation)
     */
    public void notation(XSNotation notation) {
        SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat.format(
                "Notation name='\"0}\" public =\"{1}\" system=\"{2}\"",
                notation.getName(), notation.getPublicId(),
                notation.getSystemId()), notation.getLocator());
        this.currNode.add(newNode);
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#complexType(com.sun.xml.xsom.XSComplexType)
     */
    public void complexType(XSComplexType type) {
        SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat.format(
                "ComplexType {0}", type.isLocal() ? ""
                : " name=\"" + type.getName() + "\""), type
                .getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        // TODO: wildcard

        if (type.getContentType().asSimpleType() != null) {
            // simple content
            SchemaTreeNode newNode2 = new SchemaTreeNode("Simple content", type
                    .getContentType().getLocator());
            this.currNode.add(newNode2);
            this.currNode = newNode2;

            XSType baseType = type.getBaseType();

            if (type.getDerivationMethod() == XSType.RESTRICTION) {
                // restriction
                String str = MessageFormat.format(
                        "Restriction base=\"<{0}>{1}\"", baseType.getTargetNamespace(),
                        baseType.getName());
                SchemaTreeNode newNode3 = new SchemaTreeNode(str, baseType
                        .getLocator());
                this.currNode.add(newNode3);
                this.currNode = newNode3;

                dumpComplexTypeAttribute(type);

                this.currNode = (SchemaTreeNode) this.currNode.getParent();
            }
            else {
                // extension
                String str = MessageFormat.format(
                        "Extension base=\"<{0}>{1}\"", baseType.getTargetNamespace(),
                        baseType.getName());
                SchemaTreeNode newNode3 = new SchemaTreeNode(str, baseType
                        .getLocator());
                this.currNode.add(newNode3);
                this.currNode = newNode3;

                // check if have redefine tag
                if ((type.getTargetNamespace().compareTo(
                        baseType.getTargetNamespace()) ==
                        0)
                        && (type.getName().compareTo(baseType.getName()) == 0)) {
                    SchemaTreeNode newNodeRedefine = new SchemaTreeNode(
                            "redefine", type
                            .getLocator());
                    this.currNode.add(newNodeRedefine);
                    this.currNode = newNodeRedefine;
                    baseType.visit(this);
                    this.currNode =
                            (SchemaTreeNode) newNodeRedefine.getParent();
                }

                dumpComplexTypeAttribute(type);

                this.currNode = (SchemaTreeNode) this.currNode.getParent();
            }

            this.currNode = (SchemaTreeNode) this.currNode.getParent();
        }
        else {
            // complex content
            SchemaTreeNode newNode2 = new SchemaTreeNode("Complex content",
                    type.getContentType().getLocator());
            this.currNode.add(newNode2);
            this.currNode = newNode2;

            XSComplexType baseType = type.getBaseType().asComplexType();

            if (type.getDerivationMethod() == XSType.RESTRICTION) {
                // restriction
                String str = MessageFormat.format(
                        "Restriction base=\"<{0}>{1}\"", baseType.getTargetNamespace(),
                        baseType.getName());
                SchemaTreeNode newNode3 = new SchemaTreeNode(str,
                        baseType.getLocator());
                this.currNode.add(newNode3);
                this.currNode = newNode3;

                type.getContentType().visit(this);
                dumpComplexTypeAttribute(type);

                this.currNode = (SchemaTreeNode) this.currNode.getParent();
            }
            else {
                // extension
                String str = MessageFormat.format(
                        "Extension base=\"'{'{0}'}'{1}\"", baseType.getTargetNamespace(),
                        baseType.getName());
                SchemaTreeNode newNode3 = new SchemaTreeNode(str,
                        baseType.getLocator());
                this.currNode.add(newNode3);
                this.currNode = newNode3;

                // check if have redefine tag
                if ((type.getTargetNamespace().compareTo(
                        baseType.getTargetNamespace()) ==
                        0)
                        && (type.getName().compareTo(baseType.getName()) == 0)) {
                    SchemaTreeNode newNodeRedefine = new SchemaTreeNode(
                            "redefine", type
                            .getLocator());
                    this.currNode.add(newNodeRedefine);
                    this.currNode = newNodeRedefine;
                    baseType.visit(this);
                    this.currNode =
                            (SchemaTreeNode) newNodeRedefine.getParent();
                }

                type.getExplicitContent().visit(this);
                dumpComplexTypeAttribute(type);

                this.currNode = (SchemaTreeNode) this.currNode.getParent();
            }

            this.currNode = (SchemaTreeNode) this.currNode.getParent();
        }

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /**
     * Creates node for complex type.
     *
     * @param type Complex type.
     */
    private void dumpComplexTypeAttribute(XSComplexType type) {
        Iterator itr;

        itr = type.iterateAttGroups();
        while (itr.hasNext()) {
            dumpRef((XSAttGroupDecl) itr.next());
        }

        itr = type.iterateDeclaredAttributeUses();
        while (itr.hasNext()) {
            attributeUse((XSAttributeUse) itr.next());
        }
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSTermVisitor#elementDecl(com.sun.xml.xsom.XSElementDecl)
     */
    public void elementDecl(XSElementDecl decl) {
        elementDecl(decl, "");
    }

    /**
     * Creates node for element declaration with additional attributes.
     *
     * @param decl      Element declaration.
     * @param extraAtts Additional attributes.
     */
    private void elementDecl(XSElementDecl decl, String extraAtts) {
        XSType type = decl.getType();

        // TODO: various other attributes

        String str = MessageFormat.format("Element name=\"{0}\"{1}{2}",
                decl.getName(),
                type.isLocal() ? "" : " type=\"{"
            + type.getTargetNamespace() + "}"
            + type.getName() + "\"", extraAtts);

        SchemaTreeNode newNode = new SchemaTreeNode(str, decl.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        if (type.isLocal()) {
            if (type.isLocal()) {
                type.visit(this);
            }
        }

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSTermVisitor#modelGroupDecl(com.sun.xml.xsom.XSModelGroupDecl)
     */
    public void modelGroupDecl(XSModelGroupDecl decl) {
        SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat.format(
                "Group name=\"{0}\"", decl.getName()),
                decl.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        modelGroup(decl.getModelGroup());

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSTermVisitor#modelGroup(com.sun.xml.xsom.XSModelGroup)
     */
    public void modelGroup(XSModelGroup group) {
        modelGroup(group, "");
    }

    /**
     * Creates node for model group with additional attributes.
     *
     * @param group     Model group.
     * @param extraAtts Additional attributes.
     */
    private void modelGroup(XSModelGroup group, String extraAtts) {
        SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat.format(
                "{0}{1}", group.getCompositor(), extraAtts),
                group.getLocator());
        this.currNode.add(newNode);
        this.currNode = newNode;

        final int len = group.getSize();
        for (int i = 0; i < len; i++) {
            particle(group.getChild(i));
        }

        this.currNode = (SchemaTreeNode) this.currNode.getParent();
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSContentTypeVisitor#particle(com.sun.xml.xsom.XSParticle)
     */
    public void particle(XSParticle part) {
        BigInteger i;

        StringBuilder buf = new StringBuilder();

        i = part.getMaxOccurs();
        if (i.equals(BigInteger.valueOf(XSParticle.UNBOUNDED))) {
            buf.append(" maxOccurs=\"unbounded\"");
        }
        else {
            if (!i.equals(BigInteger.ONE)) {
                buf.append(" maxOccurs=\"").append(i).append("\"");
            }
        }

        i = part.getMinOccurs();
        if (!i.equals(BigInteger.ONE)) {
            buf.append(" minOccurs=\"").append(i).append("\"");
        }

        final String extraAtts = buf.toString();

        part.getTerm().visit(new XSTermVisitor() {
            public void elementDecl(XSElementDecl decl) {
                if (decl.isLocal()) {
                    SchemaTreeTraverser.this.elementDecl(decl, extraAtts);
                }
                else {
                    // reference
                    SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat
                            .format("Element ref=\"'{'{0}'}'{1}\"{2}",
                                    decl.getTargetNamespace(),
                                    decl.getName(), extraAtts),
                            decl.getLocator());
                    currNode.add(newNode);
                }
            }

            public void modelGroupDecl(XSModelGroupDecl decl) {
                // reference
                SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat
                        .format("Group ref=\"'{'{0}'}'{1}\"{2}", decl.getTargetNamespace(), decl.getName(),
                                extraAtts), decl.getLocator());
                currNode.add(newNode);
            }

            public void modelGroup(XSModelGroup group) {
                SchemaTreeTraverser.this.modelGroup(group, extraAtts);
            }

            public void wildcard(XSWildcard wc) {
                SchemaTreeTraverser.this.wildcard(wc, extraAtts);
            }
        });
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSTermVisitor#wildcard(com.sun.xml.xsom.XSWildcard)
     */
    public void wildcard(XSWildcard wc) {
        wildcard(wc, "");
    }

    /**
     * Creates node for wild card with additional attributes.
     *
     * @param wc        Wild card.
     * @param extraAtts Additional attributes.
     */
    private void wildcard(XSWildcard wc, String extraAtts) {
        // TODO
        SchemaTreeNode newNode = new SchemaTreeNode(MessageFormat.format(
                "Any ", extraAtts), wc.getLocator());
        currNode.add(newNode);
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#annotation(com.sun.xml.xsom.XSAnnotation)
     */
    public void annotation(XSAnnotation ann) {
        // TODO: it would be nice even if we just put <xs:documentation>
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSContentTypeVisitor#empty(com.sun.xml.xsom.XSContentType)
     */
    public void empty(XSContentType t) {
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#identityConstraint(com.sun.xml.xsom.XSIdentityConstraint)
     */
    public void identityConstraint(XSIdentityConstraint ic) {
    }

    /* (non-Javadoc)
     * @see com.sun.xml.xsom.visitor.XSVisitor#xpath(com.sun.xml.xsom.XSXPath)
     */
    public void xpath(XSXPath xp) {
    }
}
