<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="https://getpsalm.org/schema/config"
    targetNamespace="https://getpsalm.org/schema/config"
    elementFormDefault="qualified"
>
    <xs:element name="psalm" type="PsalmType" />

    <xs:complexType name="PsalmType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="projectFiles" type="ProjectFilesType" minOccurs="1" maxOccurs="1" />
            <xs:element name="fileExtensions" type="FileExtensionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="mockClasses" type="MockClassesType" minOccurs="0" maxOccurs="1" />
            <xs:element name="stubs" type="StubsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="plugins" type="PluginsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="exitFunctions" type="ExitFunctionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="forbiddenFunctions" type="ExitFunctionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="issueHandlers" type="IssueHandlersType" minOccurs="0" maxOccurs="1" />
            <xs:element name="ignoreExceptions" type="ExceptionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="globals" type="GlobalsType" minOccurs="0" maxOccurs="1" />
        </xs:choice>

        <xs:attribute name="autoloader" type="xs:string" />
        <xs:attribute name="cacheDirectory" type="xs:string" />
        <xs:attribute name="errorBaseline" type="xs:string" />
        <xs:attribute name="maxStringLength" type="xs:string" />
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="serializer" type="xs:string" />

        <xs:attribute name="addParamDefaultToDocblockType" type="xs:boolean" default="false" />
        <xs:attribute name="allowCoercionFromStringToClassConst" type="xs:boolean" default="false" />
        <xs:attribute name="allowFileIncludes" type="xs:boolean" default="true" />
        <xs:attribute name="allowPhpStormGenerics" type="xs:boolean" default="false" />
        <xs:attribute name="allowStringToStandInForClass" type="xs:boolean" default="false" />
        <xs:attribute name="checkForThrowsDocblock" type="xs:boolean" default="false" />
        <xs:attribute name="checkForThrowsInGlobalScope" type="xs:boolean" default="false" />
        <xs:attribute name="ensureArrayIntOffsetsExist" type="xs:boolean" default="false" />
        <xs:attribute name="ensureArrayStringOffsetsExist" type="xs:boolean" default="false" />
        <xs:attribute name="findUnusedCode" type="xs:boolean" default="false" />
        <xs:attribute name="findUnusedVariablesAndParams" type="xs:boolean" default="false" />
        <xs:attribute name="forbidEcho" type="xs:boolean" default="false" />
        <xs:attribute name="hideExternalErrors" type="xs:boolean" default="false" />
        <xs:attribute name="hoistConstants" type="xs:boolean" default="false" />
        <xs:attribute name="ignoreInternalFunctionFalseReturn" type="xs:boolean" default="false" />
        <xs:attribute name="ignoreInternalFunctionNullReturn" type="xs:boolean" default="true" />
        <xs:attribute name="includePhpVersionsInErrorBaseline" type="xs:boolean" default="false" />
        <xs:attribute name="loadXdebugStub" type="xs:boolean">
            <xs:annotation>
                <xs:documentation xml:lang="en">
                    Default is runtime-specific: if not present, Psalm will only load the Xdebug stub if psalm has unloaded the extension.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="memoizeMethodCallResults" type="xs:boolean" default="false" />
        <xs:attribute name="parseSql" type="xs:boolean" default="false" />
        <xs:attribute name="rememberPropertyAssignmentsAfterCall" type="xs:boolean" default="true" />
        <xs:attribute name="requireVoidReturnType" type="xs:boolean" default="true" />
        <xs:attribute name="resolveFromConfigFile" type="xs:boolean" default="false" />
        <xs:attribute name="strictBinaryOperands" type="xs:boolean" default="false" />
        <xs:attribute name="throwExceptionOnError" type="xs:boolean" default="false" />
        <xs:attribute name="totallyTyped" type="xs:boolean" default="false" />
        <xs:attribute name="useAssertForType" type="xs:boolean" default="true" />
        <xs:attribute name="useDocblockTypes" type="xs:boolean" default="true" />
        <xs:attribute name="useDocblockPropertyTypes" type="xs:boolean" default="false" />
        <xs:attribute name="usePhpDocMethodsWithoutMagicCall" type="xs:boolean" default="false" />
    </xs:complexType>

    <xs:complexType name="ProjectFilesType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="ProjectDirectoryAttributeType" />
            <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
            <xs:element name="ignoreFiles" minOccurs="0" maxOccurs="1" type="IgnoreFilesType" />
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="NameAttributeType">
        <xs:attribute name="name" type="xs:string" use="required" />
    </xs:complexType>

    <xs:complexType name="IgnoreFilesType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
            <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:choice>

        <xs:attribute name="allowMissingFiles" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="ProjectDirectoryAttributeType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="ignoreTypeStats" type="xs:string" />
        <xs:attribute name="useStrictTypes" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="FileExtensionsType">
        <xs:sequence>
            <xs:element name="extension" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="name" type="xs:string" use="required" />
                    <xs:attribute name="scanner" type="xs:string" />
                    <xs:attribute name="checker" type="xs:string" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="MockClassesType">
        <xs:sequence>
            <xs:element name="class" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="ExceptionsType">
        <xs:sequence>
            <xs:element name="class" minOccurs="0" maxOccurs="unbounded" type="ExceptionType" />
            <xs:element name="classAndDescendants" minOccurs="0" maxOccurs="unbounded" type="ExceptionType" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="StubsType">
        <xs:sequence>
            <xs:element name="file" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="ExitFunctionsType">
        <xs:sequence>
            <xs:element name="function" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="PluginsType">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="plugin">
                <xs:complexType>
                    <xs:attribute name="filename" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
            <xs:element name="pluginClass">
                <xs:complexType>
                    <xs:sequence>
                        <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
                    </xs:sequence>
                    <xs:attribute name="class" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="IssueHandlersType">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="PluginIssue" type="PluginIssueHandlerType" minOccurs="0" />
            <xs:element name="AbstractInstantiation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ArgumentTypeCoercion" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="AssignmentToVoid" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="CircularReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ContinueOutsideLoop" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ConflictingReferenceConstraint" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedFunction" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedInterface" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedTrait" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DocblockTypeContradiction" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateArrayKey" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateFunction" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateClass" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="EmptyArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="FalseOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="FalsableReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ForbiddenCode" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ForbiddenEcho" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NoValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplementedParamTypeMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplementedReturnTypeMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplicitToStringCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpurePropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureStaticVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InaccessibleClassConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InaccessibleMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="InaccessibleProperty" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InterfaceInstantiation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InternalClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InternalMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="InternalProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidCatch" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidClone" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidParamDefault" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidDocblock" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidDocblockParamName" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidFalsableReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidGlobal" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidNullableReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidParent" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPassByReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPropertyAssignmentValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidScalarArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidScope" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidStaticInvocation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidStaticVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidStringClass" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidTemplateParam" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidThrow" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidToString" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificImplementedReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LoopInvalidation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MethodSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MethodSignatureMustOmitReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MisplacedRequiredParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MismatchingDocblockReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingClosureParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingClosureReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingConstructor" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingDependency" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingFile" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingImmutableAnnotation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingPropertyType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingDocblockType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingTemplateParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingThrowsDocblock" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayTypeCoercion" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedInferredReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedStringOffsetAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedTypeCoercion" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArgumentTypeCoercion" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="MixedReturnTypeCoercion" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedPropertyTypeCoercion" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="MoreSpecificReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MoreSpecificImplementedParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NoInterfaceProperties" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="NonStaticSelfCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullableReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="NullArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="NullPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="NullReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="OverriddenMethodAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="OverriddenPropertyAccess" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="ParadoxicalCondition" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ParentNotFound" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossibleRawObjectIteration" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalsePropertyAssignmentValue" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidPropertyAssignmentValue" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullPropertyAssignmentValue" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedIntArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedStringArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedGlobalVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PropertyNotSetInConstructor" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PropertyTypeCoercion" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="RawObjectIteration" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantCondition" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantConditionGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ReferenceConstraintViolation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ReservedWord" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="StringIncrement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedInput" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TraitMethodSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TooFewArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="TooManyArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="TooManyTemplateParams" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="TypeCoercion" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TypeDoesNotContainNull" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TypeDoesNotContainType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UncaughtThrowInGlobalScope" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedDocblockClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedFunction" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedInterface" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedInterfaceMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMagicMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMagicPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMagicPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedThisPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedThisPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedTrait" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedGlobalVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnimplementedAbstractMethod" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnimplementedInterfaceMethod" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UninitializedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UnrecognizedExpression" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnrecognizedStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnresolvableInclude" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnevaluatedCode" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnnecessaryVarAnnotation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedClosureParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedFunctionCall" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedMethodCall" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedPsalmSuppress" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedMethod" type="MethodIssueHandlerType" minOccurs="0" />
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="IssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="PluginIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
        <xs:attribute name="name" type="xs:string" use="required" />
    </xs:complexType>

    <xs:complexType name="MethodIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedMethod" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="FunctionIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedFunction" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="ArgumentIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedFunction" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="ClassIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedClass" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="PropertyIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedProperty" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="GlobalsType">
        <xs:sequence>
            <xs:element name="var" maxOccurs="unbounded" type="IdentifierType" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="IdentifierType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="type" type="xs:string" use="required" />
    </xs:complexType>

    <xs:complexType name="ExceptionType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="onlyGlobalScope" type="xs:string" />
    </xs:complexType>
</xs:schema>
