/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qxsdschemachecker_p.h"

#include "qderivedinteger_p.h"
#include "qderivedstring_p.h"
#include "qpatternplatform_p.h"
#include "qqnamevalue_p.h"
#include "qsourcelocationreflection_p.h"
#include "qvaluefactory_p.h"
#include "qxsdattributereference_p.h"
#include "qxsdparticlechecker_p.h"
#include "qxsdreference_p.h"
#include "qxsdschemacontext_p.h"
#include "qxsdschemahelper_p.h"
#include "qxsdschemaparsercontext_p.h"
#include "qxsdschematypesfactory_p.h"
#include "qxsdtypechecker_p.h"

#include "qxsdschemachecker_helper.cpp"

QT_BEGIN_NAMESPACE

using namespace QPatternist;

XsdSchemaChecker::XsdSchemaChecker(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext)
    : m_context(context)
    , m_namePool(parserContext->namePool())
    , m_schema(parserContext->schema())
{
    setupAllowedAtomicFacets();
}

XsdSchemaChecker::~XsdSchemaChecker()
{
}

/*
 * This method is called after the resolver has set the base type for every
 * type and information about deriavtion and 'is simple type vs. is complex type'
 * are available.
 */
void XsdSchemaChecker::basicCheck()
{
    // first check that there is no circular inheritance, only the
    // wxsSuperType is used here
    checkBasicCircularInheritances();

    // check the basic constraints like simple type can not inherit from complex type etc.
    checkBasicSimpleTypeConstraints();
    checkBasicComplexTypeConstraints();
}

void XsdSchemaChecker::check()
{
    checkCircularInheritances();
    checkInheritanceRestrictions();
    checkSimpleDerivationRestrictions();
    checkSimpleTypeConstraints();
    checkComplexTypeConstraints();
    checkDuplicatedAttributeUses();

    checkElementConstraints();
    checkAttributeConstraints();
    checkAttributeUseConstraints();
//    checkElementDuplicates();
}

void XsdSchemaChecker::addComponentLocationHash(const ComponentLocationHash &hash)
{
    m_componentLocationHash.unite(hash);
}

/**
 * Checks whether the @p otherType is the same as @p myType or if one of its
 * ancestors is the same as @p myType.
 */
static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> visitedTypes)
{
    bool retval = false;

    if (otherType) {
        if (visitedTypes.contains(otherType)) {
            return true;
        } else {
            visitedTypes.insert(otherType);
        }
        // simple types can have different varieties, so we have to check each of them
        if (otherType->isSimpleType()) {
            const XsdSimpleType::Ptr simpleType = otherType;
            if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
                // for atomic type we use the same test as in SchemaType::wxsTypeMatches
                retval = (myType == simpleType ? true : matchesType(myType, simpleType->wxsSuperType(), visitedTypes));
            } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
                // for list type we test against the itemType property
                retval = (myType == simpleType->itemType() ? true : matchesType(myType, simpleType->itemType()->wxsSuperType(), visitedTypes));
            } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
                // for union type we test against each member type
                const XsdSimpleType::List members = simpleType->memberTypes();
                for (int i = 0; i < members.count(); ++i) {
                    if (myType == members.at(i) ? true : matchesType(myType, members.at(i)->wxsSuperType(), visitedTypes)) {
                        retval = true;
                        break;
                    }
                }
            } else {
                // reached xsAnySimple type whichs category is None
                retval = false;
            }
        } else {
            // if no simple type we handle it like in SchemaType::wxsTypeMatches
            retval = (myType == otherType ? true : matchesType(myType, otherType->wxsSuperType(), visitedTypes));
        }
    } else // if otherType is null it doesn't match
        retval = false;

    return retval;
}

/**
 * Checks whether there is a circular inheritance for the union inheritance.
 */
static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool)
{
    if (type == otherType) {
        return true;
    }

    if (!otherType->isSimpleType() || !otherType->isDefinedBySchema()) {
        return false;
    }

    const XsdSimpleType::Ptr simpleOtherType = otherType;

    if (simpleOtherType->category() == XsdSimpleType::SimpleTypeUnion) {
        const XsdSimpleType::List memberTypes = simpleOtherType->memberTypes();
        for (int i = 0; i < memberTypes.count(); ++i) {
            if (otherType->wxsSuperType() == type) {
                return true;
            }
            if (hasCircularUnionInheritance(type, memberTypes.at(i), namePool)) {
                return true;
            }
        }
    }

    return false;
}

static inline bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> &visitedTypes, SchemaType::Ptr &conflictingType)
{
    if (!otherType)
        return false;

    if (visitedTypes.contains(otherType)) { // inheritance loop detected
        conflictingType = otherType;
        return true;
    } else {
        visitedTypes.insert(otherType);
    }

    if (type == otherType)
        return true;

    return wxsTypeMatches(type, otherType->wxsSuperType(), visitedTypes, conflictingType);
}

void XsdSchemaChecker::checkBasicCircularInheritances()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);
        const QSourceLocation location = sourceLocationForType(type);

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)

        // check normal base type inheritance
        QSet<SchemaType::Ptr> visitedTypes;
        SchemaType::Ptr conflictingType;

        if (wxsTypeMatches(type, type->wxsSuperType(), visitedTypes, conflictingType)) {
            if (conflictingType)
                m_context->error(QtXmlPatterns::tr("%1 has inheritance loop in its base type %2.")
                                                  .arg(formatType(m_namePool, type))
                                                  .arg(formatType(m_namePool, conflictingType)),
                                 XsdSchemaContext::XSDError, location);
            else
                m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);

            return;
        }
    }
}

void XsdSchemaChecker::checkCircularInheritances()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);
        const QSourceLocation location = sourceLocationForType(type);

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)

        // check normal base type inheritance
        QSet<SchemaType::Ptr> visitedTypes;
        if (matchesType(type, type->wxsSuperType(), visitedTypes)) {
            m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
            return;
        }

        // check union member inheritance
        if (type->isSimpleType() && type->isDefinedBySchema()) {
            const XsdSimpleType::Ptr simpleType = type;
            if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
                const XsdSimpleType::List memberTypes = simpleType->memberTypes();
                for (int j = 0; j < memberTypes.count(); ++j) {
                    if (hasCircularUnionInheritance(simpleType, memberTypes.at(j), m_namePool)) {
                        m_context->error(QtXmlPatterns::tr("Circular inheritance of union %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
                        return;
                    }
                }
            }
        }
    }
}

void XsdSchemaChecker::checkInheritanceRestrictions()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);
        const QSourceLocation location = sourceLocationForType(type);

        // check inheritance restrictions given by final property of base class
        const SchemaType::Ptr baseType = type->wxsSuperType();
        if (baseType->isDefinedBySchema()) {
            if ((type->derivationMethod() == SchemaType::DerivationRestriction) && (baseType->derivationConstraints() & SchemaType::RestrictionConstraint)) {
                m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by restriction as the latter defines it as final.")
                                                  .arg(formatType(m_namePool, type))
                                                  .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
                return;
            } else if ((type->derivationMethod() == SchemaType::DerivationExtension) && (baseType->derivationConstraints() & SchemaType::ExtensionConstraint)) {
                m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by extension as the latter defines it as final.")
                                                  .arg(formatType(m_namePool, type))
                                                  .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
                return;
            }
        }
    }
}

void XsdSchemaChecker::checkBasicSimpleTypeConstraints()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);

        if (!type->isSimpleType())
            continue;

        const XsdSimpleType::Ptr simpleType = type;

        const QSourceLocation location = sourceLocation(simpleType);

        // check inheritance restrictions of simple type defined by schema constraints
        const SchemaType::Ptr baseType = simpleType->wxsSuperType();

        if (baseType->isComplexType() && (simpleType->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool))) {
            m_context->error(QtXmlPatterns::tr("Base type of simple type %1 cannot be complex type %2.")
                                              .arg(formatType(m_namePool, simpleType))
                                              .arg(formatType(m_namePool, baseType)),
                             XsdSchemaContext::XSDError, location);
            return;
        }

        if (baseType == BuiltinTypes::xsAnyType) {
            if (type->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
                m_context->error(QtXmlPatterns::tr("Simple type %1 cannot have direct base type %2.")
                                                  .arg(formatType(m_namePool, simpleType))
                                                  .arg(formatType(m_namePool, BuiltinTypes::xsAnyType)),
                                 XsdSchemaContext::XSDError, location);
                return;
            }
        }
    }
}

void XsdSchemaChecker::checkSimpleTypeConstraints()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);

        if (!type->isSimpleType())
            continue;

        const XsdSimpleType::Ptr simpleType = type;

        const QSourceLocation location = sourceLocation(simpleType);

        if (simpleType->category() == XsdSimpleType::None) {
            // additional checks
            // check that no user defined type has xs:AnySimpleType as base type (except xs:AnyAtomicType)
            if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
                if (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
                    m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
                                                      .arg(formatType(m_namePool, simpleType))
                                                      .arg(formatType(m_namePool, simpleType->wxsSuperType())),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }
            }
            // check that no user defined type has xs:AnyAtomicType as base type
            if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
                m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
                                                  .arg(formatType(m_namePool, simpleType))
                                                  .arg(formatType(m_namePool, simpleType->wxsSuperType())),
                                 XsdSchemaContext::XSDError, location);
                return;
            }
        }

        // @see http://www.w3.org/TR/xmlschema11-1/#d0e37310
        if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
            // 1.1
            if ((simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeAtomic) && (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool))) {
                m_context->error(QtXmlPatterns::tr("Simple type %1 can only have simple atomic type as base type.")
                                                  .arg(formatType(m_namePool, simpleType)),
                                 XsdSchemaContext::XSDError, location);
            }
            // 1.2
            if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
                m_context->error(QtXmlPatterns::tr("Simple type %1 cannot derive from %2 as the latter defines restriction as final.")
                                                  .arg(formatType(m_namePool, simpleType->wxsSuperType()))
                                                  .arg(formatType(m_namePool, simpleType)),
                                 XsdSchemaContext::XSDError, location);
            }

            // 1.3
            // checked by checkConstrainingFacets  already
        } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
            const AnySimpleType::Ptr itemType = simpleType->itemType();

            // 2.1 or @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
            if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
                m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
                return;
            }

            // 2.1 second part
            if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
                const XsdSimpleType::Ptr simpleItemType = itemType;
                const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
                for (int j = 0; j < memberTypes.count(); ++j) {
                    if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic && memberTypes.at(j)->category() != SchemaType::SimpleTypeUnion) {
                        m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic or union.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
                        return;
                    }
                }
            }

            // 2.2.1
            if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
                if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
                    const XsdSimpleType::Ptr simpleItemType = itemType;

                    // 2.2.1.1
                    if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
                        m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
                                                          .arg(formatType(m_namePool, simpleType))
                                                          .arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
                        return;
                    }

                    // 2.2.1.2
                    const XsdFacet::Hash facets = simpleType->facets();

                    bool invalidFacetFound = false;
                    for (auto it = facets.cbegin(), end = facets.cend(); it != end; ++it) {
                        if (it.key() != XsdFacet::WhiteSpace) {
                            invalidFacetFound = true;
                            break;
                        }
                    }

                    if (invalidFacetFound) {
                        m_context->error(QtXmlPatterns::tr("Simple type %1 is only allowed to have %2 facet.")
                                                          .arg(formatType(m_namePool, simpleType))
                                                          .arg(formatKeyword("whiteSpace")),
                                         XsdSchemaContext::XSDError, location);
                        return;
                    }
                }
            } else { // 2.2.2
                // 2.2.2.1
                if (simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeList) {
                    m_context->error(QtXmlPatterns::tr("Base type of simple type %1 must have variety of type list.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
                    return;
                }

                // 2.2.2.2
                if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
                    m_context->error(QtXmlPatterns::tr("Base type of simple type %1 has defined derivation by restriction as final.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
                    return;
                }

                // 2.2.2.3
                if (!XsdSchemaHelper::isSimpleDerivationOk(itemType, XsdSimpleType::Ptr(simpleType->wxsSuperType())->itemType(), SchemaType::DerivationConstraints())) {
                    m_context->error(QtXmlPatterns::tr("Item type of base type does not match item type of %1.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
                    return;
                }

                // 2.2.2.4
                const XsdFacet::Hash facets = simpleType->facets();

                bool invalidFacetFound = false;
                XsdFacet::Type invalidFacetType = XsdFacet::None;
                for (auto it = facets.cbegin(), end = facets.cend(); it != end; ++it) {
                    const XsdFacet::Type facetType = it.key();
                    if (facetType != XsdFacet::Length &&
                        facetType != XsdFacet::MinimumLength &&
                        facetType != XsdFacet::MaximumLength &&
                        facetType != XsdFacet::WhiteSpace &&
                        facetType != XsdFacet::Pattern &&
                        facetType != XsdFacet::Enumeration) {
                        invalidFacetType = facetType;
                        invalidFacetFound = true;
                        break;
                    }
                }

                if (invalidFacetFound) {
                    m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
                                                      .arg(formatType(m_namePool, simpleType))
                                                      .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                // 2.2.2.5
                // TODO: check value constraints
            }


        } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
            const AnySimpleType::List memberTypes = simpleType->memberTypes();

            if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { // 3.1.1
                // 3.3.1.1
                for (int i = 0; i < memberTypes.count(); ++i) {
                    const AnySimpleType::Ptr memberType = memberTypes.at(i);

                    if (memberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
                        m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
                                                          .arg(formatType(m_namePool, simpleType))
                                                          .arg(formatType(m_namePool, memberType)), XsdSchemaContext::XSDError, location);
                        return;
                    }
                }

                // 3.3.1.2
                if (!simpleType->facets().isEmpty()) {
                    m_context->error(QtXmlPatterns::tr("%1 is not allowed to have any facets.")
                                                      .arg(formatType(m_namePool, simpleType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }
            } else {
                // 3.1.2.1
                if (simpleType->wxsSuperType()->category() != SchemaType::SimpleTypeUnion) {
                    m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 must have variety of union.")
                                                      .arg(formatType(m_namePool, simpleType->wxsSuperType()))
                                                      .arg(formatType(m_namePool, simpleType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                // 3.1.2.2
                if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::DerivationRestriction) {
                    m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute.")
                                                      .arg(formatType(m_namePool, simpleType->wxsSuperType()))
                                                      .arg(formatType(m_namePool, simpleType))
                                                      .arg(formatAttribute("final")),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                //3.1.2.3
                if (simpleType->wxsSuperType()->isDefinedBySchema()) {
                    const XsdSimpleType::Ptr simpleBaseType(simpleType->wxsSuperType());

                    AnySimpleType::List baseMemberTypes = simpleBaseType->memberTypes();
                    for (int i = 0; i < memberTypes.count(); ++i) {
                        const AnySimpleType::Ptr memberType = memberTypes.at(i);
                        const AnySimpleType::Ptr baseMemberType = baseMemberTypes.at(i);

                        if (!XsdSchemaHelper::isSimpleDerivationOk(memberType, baseMemberType, SchemaType::DerivationConstraints())) {
                            m_context->error(QtXmlPatterns::tr("Member type %1 cannot be derived from member type %2 of %3's base type %4.")
                                                              .arg(formatType(m_namePool, memberType))
                                                              .arg(formatType(m_namePool, baseMemberType))
                                                              .arg(formatType(m_namePool, simpleType))
                                                              .arg(formatType(m_namePool, simpleBaseType)),
                                             XsdSchemaContext::XSDError, location);
                        }
                    }
                }

                // 3.1.2.4
                const XsdFacet::Hash facets = simpleType->facets();

                bool invalidFacetFound = false;
                XsdFacet::Type invalidFacetType = XsdFacet::None;
                for (auto it = facets.cbegin(), end = facets.cend(); it != end; ++it) {
                    const XsdFacet::Type facetType = it.key();
                    if (facetType != XsdFacet::Pattern &&
                        facetType != XsdFacet::Enumeration) {
                        invalidFacetType = facetType;
                        invalidFacetFound = true;
                        break;
                    }
                }

                if (invalidFacetFound) {
                    m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
                                                      .arg(formatType(m_namePool, simpleType))
                                                      .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                // 3.1.2.5
                // TODO: check value constraints
            }
        }
    }
}

void XsdSchemaChecker::checkBasicComplexTypeConstraints()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);

        if (!type->isComplexType() || !type->isDefinedBySchema())
            continue;

        const XsdComplexType::Ptr complexType = type;

        const QSourceLocation location = sourceLocation(complexType);

        // check inheritance restrictions of complex type defined by schema constraints
        const SchemaType::Ptr baseType = complexType->wxsSuperType();

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 2)
        if (baseType->isSimpleType() && (complexType->derivationMethod() != XsdComplexType::DerivationExtension)) {
            m_context->error(QtXmlPatterns::tr("Derivation method of %1 must be extension because the base type %2 is a simple type.")
                                              .arg(formatType(m_namePool, complexType))
                                              .arg(formatType(m_namePool, baseType)),
                             XsdSchemaContext::XSDError, location);
            return;
        }
    }
}

void XsdSchemaChecker::checkComplexTypeConstraints()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);

        if (!type->isComplexType() || !type->isDefinedBySchema())
            continue;

        const XsdComplexType::Ptr complexType = type;

        const QSourceLocation location = sourceLocation(complexType);

        if (complexType->contentType()->particle()) {
            XsdElement::Ptr duplicatedElement;
            if (XsdParticleChecker::hasDuplicatedElements(complexType->contentType()->particle(), m_namePool, duplicatedElement)) {
                m_context->error(QtXmlPatterns::tr("Complex type %1 has duplicated element %2 in its content model.")
                                                  .arg(formatType(m_namePool, complexType))
                                                  .arg(formatKeyword(duplicatedElement->displayName(m_namePool))),
                                 XsdSchemaContext::XSDError, location);
                return;
            }

            if (!XsdParticleChecker::isUPAConform(complexType->contentType()->particle(), m_namePool)) {
                m_context->error(QtXmlPatterns::tr("Complex type %1 has non-deterministic content.")
                                                  .arg(formatType(m_namePool, complexType)),
                                 XsdSchemaContext::XSDError, location);
                return;
            }
        }

        // check inheritance restrictions of complex type defined by schema constraints
        const SchemaType::Ptr baseType = complexType->wxsSuperType();

        // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends
        if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) {
            if (baseType->isComplexType() && baseType->isDefinedBySchema()) {
                const XsdComplexType::Ptr complexBaseType = baseType;

                // we can skip 1.1 here, as it is tested in checkInheritanceRestrictions() already

                // 1.2 and 1.3
                QString errorMsg;
                if (!XsdSchemaHelper::isValidAttributeUsesExtension(complexType->attributeUses(), complexBaseType->attributeUses(),
                                                                    complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
                    m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3.")
                                                      .arg(formatType(m_namePool, complexType))
                                                      .arg(formatType(m_namePool, baseType))
                                                      .arg(errorMsg),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                // 1.4
                bool validContentType = false;
                if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
                    if (complexType->contentType()->simpleType() == complexBaseType->contentType()->simpleType()) {
                        validContentType = true; // 1.4.1
                    }
                } else if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
                    validContentType = true; // 1.4.2
                } else { // 1.4.3
                    if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { // 1.4.3.1
                        if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
                            validContentType = true; // 1.4.3.2.1
                        } else { // 1.4.3.2.2
                            if (complexType->contentType()->particle()) {  // our own check
                                if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) ||
                                           (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {  // 1.4.3.2.2.1
                                    if (isValidParticleExtension(complexType->contentType()->particle(), complexBaseType->contentType()->particle())) {
                                        validContentType = true; // 1.4.3.2.2.2
                                    }
                                }
                            }
                            // 1.4.3.2.2.3  and 1.4.3.2.2.4 handle 'open content' that we do not support yet
                        }
                    }
                }

                // 1.5 WTF?!?

                if (!validContentType) {
                    m_context->error(QtXmlPatterns::tr("Content model of complex type %1 is not a valid extension of content model of %2.")
                                                      .arg(formatType(m_namePool, complexType))
                                                      .arg(formatType(m_namePool, complexBaseType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

            } else if (baseType->isSimpleType()) {
                // 2.1
                if (complexType->contentType()->variety() != XsdComplexType::ContentType::Simple) {
                    m_context->error(QtXmlPatterns::tr("Complex type %1 must have simple content.")
                                                      .arg(formatType(m_namePool, complexType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                if (complexType->contentType()->simpleType() != baseType) {
                    m_context->error(QtXmlPatterns::tr("Complex type %1 must have the same simple type as its base class %2.")
                                                      .arg(formatType(m_namePool, complexType))
                                                      .arg(formatType(m_namePool, baseType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                // 2.2 tested in checkInheritanceRestrictions() already
            }
        } else if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
            // @see http://www.w3.org/TR/xmlschema11-1/#d0e21402
            const SchemaType::Ptr baseType(complexType->wxsSuperType());

            bool derivationOk = false;
            QString errorMsg;

            // we can partly skip 1 here, as it is tested in checkInheritanceRestrictions() already
            if (baseType->isComplexType()) {

                // 2.1
                if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
                    derivationOk = true;
                }

                if (baseType->isDefinedBySchema()) {
                    const XsdComplexType::Ptr complexBaseType(baseType);

                    // 2.2.1
                    if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
                        // 2.2.2.1
                        if (XsdSchemaHelper::isSimpleDerivationOk(complexType->contentType()->simpleType(), complexBaseType->contentType()->simpleType(), SchemaType::DerivationConstraints()))
                            derivationOk = true;

                        // 2.2.2.2
                        if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
                            if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
                                derivationOk = true;
                        }
                    }

                    // 2.3.1
                    if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
                        // 2.3.2.1
                        if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty)
                            derivationOk = true;

                        // 2.3.2.2
                        if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
                            if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
                                derivationOk = true;
                        }
                    }

                    // 2.4.1.1
                    if (((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) &&
                         (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) ||
                        // 2.4.1.2
                        (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {

                        // 2.4.2
                        if (XsdParticleChecker::subsumes(complexBaseType->contentType()->particle(), complexType->contentType()->particle(), m_context, errorMsg))
                            derivationOk = true;
                    }
                }
            }

            if (!derivationOk) {
                m_context->error(QtXmlPatterns::tr("Complex type %1 cannot be derived from base type %2%3.")
                                                  .arg(formatType(m_namePool, complexType))
                                                  .arg(formatType(m_namePool, baseType))
                                                  .arg(errorMsg.isEmpty() ? QString() : QLatin1String(": ") + errorMsg),
                                 XsdSchemaContext::XSDError, location);
                return;
            }

            if (baseType->isDefinedBySchema()) {
                const XsdComplexType::Ptr complexBaseType(baseType);

                QString errorMsg;
                if (!XsdSchemaHelper::isValidAttributeUsesRestriction(complexType->attributeUses(), complexBaseType->attributeUses(),
                                                                      complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
                    m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3.")
                                                      .arg(formatType(m_namePool, complexType))
                                                      .arg(formatType(m_namePool, baseType))
                                                      .arg(errorMsg),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }
            }
        }

        // check that complex type with simple content is not allowed to inherit from
        // built in complex type xs:AnyType
        if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
            if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
                m_context->error(QtXmlPatterns::tr("Complex type %1 with simple content cannot be derived from complex base type %2.")
                                                  .arg(formatType(m_namePool, complexType))
                                                  .arg(formatType(m_namePool, baseType)),
                                 XsdSchemaContext::XSDError, location);
                return;
            }
        }
    }
}

void XsdSchemaChecker::checkSimpleDerivationRestrictions()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);

        if (type->isComplexType())
            continue;

        if (type->category() != SchemaType::SimpleTypeList && type->category() != SchemaType::SimpleTypeUnion)
            continue;

        const XsdSimpleType::Ptr simpleType = type;
        const QSourceLocation location = sourceLocation(simpleType);

        // check all simple types derived by list
        if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
            const AnySimpleType::Ptr itemType = simpleType->itemType();

            if (itemType->isComplexType()) {
                m_context->error(QtXmlPatterns::tr("Item type of simple type %1 cannot be a complex type.")
                                                  .arg(formatType(m_namePool, simpleType)),
                                 XsdSchemaContext::XSDError, location);
                return;
            }


            if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
                const XsdSimpleType::Ptr simpleItemType = itemType;
                if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
                    m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
                                                      .arg(formatType(m_namePool, simpleType))
                                                      .arg(formatType(m_namePool, simpleItemType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }
            }

            // @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
            if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
                m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
                return;
            }

            if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
                const XsdSimpleType::Ptr simpleItemType = itemType;
                const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
                for (int j = 0; j < memberTypes.count(); ++j) {
                    if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic && memberTypes.at(j)->category() != SchemaType::SimpleTypeUnion) {
                        m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic or union.").arg(formatType(m_namePool, simpleItemType)),
                                         XsdSchemaContext::XSDError, location);
                        return;
                    }
                }
            }
        }

        // check all simple types derived by union
        if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
            const AnySimpleType::List memberTypes = simpleType->memberTypes();

            for (int i = 0; i < memberTypes.count(); ++i) {
                const AnySimpleType::Ptr memberType = memberTypes.at(i);

                if (memberType->isComplexType()) {
                    m_context->error(QtXmlPatterns::tr("Member type of simple type %1 cannot be a complex type.")
                                                      .arg(formatType(m_namePool, simpleType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                // @see http://www.w3.org/TR/xmlschema-2/#cos-no-circular-unions
                if (simpleType->name(m_namePool) == memberType->name(m_namePool)) {
                    m_context->error(QtXmlPatterns::tr("%1 is not allowed to have a member type with the same name as itself.")
                                                      .arg(formatType(m_namePool, simpleType)),
                                     XsdSchemaContext::XSDError, location);
                    return;
                }

                if (memberType->isSimpleType() && memberType->isDefinedBySchema()) {
                    const XsdSimpleType::Ptr simpleMemberType = memberType;
                    if (simpleMemberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
                        m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
                                                          .arg(formatType(m_namePool, simpleType))
                                                          .arg(formatType(m_namePool, simpleMemberType)),
                                         XsdSchemaContext::XSDError, location);
                        return;
                    }
                }
            }
        }
    }
}

void XsdSchemaChecker::checkConstrainingFacets()
{
    // first the global simple types
    const SchemaType::List types = m_schema->types();
    for (int i = 0; i < types.count(); ++i) {
        if (!(types.at(i)->isSimpleType()) || !(types.at(i)->isDefinedBySchema()))
            continue;

        const XsdSimpleType::Ptr simpleType = types.at(i);
        checkConstrainingFacets(simpleType->facets(), simpleType);
    }

    // and afterwards all anonymous simple types
    const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
    for (int i = 0; i < anonymousTypes.count(); ++i) {
        if (!(anonymousTypes.at(i)->isSimpleType()) || !(anonymousTypes.at(i)->isDefinedBySchema()))
            continue;

        const XsdSimpleType::Ptr simpleType = anonymousTypes.at(i);
        checkConstrainingFacets(simpleType->facets(), simpleType);
    }
}

void XsdSchemaChecker::checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType)
{
    if (facets.isEmpty())
        return;

    SchemaType::Ptr comparableBaseType;
    if (!simpleType->wxsSuperType()->isDefinedBySchema())
        comparableBaseType = simpleType->wxsSuperType();
    else
        comparableBaseType = simpleType->primitiveType();

    const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));

    // start checks
    if (facets.contains(XsdFacet::Length)) {
        const XsdFacet::Ptr lengthFacet = facets.value(XsdFacet::Length);
        const DerivedInteger<TypeNonNegativeInteger>::Ptr lengthValue = lengthFacet->value();

        // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
        if (facets.contains(XsdFacet::MinimumLength)) {
            const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
            const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();

            bool foundSuperMinimumLength = false;
            SchemaType::Ptr baseType = simpleType->wxsSuperType();
            while (baseType) {
                const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
                if (baseFacets.contains(XsdFacet::MinimumLength) && !baseFacets.contains(XsdFacet::Length)) {
                    const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MinimumLength)->value());
                    if (minLengthValue->toInteger() == superValue->toInteger()) {
                        foundSuperMinimumLength = true;
                        break;
                    }
                }

                baseType = baseType->wxsSuperType();
            }

            if ((minLengthValue->toInteger() > lengthValue->toInteger()) || !foundSuperMinimumLength) {
                m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
                                                  .arg(formatKeyword("length"))
                                                  .arg(formatKeyword("minLength")),
                                 XsdSchemaContext::XSDError, sourceLocation(simpleType));
                return;
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
        if (facets.contains(XsdFacet::MaximumLength)) {
            const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
            const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();

            bool foundSuperMaximumLength = false;
            SchemaType::Ptr baseType = simpleType->wxsSuperType();
            while (baseType) {
                const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
                if (baseFacets.contains(XsdFacet::MaximumLength) && !baseFacets.contains(XsdFacet::Length)) {
                    const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MaximumLength)->value());
                    if (maxLengthValue->toInteger() == superValue->toInteger()) {
                        foundSuperMaximumLength = true;
                        break;
                    }
                }

                baseType = baseType->wxsSuperType();
            }

            if ((maxLengthValue->toInteger() < lengthValue->toInteger()) || !foundSuperMaximumLength) {
                m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
                                                  .arg(formatKeyword("length"))
                                                  .arg(formatKeyword("maxLength")),
                                 XsdSchemaContext::XSDError, sourceLocation(simpleType));
                return;
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#length-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::Length)) {
                const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::Length)->value();
                if (lengthValue->toInteger() != baseValue->toInteger()) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must have the same value as %2 facet of base type.")
                                                      .arg(formatKeyword("length"))
                                                      .arg(formatKeyword("length")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }

    if (facets.contains(XsdFacet::MinimumLength)) {
        const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
        const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();

        if (facets.contains(XsdFacet::MaximumLength)) {
            const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
            const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();

            // @see http://www.w3.org/TR/xmlschema-2/#minLength-less-than-equal-to-maxLength
            if (maxLengthValue->toInteger() < minLengthValue->toInteger()) {
                m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
                                                  .arg(formatKeyword("minLength"))
                                                  .arg(formatKeyword("maxLength")),
                                 XsdSchemaContext::XSDError, sourceLocation(simpleType));
                return;
            }

            // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
            //TODO: check parent facets
        }

        // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::MinimumLength)) {
                const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::MinimumLength)->value();
                if (minLengthValue->toInteger() < baseValue->toInteger()) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be equal or greater than %2 facet of base type.")
                                                      .arg(formatKeyword("minLength"))
                                                      .arg(formatKeyword("minLength")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }
    if (facets.contains(XsdFacet::MaximumLength)) {
        const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
        const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();

        // @see http://www.w3.org/TR/xmlschema-2/#maxLength-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::MaximumLength)) {
                const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue(baseFacets.value(XsdFacet::MaximumLength)->value());
                if (maxLengthValue->toInteger() > baseValue->toInteger()) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                      .arg(formatKeyword("maxLength"))
                                                      .arg(formatKeyword("maxLength")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }
    if (facets.contains(XsdFacet::Pattern)) {
        //  we keep the patterns in separated facets
        // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-patterns

        // @see http://www.w3.org/TR/xmlschema-2/#cvc-pattern-valid
        const XsdFacet::Ptr patternFacet = facets.value(XsdFacet::Pattern);
        const AtomicValue::List multiValue = patternFacet->multiValue();

        for (int i = 0; i < multiValue.count(); ++i) {
            const DerivedString<TypeString>::Ptr value = multiValue.at(i);
            QRegExp exp = PatternPlatform::parsePattern(value->stringValue(), m_context, &reflection);
            if (!exp.isValid()) {
                m_context->error(QtXmlPatterns::tr("%1 facet contains invalid regular expression").arg(formatKeyword("pattern.")), XsdSchemaContext::XSDError, sourceLocation(simpleType));
                return;
            }
        }
    }
    if (facets.contains(XsdFacet::Enumeration)) {
        // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-enumerations

        const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);

        if (BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) {
            const AtomicValue::List notationNames = facet->multiValue();
            for (int k = 0; k < notationNames.count(); ++k) {
                const QNameValue::Ptr notationName = notationNames.at(k);
                if (!m_schema->notation(notationName->qName())) {
                    m_context->error(QtXmlPatterns::tr("Unknown notation %1 used in %2 facet.")
                                                      .arg(formatKeyword(m_namePool, notationName->qName()))
                                                      .arg(formatKeyword("enumeration")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                }
            }
        } else if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType)) {
        } else {
            const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(simpleType));

            const AnySimpleType::Ptr baseType = simpleType->wxsSuperType();
            const XsdFacet::Hash baseFacets = XsdTypeChecker::mergedFacetsForType(baseType, m_context);

            const AtomicValue::List multiValue = facet->multiValue();
            for (int k = 0; k < multiValue.count(); ++k) {
                const QString stringValue = multiValue.at(k)->as<DerivedString<TypeString> >()->stringValue();
                const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, baseFacets);

                QString errorMsg;
                if (!checker.isValidString(actualValue, baseType, errorMsg)) {
                    m_context->error(QtXmlPatterns::tr("%1 facet contains invalid value %2: %3.")
                                                      .arg(formatKeyword("enumeration"))
                                                      .arg(formatData(stringValue))
                                                      .arg(errorMsg),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }
    if (facets.contains(XsdFacet::WhiteSpace)) {
        const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace);
        const DerivedString<TypeString>::Ptr whiteSpaceValue = whiteSpaceFacet->value();

        // @see http://www.w3.org/TR/xmlschema-2/#whiteSpace-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::WhiteSpace)) {
                const QString value = whiteSpaceValue->stringValue();
                const QString baseValue = DerivedString<TypeString>::Ptr(baseFacets.value(XsdFacet::WhiteSpace)->value())->stringValue();
                if (value == XsdSchemaToken::toString(XsdSchemaToken::Replace) || value == XsdSchemaToken::toString(XsdSchemaToken::Preserve)) {
                    if (baseValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 or %3 if %4 facet of base type is %5.")
                                                          .arg(formatKeyword("whiteSpace"))
                                                          .arg(formatData("replace"))
                                                          .arg(formatData("preserve"))
                                                          .arg(formatKeyword("whiteSpace"))
                                                          .arg(formatData("collapse")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
                if (value == XsdSchemaToken::toString(XsdSchemaToken::Preserve) && baseValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
                    m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 if %3 facet of base type is %4.")
                                                      .arg(formatKeyword("whiteSpace"))
                                                      .arg(formatData("preserve"))
                                                      .arg(formatKeyword("whiteSpace"))
                                                      .arg(formatData("replace")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }
    if (facets.contains(XsdFacet::MaximumInclusive)) {
        const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);

        // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-equal-to-maxInclusive
        if (facets.contains(XsdFacet::MinimumInclusive)) {
            const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);

            if (comparableBaseType) {
                if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
                                                      .arg(formatKeyword("minInclusive"))
                                                      .arg(formatKeyword("maxInclusive")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("maxInclusive"))
                                                          .arg(formatKeyword("maxInclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
                                                          .arg(formatKeyword("maxInclusive"))
                                                          .arg(formatKeyword("maxExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
        }
    }
    if (facets.contains(XsdFacet::MaximumExclusive)) {
        const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);

        // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-maxExclusive
        if (facets.contains(XsdFacet::MaximumInclusive)) {
            m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
                                              .arg(formatKeyword("maxExclusive"))
                                              .arg(formatKeyword("maxInclusive")),
                             XsdSchemaContext::XSDError, sourceLocation(simpleType));
            return;
        }

        // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-equal-to-maxExclusive
        if (facets.contains(XsdFacet::MinimumExclusive)) {
            const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
            if (comparableBaseType) {
                if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
                                                      .arg(formatKeyword("minExclusive"))
                                                      .arg(formatKeyword("maxExclusive")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#maxExclusive-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("maxExclusive"))
                                                          .arg(formatKeyword("maxExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("maxExclusive"))
                                                          .arg(formatKeyword("maxInclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
                                                          .arg(formatKeyword("maxExclusive"))
                                                          .arg(formatKeyword("minInclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
                                                          .arg(formatKeyword("maxExclusive"))
                                                          .arg(formatKeyword("minExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
        }
    }
    if (facets.contains(XsdFacet::MinimumExclusive)) {
        const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);

        // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-minExclusive
        if (facets.contains(XsdFacet::MinimumInclusive)) {
            m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
                                              .arg(formatKeyword("minExclusive"))
                                              .arg(formatKeyword("minInclusive")),
                             XsdSchemaContext::XSDError, sourceLocation(simpleType));
            return;
        }

        // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-maxInclusive
        if (facets.contains(XsdFacet::MaximumInclusive)) {
            const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
            if (comparableBaseType) {
                if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
                                                      .arg(formatKeyword("minExclusive"))
                                                      .arg(formatKeyword("maxInclusive")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("minExclusive"))
                                                          .arg(formatKeyword("minExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
                                                          .arg(formatKeyword("minExclusive"))
                                                          .arg(formatKeyword("maxExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("minExclusive"))
                                                          .arg(formatKeyword("maxInclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
        }
    }
    if (facets.contains(XsdFacet::MinimumInclusive)) {
        const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);

        // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-maxExclusive
        if (facets.contains(XsdFacet::MaximumExclusive)) {
            const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
            if (comparableBaseType) {
                if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
                                                      .arg(formatKeyword("minInclusive"))
                                                      .arg(formatKeyword("maxExclusive")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("minInclusive"))
                                                          .arg(formatKeyword("minInclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
                                                          .arg(formatKeyword("minInclusive"))
                                                          .arg(formatKeyword("minExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                          .arg(formatKeyword("minInclusive"))
                                                          .arg(formatKeyword("maxInclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
            if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
                if (comparableBaseType) {
                    if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
                        m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
                                                          .arg(formatKeyword("minInclusive"))
                                                          .arg(formatKeyword("maxExclusive")),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
        }
    }
    if (facets.contains(XsdFacet::TotalDigits)) {
        const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
        const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();

        // @see http://www.w3.org/TR/xmlschema-2/#totalDigits-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::TotalDigits)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::TotalDigits);
                const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();

                if (totalDigitsValue->toInteger() > baseValue->toInteger()) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                      .arg(formatKeyword("totalDigits"))
                                                      .arg(formatKeyword("totalDigits")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }
    if (facets.contains(XsdFacet::FractionDigits)) {
        const XsdFacet::Ptr fractionDigitsFacet = facets.value(XsdFacet::FractionDigits);
        const DerivedInteger<TypeNonNegativeInteger>::Ptr fractionDigitsValue = fractionDigitsFacet->value();

        // http://www.w3.org/TR/xmlschema-2/#fractionDigits-totalDigits
        if (facets.contains(XsdFacet::TotalDigits)) {
            const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
            const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();

            if (fractionDigitsValue->toInteger() > totalDigitsValue->toInteger()) {
                m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
                                                  .arg(formatKeyword("fractionDigits"))
                                                  .arg(formatKeyword("totalDigits")),
                                 XsdSchemaContext::XSDError, sourceLocation(simpleType));
                return;
            }
        }

        // @see http://www.w3.org/TR/xmlschema-2/#fractionDigits-valid-restriction
        if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
            const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
            if (baseFacets.contains(XsdFacet::FractionDigits)) {
                const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::FractionDigits);
                const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();

                if (fractionDigitsValue->toInteger() > baseValue->toInteger()) {
                    m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
                                                      .arg(formatKeyword("fractionDigits"))
                                                      .arg(formatKeyword("fractionDigits")),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    }


    // check whether facets are allowed for simple types variety
    if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeAtomic) {
        if (simpleType->primitiveType()) {
            const QXmlName primitiveTypeName = simpleType->primitiveType()->name(m_namePool);
            if (m_allowedAtomicFacets.contains(primitiveTypeName)) {
                const QSet<XsdFacet::Type> allowedFacets = m_allowedAtomicFacets.value(primitiveTypeName);

                QSet<XsdFacet::Type> availableFacets;
                for (auto it = facets.cbegin(), end = facets.cend(); it != end; ++it)
                    availableFacets.insert(it.key());

                if (!availableFacets.subtract(allowedFacets).isEmpty()) {
                    m_context->error(QtXmlPatterns::tr("Simple type contains not allowed facet %1.")
                                                      .arg(formatKeyword(XsdFacet::typeName(availableFacets.values().constFirst()))),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }
        }
    } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeList) {
        if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) ||
            facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) ||
            facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits))
        {
            m_context->error(QtXmlPatterns::tr("%1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list.")
                                              .arg(formatKeyword("maxInclusive"))
                                              .arg(formatKeyword("maxExclusive"))
                                              .arg(formatKeyword("minInclusive"))
                                              .arg(formatKeyword("minExclusive"))
                                              .arg(formatKeyword("totalDigits"))
                                              .arg(formatKeyword("fractionDigits")),
                             XsdSchemaContext::XSDError, sourceLocation(simpleType));
        }
    } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeUnion) {
        if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) ||
            facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) ||
            facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits) ||
            facets.contains(XsdFacet::MinimumLength) || facets.contains(XsdFacet::MaximumLength) ||
            facets.contains(XsdFacet::Length) || facets.contains(XsdFacet::WhiteSpace))
        {
            m_context->error(QtXmlPatterns::tr("Only %1 and %2 facets are allowed when derived by union.")
                                              .arg(formatKeyword("pattern"))
                                              .arg(formatKeyword("enumeration")),
                             XsdSchemaContext::XSDError, sourceLocation(simpleType));
        }
    }

    // check whether value of facet matches the value space of the simple types base type
    const SchemaType::Ptr baseType = simpleType->wxsSuperType();
    if (!baseType->isDefinedBySchema()) {
        const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));

        for (auto it = facets.cbegin(), end = facets.cend(); it != end; ++it) {
            const XsdFacet::Ptr facet = it.value();
            if (facet->type() == XsdFacet::MaximumInclusive ||
                facet->type() == XsdFacet::MaximumExclusive ||
                facet->type() == XsdFacet::MinimumInclusive ||
                facet->type() == XsdFacet::MinimumExclusive) {
                const DerivedString<TypeString>::Ptr stringValue = facet->value();
                const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue->stringValue(), baseType, m_context, &reflection);
                if (value->hasError()) {
                    m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
                                                      .arg(formatType(m_namePool, simpleType))
                                                      .arg(formatKeyword(XsdFacet::typeName(facet->type())))
                                                      .arg(formatData(stringValue->stringValue())),
                                     XsdSchemaContext::XSDError, sourceLocation(simpleType));
                    return;
                }
            }

            // @see http://www.w3.org/TR/xmlschema-2/#enumeration-valid-restriction
            if (facet->type() == XsdFacet::Enumeration && baseType != BuiltinTypes::xsNOTATION) {
                const AtomicValue::List multiValue = facet->multiValue();
                for (int j = 0; j < multiValue.count(); ++j) {
                    const QString stringValue = DerivedString<TypeString>::Ptr(multiValue.at(j))->stringValue();
                    const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue, baseType, m_context, &reflection);
                    if (value->hasError()) {
                        m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
                                                          .arg(formatType(m_namePool, simpleType))
                                                          .arg(formatKeyword(XsdFacet::typeName(XsdFacet::Enumeration)))
                                                          .arg(formatData(stringValue)),
                                         XsdSchemaContext::XSDError, sourceLocation(simpleType));
                        return;
                    }
                }
            }
        }
    }
}

void XsdSchemaChecker::checkDuplicatedAttributeUses()
{
    // first all global attribute groups
    const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups();
    for (int i = 0; i < attributeGroups.count(); ++i) {
        const XsdAttributeGroup::Ptr attributeGroup = attributeGroups.at(i);
        const XsdAttributeUse::List uses = attributeGroup->attributeUses();

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
        XsdAttribute::Ptr conflictingAttribute;
        if (hasDuplicatedAttributeUses(uses, conflictingAttribute)) {
            m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 twice.")
                                              .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
                                              .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
                             XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
            return;
        }

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
        if (hasMultipleIDAttributeUses(uses)) {
            m_context->error(QtXmlPatterns::tr("Attribute group %1 contains two different attributes that both have types derived from %2.")
                                              .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
                                              .arg(formatType(m_namePool, BuiltinTypes::xsID)),
                             XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
            return;
        }

        if (hasConstraintIDAttributeUse(uses, conflictingAttribute)) {
            m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3.")
                                              .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
                                              .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
                                              .arg(formatType(m_namePool, BuiltinTypes::xsID)),
                             XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
            return;
        }
    }

    // then the global and anonymous complex types
    SchemaType::List types = m_schema->types();
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
            continue;

        const XsdComplexType::Ptr complexType = types.at(i);
        const XsdAttributeUse::List attributeUses = complexType->attributeUses();

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
        XsdAttribute::Ptr conflictingAttribute;
        if (hasDuplicatedAttributeUses(attributeUses, conflictingAttribute)) {
            m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 twice.")
                                              .arg(formatType(m_namePool, complexType))
                                              .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
                             XsdSchemaContext::XSDError, sourceLocation(complexType));
            return;
        }

        // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
        if (hasMultipleIDAttributeUses(attributeUses)) {
            m_context->error(QtXmlPatterns::tr("Complex type %1 contains two different attributes that both have types derived from %2.")
                                              .arg(formatType(m_namePool, complexType))
                                              .arg(formatType(m_namePool, BuiltinTypes::xsID)),
                             XsdSchemaContext::XSDError, sourceLocation(complexType));
            return;
        }

        if (hasConstraintIDAttributeUse(attributeUses, conflictingAttribute)) {
            m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3.")
                                              .arg(formatType(m_namePool, complexType))
                                              .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
                                              .arg(formatType(m_namePool, BuiltinTypes::xsID)),
                             XsdSchemaContext::XSDError, sourceLocation(complexType));
            return;
        }
    }
}

void XsdSchemaChecker::checkElementConstraints()
{
    const QSet<XsdElement::Ptr> elements = collectAllElements(m_schema);

    for (const XsdElement::Ptr &element : elements) {

        // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct

        // 2 and xs:ID check
        if (element->valueConstraint()) {
            const SchemaType::Ptr type = element->type();

            AnySimpleType::Ptr targetType;
            if (type->isSimpleType() && type->category() == SchemaType::SimpleTypeAtomic) {
                targetType = type;

                // if it is a XsdSimpleType, use its primitive type as target type
                if (type->isDefinedBySchema())
                    targetType = XsdSimpleType::Ptr(type)->primitiveType();

            } else if (type->isComplexType() && type->isDefinedBySchema()) {
                const XsdComplexType::Ptr complexType(type);

                if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
                    const AnySimpleType::Ptr simpleType = complexType->contentType()->simpleType();
                    if (simpleType->category() == AnySimpleType::SimpleTypeAtomic) {
                        targetType = simpleType;

                        if (simpleType->isDefinedBySchema())
                            targetType = XsdSimpleType::Ptr(simpleType)->primitiveType();
                    }
                } else if (complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) {
                    m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its base type is complex.")
                                                      .arg(formatKeyword(element->displayName(m_namePool))),
                                     XsdSchemaContext::XSDError, sourceLocation(element));
                    return;
                }
            }
            if ((targetType == BuiltinTypes::xsID) || BuiltinTypes::xsID->wxsTypeMatches(type)) {
                m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its type is derived from %2.")
                                                  .arg(formatKeyword(element->displayName(m_namePool)))
                                                  .arg(formatType(m_namePool, BuiltinTypes::xsID)),
                                 XsdSchemaContext::XSDError, sourceLocation(element));
                return;
            }

            if (type->isSimpleType()) {
                QString errorMsg;
                if (!isValidValue(element->valueConstraint()->value(), type, errorMsg)) {
                    m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
                                                      .arg(formatKeyword(element->displayName(m_namePool)))
                                                      .arg(errorMsg),
                                     XsdSchemaContext::XSDError, sourceLocation(element));
                    return;
                }
            } else if (type->isComplexType() && type->isDefinedBySchema()) {
                const XsdComplexType::Ptr complexType(type);
                if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
                    QString errorMsg;
                    if (!isValidValue(element->valueConstraint()->value(), complexType->contentType()->simpleType(), errorMsg)) {
                        m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
                                                          .arg(formatKeyword(element->displayName(m_namePool)))
                                                          .arg(errorMsg),
                                         XsdSchemaContext::XSDError, sourceLocation(element));
                        return;
                    }
                }
            }
        }

        if (!element->substitutionGroupAffiliations().isEmpty()) {
            // 3
            if (!element->scope() || element->scope()->variety() != XsdElement::Scope::Global) {
                m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have substitution group affiliation as it is no global element.").arg(formatKeyword(element->displayName(m_namePool))),
                                 XsdSchemaContext::XSDError, sourceLocation(element));
                return;
            }

            // 4
            const XsdElement::List affiliations = element->substitutionGroupAffiliations();
            for (int i = 0; i < affiliations.count(); ++i) {
                const XsdElement::Ptr affiliation = affiliations.at(i);

                bool derivationOk = false;
                if (element->type()->isComplexType() && affiliation->type()->isComplexType()) {
                    if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
                        derivationOk = true;
                    }
                }
                if (element->type()->isComplexType() && affiliation->type()->isSimpleType()) {
                    if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
                        derivationOk = true;
                    }
                }
                if (element->type()->isSimpleType()) {
                    if (XsdSchemaHelper::isSimpleDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
                        derivationOk = true;
                    }
                }

                if (!derivationOk) {
                    m_context->error(QtXmlPatterns::tr("Type of element %1 cannot be derived from type of substitution group affiliation.").arg(formatKeyword(element->displayName(m_namePool))),
                                     XsdSchemaContext::XSDError, sourceLocation(element));
                    return;
                }
            }

            // 5 was checked in XsdSchemaResolver::resolveSubstitutionGroupAffiliations() already
        }
    }
}

void XsdSchemaChecker::checkAttributeConstraints()
{
    // all global attributes
    XsdAttribute::List attributes = m_schema->attributes();

    // and all local attributes
    SchemaType::List types = m_schema->types();
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        if (!types.at(i)->isComplexType() || !types.at(i)->isDefinedBySchema())
            continue;

        const XsdComplexType::Ptr complexType(types.at(i));
        const XsdAttributeUse::List uses = complexType->attributeUses();
        for (int j = 0; j < uses.count(); ++j)
            attributes.append(uses.at(j)->attribute());
    }

    for (int i = 0; i < attributes.count(); ++i) {
        const XsdAttribute::Ptr attribute = attributes.at(i);

        if (!attribute->valueConstraint())
            continue;

        if (attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Default || attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
            const SchemaType::Ptr type = attribute->type();

            QString errorMsg;
            if (!isValidValue(attribute->valueConstraint()->value(), attribute->type(), errorMsg)) {
                m_context->error(QtXmlPatterns::tr("Value constraint of attribute %1 is not of attributes type: %2.")
                                                  .arg(formatKeyword(attribute->displayName(m_namePool)))
                                                  .arg(errorMsg),
                                 XsdSchemaContext::XSDError, sourceLocation(attribute));
                return;
            }
        }

        if (BuiltinTypes::xsID->wxsTypeMatches(attribute->type())) {
            m_context->error(QtXmlPatterns::tr("Attribute %1 has value constraint but has type derived from %2.")
                                              .arg(formatKeyword(attribute->displayName(m_namePool)))
                                              .arg(formatType(m_namePool, BuiltinTypes::xsID)),
                             XsdSchemaContext::XSDError, sourceLocation(attribute));
            return;
        }
    }
}

bool XsdSchemaChecker::isValidValue(const QString &stringValue, const AnySimpleType::Ptr &type, QString &errorMsg) const
{
    if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool))
        return true; // no need to check xs:anyType content

    const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
    const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, facets);

    const XsdTypeChecker checker(m_context, QVector<QXmlName>(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1));
    return checker.isValidString(actualValue, type, errorMsg);
}

void XsdSchemaChecker::checkAttributeUseConstraints()
{
    XsdComplexType::List complexTypes;

    SchemaType::List types = m_schema->types();
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);
        if (type->isComplexType() && type->isDefinedBySchema())
            complexTypes.append(XsdComplexType::Ptr(type));
    }

    for (int i = 0; i < complexTypes.count(); ++i) {
        const XsdComplexType::Ptr complexType(complexTypes.at(i));
        const SchemaType::Ptr baseType = complexType->wxsSuperType();
        if (!baseType || !baseType->isComplexType() || !baseType->isDefinedBySchema())
            continue;

        const XsdComplexType::Ptr complexBaseType(baseType);

        const XsdAttributeUse::List attributeUses = complexType->attributeUses();
        QHash<QXmlName, XsdAttributeUse::Ptr> lookupHash;
        for (int j = 0; j < attributeUses.count(); ++j)
            lookupHash.insert(attributeUses.at(j)->attribute()->name(m_namePool), attributeUses.at(j));

        const XsdAttributeUse::List baseAttributeUses = complexBaseType->attributeUses();
        for (int j = 0; j < baseAttributeUses.count(); ++j) {
            const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(j);

            if (lookupHash.contains(baseAttributeUse->attribute()->name(m_namePool))) {
                const XsdAttributeUse::Ptr attributeUse = lookupHash.value(baseAttributeUse->attribute()->name(m_namePool));

                if (baseAttributeUse->useType() == XsdAttributeUse::RequiredUse) {
                    if (attributeUse->useType() == XsdAttributeUse::OptionalUse || attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
                        m_context->error(QtXmlPatterns::tr("%1 attribute in derived complex type must be %2 like in base type.")
                                                          .arg(formatAttribute("use"))
                                                          .arg(formatData("required")),
                                         XsdSchemaContext::XSDError, sourceLocation(complexType));
                        return;
                    }
                }

                if (baseAttributeUse->valueConstraint()) {
                    if (baseAttributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
                        if (!attributeUse->valueConstraint()) {
                            m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint like in base type.")
                                                              .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
                                                              .arg(formatData("fixed")),
                                             XsdSchemaContext::XSDError, sourceLocation(complexType));
                            return;
                        } else {
                            if (attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
                                const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(complexType));
                                if (!checker.valuesAreEqual(attributeUse->valueConstraint()->value(), baseAttributeUse->valueConstraint()->value(), attributeUse->attribute()->type())) {
                                    m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have the same %2 value constraint like in base type.")
                                                                      .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
                                                                      .arg(formatData("fixed")),
                                                     XsdSchemaContext::XSDError, sourceLocation(complexType));
                                    return;
                                }
                            } else {
                                m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint.")
                                                                  .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
                                                                  .arg(formatData("fixed")),
                                                 XsdSchemaContext::XSDError, sourceLocation(complexType));
                                return;
                            }
                        }
                    }
                }
            }
        }

        // additional check that process content property of attribute wildcard in derived type is
        // not weaker than the wildcard in base type
        const XsdWildcard::Ptr baseWildcard(complexBaseType->attributeWildcard());
        const XsdWildcard::Ptr derivedWildcard(complexType->attributeWildcard());
        if (baseWildcard && derivedWildcard) {
            if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, derivedWildcard)) {
                m_context->error(QtXmlPatterns::tr("processContent of base wildcard must be weaker than derived wildcard."), XsdSchemaContext::XSDError, sourceLocation(complexType));
                return;
            }
        }
    }
}

void XsdSchemaChecker::checkElementDuplicates()
{
    // check all global types...
    SchemaType::List types = m_schema->types();

    // .. and anonymous types
    types << m_schema->anonymousTypes();

    for (int i = 0; i < types.count(); ++i) {
        const SchemaType::Ptr type = types.at(i);

        if (!type->isComplexType() || !type->isDefinedBySchema())
            continue;

        const XsdComplexType::Ptr complexType(type);

        if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) || (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
            DuplicatedElementMap elementMap;
            DuplicatedWildcardMap wildcardMap;

            checkElementDuplicates(complexType->contentType()->particle(), elementMap, wildcardMap);
        }
    }
}

void XsdSchemaChecker::checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap)
{
    if (particle->term()->isElement()) {
        const XsdElement::Ptr element(particle->term());

        if (elementMap.contains(element->name(m_namePool))) {
            if (element->type() != elementMap.value(element->name(m_namePool))) {
                m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
                                                  .arg(formatKeyword(element->displayName(m_namePool))),
                                 XsdSchemaContext::XSDError, sourceLocation(element));
                return;
            }
        } else {
            elementMap.insert(element->name(m_namePool), element->type());
        }

        // check substitution group affiliation
        const XsdElement::List substElements = element->substitutionGroupAffiliations();
        for (int i = 0; i < substElements.count(); ++i) {
            const XsdElement::Ptr substElement = substElements.at(i);
            if (elementMap.contains(substElement->name(m_namePool))) {
                if (substElement->type() != elementMap.value(substElement->name(m_namePool))) {
                    m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
                                                      .arg(formatKeyword(substElement->displayName(m_namePool))),
                                     XsdSchemaContext::XSDError, sourceLocation(element));
                    return;
                }
            } else {
                elementMap.insert(substElement->name(m_namePool), substElement->type());
            }
        }
    } else if (particle->term()->isModelGroup()) {
        const XsdModelGroup::Ptr group(particle->term());
        const XsdParticle::List particles = group->particles();
        for (int i = 0; i < particles.count(); ++i)
            checkElementDuplicates(particles.at(i), elementMap, wildcardMap);
    } else if (particle->term()->isWildcard()) {
        const XsdWildcard::Ptr wildcard(particle->term());

        bool error = false;
        if (!wildcardMap.contains(wildcard->namespaceConstraint()->variety())) {
            if (!wildcardMap.isEmpty())
                error = true;
        } else {
            const XsdWildcard::Ptr otherWildcard = wildcardMap.value(wildcard->namespaceConstraint()->variety());
            if ((wildcard->processContents() != otherWildcard->processContents()) || (wildcard->namespaceConstraint()->namespaces() != otherWildcard->namespaceConstraint()->namespaces()))
                error = true;
        }

        if (error) {
            m_context->error(QtXmlPatterns::tr("Particle contains non-deterministic wildcards."), XsdSchemaContext::XSDError, sourceLocation(wildcard));
            return;
        } else {
            wildcardMap.insert(wildcard->namespaceConstraint()->variety(), wildcard);
        }
    }
}

QSourceLocation XsdSchemaChecker::sourceLocation(const NamedSchemaComponent::Ptr &component) const
{
    if (m_componentLocationHash.contains(component)) {
        return m_componentLocationHash.value(component);
    } else {
        QSourceLocation location;
        location.setLine(1);
        location.setColumn(1);
        location.setUri(QString::fromLatin1("dummyUri"));

        return location;
    }
}

QSourceLocation XsdSchemaChecker::sourceLocationForType(const SchemaType::Ptr &type) const
{
    if (type->isSimpleType())
        return sourceLocation(XsdSimpleType::Ptr(type));
    else
        return sourceLocation(XsdComplexType::Ptr(type));
}

QT_END_NAMESPACE
