<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
    "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">

<module name="Checker">

    <!-- properties for JVM -->
    <property name="localeCountry" value="US"/>
    <property name="localeLanguage" value="en"/>
    <property name="charset" value="UTF-8"/>

    <!-- by default, everything flagged is a warning -->
    <property name="severity" value="warning"/>

    <!-- =========================================================================== -->
    <!-- =========================================================================== -->
    <!-- CHECKS THAT DO NOT REQUIRE WALKING THE PARSE TREE                           -->
    <!-- =========================================================================== -->
    <!-- =========================================================================== -->

    <!-- Checks that no tab characters in the source code; report only first instance. -->
    <module name="FileTabCharacter">
        <property name="fileExtensions" value="java, toy, txt"/>
        <property name="eachLine" value="false"/>
        <message key="containsTab" value="Line contains a tab character. Configure your editor to replace tabs with spaces."/>
        <message key="file.containsTab" value="File contains tab characters (this is the first occurrence). Configure your editor to replace tabs with spaces."/>
    </module>

    <!-- Checks that no file is more than 1500 lines long. -->
    <module name="FileLength">
        <property name="max" value="1500"/>
    </module>

    <module name="RegexpSingleline">
        <!-- <property name="fileExtensions" value ="java, txt, toy"/> -->
        <property name="fileExtensions" value ="toy"/>
        <property name="format" value="[^\x00-\x7F]"/>
        <property name="message" value="Line contains a non-ASCII character."/>
    </module>

    <!-- check for non printable characters (excluding Tab, CR, LF) -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]"/>
        <property name="message" value="Line contains either a non-printable or control character."/>
    </module>

    <!-- check for Rich Text Format (RTF) -->
    <module name="RegexpMultiline">
        <property name="fileExtensions" value="txt, java, toy"/>
        <property name="format" value="\A\{\\rtf1\\ansi\\ansicpg1252"/>
        <property name="message" value="This appears to be a Rich Text Format (RTF) file. Reconfigure your editor to save as an ASCII or UTF-8 text file."/>
    </module>

    <!-- Checks for byte order mark (BOM) that might be set by editor when saving Unicode. -->
    <module name="RegexpMultiline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="\A[\uFEFF\uFFEF]"/>
        <property name="message" value="This file appears to be setting the byte order mark (BOM)."/>
    </module>

<!-- Seems to flag too many .java files. Not sure why.
    <module name="NewlineAtEndOfFile">
        <property name="fileExtensions" value="java, xml, py"/>
        <property name="lineSeparator" value="lf_cr_crlf"/>
    </module>
-->

<!--
    <module name="Translation"/>
    <module name="UniqueProperties"/>
-->

    <!-- =========================================================================== -->
    <!-- BEGIN: PRINCETON COS 226 SPECIFIC CHECKS (mostly for header)                -->
    <!-- =========================================================================== -->

    <!-- header for .java and .toy files -->
    <module name="RegexpMultiline">
        <property name="fileExtensions" value="java, toy"/>
        <property name="format" 
                  value="\A[\uFEFF\uFFEF]? *\/\*{70,} *(\n|\r|\r\n) *\* *Name:.*(\n|\r|\r\n) *\* *NetID:.*(\n|\r|\r\n) *\* *Precept:.*(\n|\r|\r\n)( *\* *(\n|\r|\r\n))*( *\* *Partner Name:.*(\n|\r|\r\n) *\* *Partner NetID:.*(\n|\r|\r\n) *\* *Partner Precept:.*(\n|\r|\r\n) *\* *(\n|\r|\r\n))? *\* *Description:.*(\n|\r|\r\n)( *\*.*(\n|\r|\r\n))* *\*{70,}/ *(\n|\r|\r\n)"/>
        <!-- for exactly match
                  value="\A\/\*{78}(\n|\r|\r\n) \*  ?Name:.*(\n|\r|\r\n) \*  ?NetID:.*(\n|\r|\r\n) \*  ?Precept:.*(\n|\r|\r\n) \*\s*(\n|\r|\r\n)( \*  ?Partner Name:.*(\n|\r|\r\n) \*  ?Partner NetID:.*(\n|\r|\r\n) \*  ?Partner Precept:.*(\n|\r|\r\n) \*\s*(\n|\r|\r\n))? \*  ?Description:.*(\n|\r|\r\n)( \*.*(\n|\r|\r\n))* \*{78}/(\n|\r|\r\n)"/>
        -->
        <property name="message" value="Incorrect COS 226 header format. Please cut and paste from the template at https://goo.gl/KZ7Vfc."/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="1"/>
        <property name="ignoreCase" value="false"/>
    </module>

    <!-- header for readme.txt -->
    <module name="RegexpMultiline">
        <property name="fileExtensions" value="txt"/>
        <property name="format" 
                  value="\A[\uFEFF\uFFEF]? *\/\*{70,} *(\n|\r|\r\n) *\* *Name:.*(\n|\r|\r\n) *\* *NetID:.*(\n|\r|\r\n) *\* *Precept:.*(\n|\r|\r\n)( *\* *(\n|\r|\r\n))*( *\* *Partner Name:.*(\n|\r|\r\n) *\* *Partner NetID:.*(\n|\r|\r\n) *\* *Partner Precept:.*(\n|\r|\r\n) *\* *(\n|\r|\r\n))?( *\*.*(\n|\r|\r\n))* *\*{70,}/ *(\n|\r|\r\n)"/>
        <!-- for exact match
                  value="\A\/\*{78}(\n|\r|\r\n) \*  ?Name:.*(\n|\r|\r\n) \*  ?NetID:.*(\n|\r|\r\n) \*  ?Precept:.*(\n|\r|\r\n)( \*\s*(\n|\r|\r\n))*( \*  ?Partner Name:.*(\n|\r|\r\n) \*  ?Partner NetID:.*(\n|\r|\r\n) \*  ?Partner Precept:.*(\n|\r|\r\n) \*\s*(\n|\r|\r\n))?( \*.*(\n|\r|\r\n))* \*{78}/(\n|\r|\r\n)"/>
        -->
        <property name="message" value="Incorrect COS 226 header format. Please cut and paste from the template at https://goo.gl/KZ7Vfc."/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="1"/>
        <property name="ignoreCase" value="false"/>
    </module>

    <module name="RegexpMultiline">
        <property name="fileExtensions" value="java, toy"/>
        <property name="format"
                  value="^ *\* *(Partner|Partner Precept):.*(\n|\r|\r\n) *\* *Description:"/>
        <property name="message" value="There must be one line in the header between the Name/NetID/Precept information and the Description."/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="ignoreCase" value="false"/>
    </module>

    <!-- a helpful warning for students that copy the header the introcs booksite code -->
    <module name="RegexpMultiline">
        <property name="fileExtensions" value="java"/>
        <property name="format"
                  value="^ *\* *(Partner|Partner Precept):.*(\n|\r|\r\n)( *\* *(\n|\r|\r\n))* *\* *(Compilation:|Execution:Dependencies:)"/>
        <property name="message" value="If you include ''Compilation'', ''Execution'', and ''Dependencies'' comments in the header, they must appear after the ''Description'' comment."/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="ignoreCase" value="false"/>
    </module>

    <!-- check that the first non-whitespace character in each line of the header is an asterisk -->
    <!-- (except for the first line, which begins with /*) -->
    <module name="RegexpMultiline">
        <property name="fileExtensions" value="txt, java, toy"/>
        <property name="format" 
                  value="\A[\uFEFF\uFFEF]?\s*\/\*{1,}.*(\n|\r|\r\n)( *\*.*(\n|\r|\r\n))+ *\*{1,}/ *(\n|\r|\r\n)"/>
        <property name="message" value="The second character of each line in the header must be an asterisk (''*'')."/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="1"/>
    </module>

    <module name="RegexpHeader">
        <property name="fileExtensions" value="txt, java, toy"/>
        <property name="header" value="\/\*{70,}\s*$"/>
        <message key="header.mismatch" value="The header must begin on line 1 and the first line of the header must start with the slash character (''/'') and be followed by 78 asterisks (''*'')."/>
        <message key="header.missing"  value="The header must begin on line 1 and the first line of the header must start with the slash character (''/'') and be followed by 78 asterisks (''*'')."/>
    </module>

    <!-- Checks for Name, NetID, and Precept -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="Name:\s+\S"/>
        <property name="ignoreCase" value="false"/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="999"/>
        <property name="message" value="Invalid, empty, or missing ''Name'' in header."/>
    </module>

    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="NetID:\s+[a-zA-Z0-9]{2,8}\s*$"/>
        <property name="ignoreCase" value="false"/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="999"/>
        <property name="message" value="Invalid, empty, or missing ''NetID'' in header."/>
    </module>

    <!-- Forgot to change Name or Partner Name? -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="Name:\s+Kevin\s+Wayne"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="Are you sure that your name (or partner''s name) is ''Kevin Wayne''?"/>
    </module>

    <!-- Forgot to change NetID or Partner NetID? -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="NetID:\s+wayne\s*$"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="Are you sure that your NetID (or partner''s NetID) is ''wayne''?"/>
    </module>

    <!-- Forgot to change Name or Partner Name? -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="Name:\s+Robert\s+Sedgewick"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="Are you sure that your name (or partner''s name) is ''Robert Sedgewick''?"/>
    </module>

    <!-- Forgot to change NetID or Partner NetID? -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="NetID:\s+rs\s*$"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="Are you sure that your NetID (or partner''s NetID) is ''rs''?"/>
    </module>

    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="NetID:\s+[a-zA-Z0-9]{2,8}@princeton.edu\b"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="The NetID must not include the ''@princeton.edu'' suffix."/>
    </module>

    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="Precept:\s+((P[0-9][0-9][A-Z]?)|(B0[12]))\b"/>
        <property name="ignoreCase" value="false"/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="999"/>
        <property name="message" value="Invalid, empty, or missing ''Precept'' in header."/>
    </module>

    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="Precept:\s+(p[0-9][0-9][A-Z]?)\b"/>
        <property name="ignoreCase" value="false"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="The precept number in the header contains the letter ''p'' instead of ''P''."/>
    </module>

    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, java, toy"/>
        <property name="format" value="Precept:\s+(B[Oo][12]|P[Oo][Oo0-9][A-Z]?|P[0-9][Oo][A-Z]?)\b"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="The precept number in the header contains the letter ''O'' instead of the digit ''0''."/>
    </module>

    <!-- Checks for Description, but not in readme.txt  -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="java, toy"/>
        <property name="format" value="Description:\s+\S"/>
        <property name="ignoreCase" value="true"/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="999"/>
        <property name="message" value="Invalid, empty, or missing ''Description'' in header."/>
    </module>

    <!-- This is for readme.txt and .toy files only. LineLength checks only Java files (but also reports number of characters). -->
    <!-- 87 is the limit on codePost before the text because invisible until you scroll -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value ="txt, toy"/>
        <property name="format" value="..{87}"/>
        <property name="message" value="Line exceeds 87 characters."/>
    </module>

    <!-- Checks for more than 87 characters because it ends in whitespace. -->
    <module name="RegexpSingleline">
        <property name="fileExtensions" value="txt, java, toy"/>
        <property name="format" value="^.{87}\s+$"/>
        <property name="message" value="Line exceeds 87 characters because it ends in whitespace."/>
    </module>

    <!-- =========================================================================== -->
    <!-- END: PRINCETON COS 226 SPECIFIC CHECKS (mostly for header)                  -->
    <!-- =========================================================================== -->


    <!-- =========================================================================== -->
    <!-- =========================================================================== -->
    <!-- CHECKS THAT REQUIRE WALKING THE PARSE TREE                                  -->
    <!-- =========================================================================== -->
    <!-- =========================================================================== -->

    <module name="TreeWalker">
        <property name="tabWidth" value="4"/>

        <!-- =========================================================================== -->
        <!-- Check for annotations                                                       -->
        <!-- http://checkstyle.sourceforge.net/config_annotation.html                    -->
        <!-- =========================================================================== -->

<!--
        <module name="AnnotationUseStyle"/>
        <module name="MissingDeprecated"/>
        <module name="MissingOverride"/>
        <module name="PackageAnnotation"/>
        <module name="SuppressWarningsHolder"/>
        <module name="AnnotationLocation"/>
-->

        <!-- =========================================================================== -->
        <!-- Block checks                                                                -->
        <!-- http://checkstyle.sourceforge.net/config_blocks.html                        -->
        <!-- =========================================================================== -->

        <module name="EmptyCatchBlock"/>

        <module name="AvoidNestedBlocks">
            <message key="block.nested" value="Avoid nested blocks: the curly braces serve no purpose."/>
        </module>

        <module name="NeedBraces">
            <property name="tokens" value="LITERAL_DO"/>
        </module>

<!-- 
        <module name="EmptyBlock">
            <property name="option" value="text"/>
            <message key="block.noStmt" value="A block must have at least one statement."/>
        </module>

        <module name="LeftCurly"/> 
        <module name="RightCurly"/>
-->

        <!-- =========================================================================== -->
        <!-- Class design                                                                -->
        <!-- http://checkstyle.sourceforge.net/config_design.html                        -->
        <!-- =========================================================================== -->

        <!-- Flags instance variables in private nested classes (even though they are effectively private) -->
<!--
        <module name="VisibilityModifier">
            <message key="variable.notPrivate" value="The instance (or static) variable ''{0}'' must be private."/>
        </module>
-->

        <module name="InterfaceIsType">
            <message key="interface.type" value="An interface must describe a type (and have methods)."/>
        </module>
        <module name="MutableException"/>
        <module name="ThrowsCount"/>
        <module name="OneTopLevelClass">
            <message key="one.top.level.class" value="The .java file must have exactly one top-level class."/>
        </module>

<!--
        <module name="FinalClass"/>
        <module name="HideUtilityClassConstructor"/>
        <module name="DesignForExtension"/>
        <module name="InnerTypeLast"/>
-->

        <!-- =========================================================================== -->
        <!-- Coding violations                                                           -->
        <!-- http://checkstyle.sourceforge.net/config_coding.html                        -->
        <!-- =========================================================================== -->
        <module name="CovariantEquals">
            <message key="covariant.equals" value="The type of the parameter variable for the ''equals()'' method must be ''Object''."/>
        </module>

        <module name="EmptyStatement">
            <message key="empty.statement" value="Are you sure you want an empty statement here? An empty statement might indicate a superfluous semicolon."/>
        </module>

        <module name="HiddenField">
            <property name="ignoreConstructorParameter" value="true"/>
            <property name="ignoreSetter" value="true"/>
            <message key="hidden.field" value="The local (or parameter) variable ''{0}'' has the same name as an instance variable. Use a different name."/>
        </module>

        <module name="InnerAssignment"/>
        <module name="ModifiedControlVariable">
            <message key="modified.control.variable" value="Control variable ''{0}'' is modified inside loop."/>
        </module>

        <module name="SimplifyBooleanExpression">
            <message key="simplify.expression" value="Boolean expression can be simplified, e.g., use ''if (!isEmpty)'' instead of ''if (isEmpty == false)''."/>
        </module>

        <module name="SimplifyBooleanReturn">
            <message key="simplify.boolreturn" value="Conditional logic can be removed in return statement, e.g., use ''return x >= 0'' instead of ''if (x >= 0) return true; else return false;''."/>
        </module>

        <module name="StringLiteralEquality">
            <message key="string.literal.equality" value="Compare string literals using ''equals()'', not ''{0}''."/>
        </module>

        <module name="NestedForDepth">
            <property name="max" value="4"/>
        </module>
        <module name="NestedIfDepth">
            <property name="max" value="3"/>
        </module>
        <module name="NestedTryDepth">
            <property name="max" value="1"/>
        </module>
        <module name="NoClone"/>
        <module name="NoFinalizer"/>
        <module name="SuperClone"/>
        <module name="SuperFinalize"/>

         <!-- Don't allow these classes in java.lang -->
         <!-- (must include both short and long names for java.lang classes) -->
        <module name="IllegalType">
            <property name="severity" value="error"/>
            <property name="illegalClassNames" value="java.lang.Compiler,          Compiler,
                                                      java.lang.ClassLoader,       ClassLoader,
                                                      java.lang.Class,             Class,
                                                      java.lang.Process,           Process,
                                                      java.lang.Runtime,           Runtime,
                                                      java.lang.RuntimePermission, RuntimePermission,
                                                      java.lang.SecurityManager,   SecurityManager,
                                                      java.lang.System,            System,
                                                      java.lang.Thread,            Thread,
                                                      java.lang.ThreadGroup,       ThreadGroup,
                                                      java.lang.ThreadLocal,       ThreadLocal"/>
            <message key="illegal.type" value="Do not use the data type ''{0}'' in this course."/>
        </module>

        <module name="IllegalType">
            <property name="severity" value="error"/>
            <property name="illegalClassNames" value="java.util.IdentityHashMap,
                                                      java.util.LinkedHashMap,
                                                      java.util.LinkedHashSet,
                                                      java.util.Locale,
                                                      java.util.Locale.Builder,
                                                      java.util.WeakHashMap,
                                                      java.util.Observable,
                                                      java.util.Properties,
                                                      java.util.TimerTask,
                                                      java.util.Timer,
                                                      java.util.concurrent.ArrayBlockingQueue,
                                                      java.util.concurrent.ConcurrentHashMap,
                                                      java.util.concurrent.ConcurrentLinkedDeque,
                                                      java.util.concurrent.ConcurrentLinkedQueue,
                                                      java.util.concurrent.ConcurrentSkipListMap,
                                                      java.util.concurrent.ConcurrentSkipListSet,
                                                      java.util.concurrent.CopyOnWriteArrayList,
                                                      java.util.concurrent.CopyOnWriteArraySet,
                                                      java.util.concurrent.DelayQueue,
                                                      java.util.concurrent.LinkedBlockingDeque,
                                                      java.util.concurrent.LinkedBlockingQueue,
                                                      java.util.concurrent.LinkedTransferQueue,
                                                      java.util.concurrent.PriorityBlockingQueue,
                                                      java.util.concurrent.SynchronousQueue"/>
           <message key="illegal.type" value="Do not use the ''{0}'' data type in this course."/>
        </module>

        <!-- to ensure that the java.util prefix gets used -->
        <module name="IllegalType">
            <property name="illegalClassNames" value="java.util.Vector"/>
            <message key="illegal.type" value="Do not use ''java.util.Vector'' in this course. Instead, use ''java.util.ArrayList'' or ''java.util.LinkedList''."/>
        </module>

        <!-- use StdRandom instead of java.util.Random -->
        <module name="IllegalType">
            <property name="illegalClassNames" value="java.util.Random"/>
            <message key="illegal.type" value="Do not use ''java.util.Random'' in this course. Instead, use an appropriate method from ''StdRandom''."/>
        </module>

        <!-- use StringBuilder instead of StringBuffer -->
        <module name="IllegalType">
            <property name="illegalClassNames" value="java.lang.StringBuffer"/>
            <message key="illegal.type" value="Do not use ''{0}'' in this course. Instead, use ''StringBuilder''."/>
        </module>

        <!-- don't use Hashtable -->
        <module name="IllegalType">
            <property name="illegalClassNames" value="java.util.Hashtable"/>
            <message key="illegal.type" value="Do not use ''java.util.Hashtable'' in this course. Instead, use ''java.util.HashMap''."/>
        </module>

        <module name="DeclarationOrder">
            <message key="declaration.order.constructor" value="Define constructors after static and instance variables but before methods."/>
            <message key="declaration.order.method" value="Define methods after static variables, instance variables, and constructors."/>
            <message key="declaration.order.instance" value="Declare instance variables after static variables but before constructors and methods."/>
            <message key="declaration.order.access" value="Declare static and instance variables in order of their access modifiers: public, protected, package, and private."/>
            <message key="declaration.order.static" value="Declare static variables before instance variables, constructors, and methods."/>
        </module>

<!--
        <module name="ParameterAssignment">
            <message key="parameter.assignment" value="Changing the value of the parameter variable ''{0}'' suggests poor design. Instead, define a local variable."/>
        </module>
-->

        <module name="DefaultComesLast"/>
        <module name="FallThrough"/>

        <module name="OneStatementPerLine">
            <message key="multiple.statements.line" value="Do not put multiple statements on the same line."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="LITERAL_FLOAT"/>
            <message key="illegal.token" value="Use the primitive type ''double'' instead of the primitive type ''float''."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_FLOAT"/>
            <property name="format" value="^.*f$"/>
            <message key="illegal.token.text" value="Use a ''double'' literal instead of a ''float'' literal."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_FLOAT, NUM_DOUBLE"/>
            <property name="format" value="^\..*"/>
            <message key="illegal.token.text" value="Use at least one digit to the left of the decimal point. For example, use the literal ''0.5'' instead of ''.5''."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_INT,NUM_LONG"/>
            <property name="format" value="^0[^lxb]"/>
            <property name="ignoreCase" value="true"/>
            <message key="illegal.token.text" value="A leading 0 in an integer literal signifies that it is an octal (base-8) integer."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_INT,NUM_LONG"/>
            <property name="format" value="^2147483647L?$"/>
            <message key="illegal.token.text" value="Use the named constant ''Integer.MAX_VALUE'' instead of ''2147483647''."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_INT,NUM_LONG"/>
            <property name="format" value="^2147483648L?$"/>
            <message key="illegal.token.text" value="Use the named constant ''Integer.MIN_VALUE'' instead of ''-2147483648''."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_LONG"/>
            <property name="format" value="^9223372036854775807L$"/>
            <message key="illegal.token.text" value="Use the named constant ''Long.MAX_VALUE'' instead of ''9223372036854775807L''."/>
        </module>

        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_LONG"/>
            <property name="format" value="^9223372036854775808L$"/>
            <message key="illegal.token.text" value="Use the named constant ''Long.MIN_VALUE'' instead of ''-9223372036854775808L''."/>
        </module>

        <!-- Do not name a variable 'l'. -->
        <module name="IllegalTokenText">
            <property name="tokens" value="IDENT"/>
            <property name="format" value="^l$"/>
            <message key="illegal.token.text" value="Do not use the letter ''l'' as a variable name (or other identifier). It is hard to distinguish from the number ''1''."/>
        </module>

        <!-- Do not name a variable 'o'. -->
        <module name="IllegalTokenText">
            <property name="tokens" value="IDENT"/>
            <property name="format" value="^[oO]$"/>
            <message key="illegal.token.text" value="Do not use the letter ''o'' or ''O'' as a variable name (or other identifier). It is hard to distinguish from the number ''0''."/>
        </module>

        <!-- Do not name a variable 'one', 'two', 'three', and so forth -->
        <module name="IllegalTokenText">
            <property name="tokens" value="IDENT"/>
            <property name="format" value="^(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve)$"/>
            <property name="ignoreCase" value="true"/>
            <message key="illegal.token.text" value="Do not use the name of a number (such as ''ten'') as a variable name (or other identifier)."/>
        </module>

<!--
        <module name="UnnecessaryParentheses"/>
        <module name="ArrayTrailingComma"/>
        <module name="EqualsAvoidsNull"/>
        <module name="EqualsHashCode"/>    findbugs catches this already
        <module name="FinalLocalVariable"/>
        <module name="IllegalInstantiation"/>
        <module name="PackageDeclaration"/>
        <module name="ReturnCount"/>
        <module name="ExplicitInitialization"/>
        <module name="MissingCtor"/>
        <module name="MultipleStringLiterals"/>
        <module name="MultipleVariableDeclarations"/>
        <module name="RequireThis"/>
        <module name="VariableDeclarationUsageDistance"/>
        <module name="OverloadMethodsDeclarationOrder"/>
        <module name="MagicNumber">
            <property name="tokens" value="NUM_DOUBLE, NUM_FLOAT, NUM_INT, NUM_LONG"/>
            <property name="ignoreNumbers" value="-256, -128, -100, -64, -32, -16, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 32, 64, 100, 128, 256, 512, 1024, 32768"/>
            <message key="magic.number" value="''{0}'' looks like a hard-coded value. This should be made a constant variable with a symbolic name (such as AVOGADROS_NUMBER)."/>
        </module>
        <module name="MissingSwitchDefault">
            <message key="missing.switch.default" value="A switch statement must contain a ''default'' clause."/>
        </module>
-->

        <!-- =========================================================================== -->
        <!-- Headers                                                                     -->
        <!-- http://checkstyle.sourceforge.net/config_header.html                        -->
        <!-- =========================================================================== -->

<!--
        <module name="Header"/>
-->

        <!-- =========================================================================== -->
        <!-- Imports                                                                     -->
        <!-- http://checkstyle.sourceforge.net/config_imports.html                       -->
        <!-- =========================================================================== -->

        <module name="AvoidStaticImport">
            <message key="import.avoidStatic" value="Do not use static imports."/>
        </module>

        <module name="RedundantImport">
            <message key="import.same" value="Unnecessary import statement for ''{0}'' becaue it is in the same package as this class."/>
            <message key="import.lang" value="Unnecessary import statement for ''{0}'' because it is from the package ''java.lang''."/>
            <message key="import.duplicate" value="Duplicate import statement for ''{1}''."/>
        </module>

        <module name="UnusedImports">
            <message key="import.unused" value="Unused import statement for ''{0}''."/>
        </module>

        <module name="AvoidStarImport">
            <message key="import.avoidStar" value="Do not use .* in import statements."/>
        </module>

<!--

        <module name="ImportOrder"/>
        <module name="ImportControl"/>
        <module name="CustomImportOrder"/>
-->

        <!-- =========================================================================== -->
        <!-- Javadoc comments                                                            -->
        <!-- http://checkstyle.sourceforge.net/config_javadoc.html                       -->
        <!-- =========================================================================== -->

<!--    Running time increases substantially with Javadoc checks -->
<!--
        <module name="JavadocStyle"/>
        <module name="NonEmptyAtclauseDescription"/>
        <module name="AtclauseOrder"/>
        <module name="JavadocPackage"/>
        <module name="JavadocType"/>
        <module name="JavadocMethod"/>
        <module name="JavadocVariable"/>
        <module name="WriteTag"/>
        <module name="SummaryJavadoc"/>
        <module name="JavadocParagraph"/>
        <module name="SingleLineJavadoc"/>
-->

        <!-- =========================================================================== -->
        <!-- Metrics                                                                     -->
        <!-- http://checkstyle.sourceforge.net/config_metrics.html                       -->
        <!-- =========================================================================== -->

<!--
        <module name="BooleanExpressionComplexity"/>
        <module name="ClassDataAbstractionCoupling"/>
        <module name="ClassFanOutComplexity"/>
        <module name="CyclomaticComplexity"/>
        <module name="NPathComplexity"/>
        <module name="JavaNCSS"/>
-->

        <!-- =========================================================================== -->
        <!-- Miscellaneous checks                                                        -->
        <!-- http://checkstyle.sourceforge.net/config_misc.html                          -->
        <!-- =========================================================================== -->
        <module name="TodoComment"/>

        <module name="UpperEll">
            <message key="upperEll" value="Use an uppercase ''L'' instead of a lowercase ''l'' to specify a literal of type long."/>
        </module>

        <module name="ArrayTypeStyle">
            <message key="array.type.style" value="To specify an array type, put the square brackets before the variable name, e.g., ''String[] args'' instead of ''String args[]''."/>
        </module>

        <module name="OuterTypeFilename">
            <message key="type.file.mismatch" value="The name of the outer type and the file do not match. For example, the class Point must be in a file named Point.java."/>
        </module>

<!--
        <module name="UncommentedMain"/>
        <module name="FinalParameters"/>
        <module name="Indentation"/>
        <module name="TrailingComment"/>
        <module name="AvoidEscapedUnicodeCharacters"/>
-->

        <module name="DescendantToken">
            <property name="tokens" value="LITERAL_ASSERT"/>
            <property name="limitedTokens" value="ASSIGN,DEC,INC,POST_DEC,
                POST_INC,PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,DIV_ASSIGN,MOD_ASSIGN,
                BSR_ASSIGN,SR_ASSIGN,SL_ASSIGN,BAND_ASSIGN,BXOR_ASSIGN,BOR_ASSIGN"/>
            <property name="maximumNumber" value="0"/>
            <property name="maximumMessage" value="Assert statements must not produce side effects."/>
        </module>

        <module name="DescendantToken">
            <property name="tokens" value="EQUAL,NOT_EQUAL"/>
            <property name="limitedTokens" value="LITERAL_THIS,LITERAL_NULL"/>
            <property name="maximumNumber" value="1"/>
            <property name="maximumDepth" value="1"/>
            <property name="sumTokenCounts" value="true"/>
            <property name="maximumMessage" value="Do not compare ''this'' with ''null''; it is never null."/>
        </module>

        <!-- =========================================================================== -->
        <!-- Modifiers                                                                   -->
        <!-- http://checkstyle.sourceforge.net/config_modifier.html                      -->
        <!-- =========================================================================== -->

        <module name="ModifierOrder">
            <message key = "mod.order" value = "The modifier ''{0}'' is out of order. The preferred order is [''public'', ''protected'', ''private'', ''abstract'', ''static'', ''final'', ''transient'', ''volatile'', ''synchronized'', ''native'', and ''strictfp'']."/>
        </module>

        <!-- removed CTOR_DEF for public constructors in private nested classes -->
        <module name="RedundantModifier">
            <property name="tokens" value="METHOD_DEF,VARIABLE_DEF,ANNOTATION_FIELD_DEF,
                                           INTERFACE_DEF,CLASS_DEF,ENUM_DEF"/>
        </module>

        <!-- =========================================================================== -->
        <!-- Naming conventions                                                          -->
        <!-- http://checkstyle.sourceforge.net/config_naming.html                        -->
        <!-- =========================================================================== -->

        <!-- MODIFIED TO ALLOW FINAL VARIABLES TO BE ALL UPPERCASE     -->
        <!-- MODIFIED TO ALLOW TYPE PARAMETERS TO BE LIKE CLASS NAMES  -->

        <!-- static final field -->
        <module name="ConstantName">
            <message key="name.invalidPattern" value="The constant ''{0}'' must be ALL_UPPERCASE, with words separated by underscores."/>
        </module>

        <!-- includes catch parameters -->
        <module name="LocalFinalVariableName">
            <property name="format" value="^([a-z][a-zA-Z0-9]*|[A-Z][A-Z_0-9]*)$"/>
            <message key="name.invalidPattern" value="The local final variable ''{0}'' must start with a lowercase letter and use camelCase (or be ALL_UPPERCASE if it is a constant)."/>
        </module>  

        <!-- local variables, allow camelCase or ALL_UPPERCASE of two or more characters -->
        <module name="LocalVariableName">
            <!-- <property name="format" value="^([a-z][a-zA-Z0-9]*|[A-Z][A-Z_0-9]+|G|[A-Z])$"/> -->
            <property name="format" value="^([a-z][a-zA-Z0-9]*|[A-Z][A-Z_0-9]+|G)$"/>
            <message key="name.invalidPattern" value="The local variable ''{0}'' must start with a lowercase letter and use camelCase."/>
        </module>

        <!-- instance variables must be camelCase or G -->
        <module name="MemberName">
            <property name="format" value="^([a-z][a-zA-Z0-9]*|G)$"/>
            <message key="name.invalidPattern" value="The instance variable ''{0}'' must start with a lowercase letter and use camelCase."/>
        </module>

        <!-- method name -->
        <!-- ^[a-z][a-zA-Z0-9]*$ -->
        <module name="MethodName">
            <message key="name.invalidPattern" value="The method ''{0}'' must start with a lowercase letter and use camelCase."/>
            <message key="method.name.equals.class.name" value="The method name ''{0}'' must not be identical to the class name. Remove the return type if you intended to define a constructor instead of a method."/>
        </module>

        <module name="PackageName">
            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
            <message key="name.invalidPattern" value="The package ''{0}'' must be lowercase, with package components separated by dots."/>
        </module>

        <!-- allows single letter uppercase parameter variable names in COS 226 -->
        <module name="ParameterName">
            <property name="format" value="^([a-z][a-zA-Z0-9]*|G|[A-Z])$"/>
            <message key="name.invalidPattern" value="The parameter variable ''{0}'' must start with a lowercase letter and use camelCase."/>
        </module>

        <!-- static non-final field -->
        <!-- ^[a-z][a-zA-Z0-9]*$ -->
        <module name="StaticVariableName">
            <message key="name.invalidPattern" value="The static variable ''{0}'' must start with a lowercase letter and use camelCase. If you intended ''{0}'' to be a constant, add the modifier ''final'' immediately after ''static'' and use ALL_UPPERCASE."/>
        </module>

        <!-- type name -->
        <!-- ^[A-Z][a-zA-Z0-9]*$ -->
        <module name="TypeName">
            <message key="name.invalidPattern" value="The class ''{0}'' must start with an uppercase letter and use CamelCase."/>
        </module>

        <module name="ClassTypeParameterName">
            <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
            <message key="name.invalidPattern" value="The type parameter ''{0}'' must either be a single uppercase letter or start with an uppercase letter and use CamelCase."/>
        </module>

        <module name="MethodTypeParameterName">
            <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
            <message key="name.invalidPattern" value="The type parameter ''{0}'' must either be a single uppercase letter or start with an uppercase letter and use CamelCase."/>
        </module>

        <module name="InterfaceTypeParameterName">
            <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
            <message key="name.invalidPattern" value="The type parameter ''{0}'' must either be a single uppercase letter or start with an uppercase letter and use CamelCase."/>
        </module>

<!--
	<module name="AbstractClassName"/>
-->

        <!-- =========================================================================== -->
        <!-- Regexp                                                                      -->
        <!-- http://checkstyle.sourceforge.net/config_regexp.html                        -->
        <!-- =========================================================================== -->

        <!-- Checks for calls to StdDraw.show(int). -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="\bStdDraw\.show\(\d+\)"/>
            <property name="ignoreComments" value="true"/>
            <property name="message" value="The method ''StdDraw.show(int)'' is deprecated. Use ''StdDraw.enableDoubleBuffering()'', ''StdDraw.show()'', and ''StdDraw.pause(int)'' instead."/>
        </module>

        <!-- check for Math.pow(*, 3) and Math.pow(*, 0.5) -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="\bMath\.pow\([^,]*, *3(\.0?)?\)"/>
            <property name="ignoreComments" value="true"/>
            <property name="message" value="''Math.pow(x, 3)'' is slow. Use ''x*x*x'' instead."/>
        </module>

        <module name="RegexpSinglelineJava">
            <property name="format" value="\bMath\.pow\([^,]*, *0?\.5\)"/>
            <property name="ignoreComments" value="true"/>
            <property name="message" value="Use ''Math.sqrt(x)'' instead of ''Math.pow(x, 0.5)''."/>
        </module>

<!--
        <module name="Regexp"/>
-->

        <!-- =========================================================================== -->
        <!-- Size violations                                                             -->
        <!-- http://checkstyle.sourceforge.net/config_sizes.html                         -->
        <!-- =========================================================================== -->

        <module name="AnonInnerLength"/>
        <module name="ParameterNumber"/>

        <module name="OuterTypeNumber">
            <message key="maxOuterTypes" value="Your program defines {0,number,integer} outer types, but there should be only 1."/>
        </module>

        <module name="MethodCount"/>

<!--
        <module name="ExecutableStatementCount"/>
-->

        <!-- =========================================================================== -->
        <!-- Whitespace                                                                  -->
        <!-- http://checkstyle.sourceforge.net/config_whitespace.html                    -->
        <!-- =========================================================================== -->
        <module name="GenericWhitespace"/>
        <module name="EmptyForInitializerPad"/>
        <module name="EmptyForIteratorPad"/>
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceAfter">
           <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/>
         </module>
        <module name="NoWhitespaceBefore"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter">
            <message key="ws.typeCast" value="Typecast is not followed by whitespace."/>
        </module>

        <module name="WhitespaceAround">
           <!-- removed PLUS, MINUS, STAR, DIV -->
           <!-- removed GENERIC_START, GENERIC_END -->
           <property name="tokens"
            value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, 
                   BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON,  DIV_ASSIGN,
                   EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_ASSERT,
                   LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
                   LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SYNCHRONIZED,
                   LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS_ASSIGN, MOD,
                   MOD_ASSIGN, NOT_EQUAL, PLUS_ASSIGN, QUESTION, RCURLY,
                   SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR_ASSIGN,
                   TYPE_EXTENSION_AND"/>
        </module>

        <!-- seems buggy if used with class in default package. seems to need VARIABLE_DEF for it to behave properly? -->
<!--
        <module name="EmptyLineSeparator">
            <property name="tokens" value="CTOR_DEF, VARIABLE_DEF"/>
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
            <message key="empty.line.separator" value="Constructor must be separated from previous statement with a blank line."/>
        </module>
        <module name="EmptyLineSeparator">
            <property name="tokens" value="METHOD_DEF, VARIABLE_DEF"/>
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
            <message key="empty.line.separator" value="Method must be separated from previous statement with a blank line."/>
        </module>
        <module name="EmptyLineSeparator">
            <property name="tokens" value="CLASS_DEF, VARIABLE_DEF"/>
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
            <message key="empty.line.separator" value="Class definition must be separated from previous statement or header with a blank line."/>
        </module>

        <module name="EmptyLineSeparator">
            <property name="tokens" value="IMPORT, INTERFACE_DEF, VARIABLE_DEF, METHOD_DEF, PACKAGE_DEF, CTOR_DEF, STATIC_INIT, INSTANCE_INIT"/>
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
            <message key="empty.line.separator" value="''{0}'' must be separated from previous statement with a blank line."/>
        </module>
-->

<!--
        <module name="OperatorWrap">
            <property name="option" value="eol"/>
            <message key="line.previous" value="''{0}'' must be at the end of the previous line."/>
        </module>
        <module name="NoLineWrap"/>
        <module name="SeparatorWrap"/>
-->

        <!-- =========================================================================== -->
        <!-- COURSE SPECIFIC CHECKS                                                      -->
        <!-- =========================================================================== -->

        <!-- Don't allow suppressing of compiler warnings. -->
        <module name="SuppressWarnings">
            <property name="severity" value="error"/>
            <property name="format" value=".*"/>
            <property name="tokens"
                     value="CLASS_DEF,INTERFACE_DEF,ENUM_DEF,ANNOTATION_DEF,ANNOTATION_FIELD_DEF,
                            ENUM_CONSTANT_DEF,METHOD_DEF,CTOR_DEF,PARAMETER_DEF,VARIABLE_DEF"/>
            <message key="suppressed.warning.not.allowed" value="Do not suppress warnings in this course."/>
        </module>

        <!-- no implementation inheritance -->
        <module name="IllegalToken">
            <property name="tokens" value="EXTENDS_CLAUSE"/>
            <message key="illegal.token" value="Do not use implementation inheritance in this course."/>
        </module>

        <!-- type upper or lower bounds -->
        <module name="IllegalToken">
            <property name="id" value="type_bounds"/>
            <property name="tokens" value="TYPE_UPPER_BOUNDS, TYPE_LOWER_BOUNDS, TYPE_EXTENSION_AND"/>
            <message key="illegal.token" value="You should not need to use type upper or lower bounds in this course."/>
        </module>

        <!-- wildcard types -->
        <module name="IllegalToken">
            <property name="tokens" value="WILDCARD_TYPE"/>
            <message key="illegal.token" value="You should not need to use wildcard types in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="id" value="xor"/>
            <property name="tokens" value="BXOR, BXOR_ASSIGN"/>
            <message key="illegal.token" value="Did you mean to use ''Math.pow()'' instead of the bitwise XOR operator (''^'') ?"/>
        </module>

<!--  triggers too many warnings
        <module name="IllegalToken">
            <property name="tokens" value="TYPECAST"/>
            <message key="illegal.token" value="Avoid typecasts whenever possible."/>
        </module>
-->

<!--   seems to flag double literals as well as float literals; appears to be a bug in Checkstyle
        <module name="IllegalToken">
            <property name="tokens" value="NUM_FLOAT"/>
            <message key="illegal.token" value="Use the primitive type ''double'' instead of the primitive type ''float''."/>
        </module>
-->
        <module name="IllegalToken">
            <property name="severity" value="error"/>
            <property name="tokens" value="PACKAGE_DEF"/>
            <message key="illegal.token" value="Do not define packages in this course. You must use the default (no-name) package in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="severity" value="error"/>
            <property name="tokens" value="LITERAL_NATIVE, STRICTFP, LITERAL_VOLATILE, LITERAL_TRANSIENT, LITERAL_SYNCHRONIZED"/>
            <message key="illegal.token" value="Do not use the keyword ''{0}'' in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="severity" value="error"/>
            <property name="tokens" value="LITERAL_THROWS, LITERAL_SUPER, LITERAL_PROTECTED, ABSTRACT"/>
            <message key="illegal.token" value="Do not use the keyword ''{0}'' in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="severity" value="error"/>
            <property name="tokens" value="STATIC_INIT"/>
            <message key="illegal.token" value="Do not use static initializers in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="LITERAL_INSTANCEOF"/>
            <message key="illegal.token" value="Do not use the ''instanceof'' operator in this course. Use ''getClass()'' to compare classes."/>
        </module>

        <!-- Avoid masking of Exception, Throwable, RuntimeException -->
        <module name="IllegalCatch">
            <property name="severity" value="error"/>
            <property name="illegalClassNames" value="java.lang.Exception,
                                                      java.lang.Throwable,
                                                      java.lang.RuntimeException,
                                                      java.lang.AssertionError,
                                                      java.lang.VirtualMachineError,
                                                      java.lang.InternalError,
                                                      java.lang.StackOverflowError,
                                                      java.lang.UnknownError,
                                                      java.lang.OutOfMemoryError"/>
            <message key="illegal.catch" value="Do not catch ''{0}'' in this course."/>
        </module>

        <module name="IllegalThrows">
            <message key="illegal.throw" value="Do not throw ''{0}'' in this course."/>
        </module>

        <!-- Disallow java.io and other packages that students must not use -->
        <!-- Disallowing the package also disallows all subpackages. -->

        <module name="IllegalImport">
            <property name="severity" value="error"/>
            <property name="illegalPkgs" value="java.applet,
                                                java.beans,
                                                java.math,
                                                java.net,
                                                java.rmi,
                                                java.security,
                                                java.sql,
                                                java.text,
                                                java.time,
                                                javax,
                                                org,
                                                sun"/>
            <message key="import.illegal" value="Do not import ''{0}'' in this course."/>
        </module>


        <module name="IllegalImport">
            <property name="severity" value="error"/>
            <property name="illegalPkgs" value="edu.princeton.cs.introcs,
                                                java.nio,
                                                java.io"/>
            <message key="import.illegal" value="Do not import ''{0}'' in this course. Instead, use the I/O libraries in edu.princeton.cs.algs4."/>
        </module>


        <!-- =========================================================================== -->
        <!-- BEGIN: PRINCETON COS 226 SPECIFIC CHECKS                                    -->
        <!-- =========================================================================== -->

        <!-- Check that length of line is at most 87 characters. -->
        <module name="LineLength">
            <property name="max" value="87"/>
            <message key="maxLineLen" value="Line exceeds {0,number,integer} characters (currently {1,number,integer})."/>
        </module>

        <module name="MethodLength">
            <property name="max" value="150"/>
            <property name="countEmpty" value="true"/>
            <message key="maxLine.method" value="Method length is {0,number,integer} lines (max allowed is {1,number,integer})."/>
        </module>

        <module name="IllegalToken">
            <property name="id" value="bor"/>
            <property name="tokens" value="BOR, BOR_ASSIGN"/>
            <message key="illegal.token" value="Did you mean to use the conditional OR operator (''||'') instead of the bitwise OR operator (''|'') ?"/>
        </module>

        <module name="IllegalToken">
            <property name="id" value="band"/>
            <property name="tokens" value="BAND, BAND_ASSIGN"/>
            <message key="illegal.token" value="Did you mean to use the conditional AND operator (''&amp;&amp;'') instead of the bitwise AND operator (''&amp;'') ?"/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="LAMBDA"/>
            <message key="illegal.token" value="Do not use lambdas in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="ENUM_DEF"/>
            <message key="illegal.token" value="Do not define enums in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="ELLIPSIS"/>
            <message key="illegal.token" value="Do not use variable-length arguments in this course."/>
        </module>

        <module name="AvoidInlineConditionals">
            <message key="inline.conditional.avoid" value="Do not use the ternary conditional operator in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="LABELED_STAT"/>
            <message key="illegal.token" value="Do not use labeled break or continue statements in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="DOUBLE_COLON"/>
            <message key="illegal.token" value="Do not use method references in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="INTERFACE_DEF"/>
            <message key="illegal.token" value="Do not define interfaces in this course."/>
        </module>

        <module name="IllegalToken">
            <property name="tokens" value="WILDCARD_TYPE, TYPE_EXTENSION_AND, TYPE_LOWER_BOUNDS"/>
            <message key="illegal.token" value="Do not use ''{0}'' with generics in this course."/>
        </module>

        <!-- =========================================================================== -->
        <!-- END: PRINCETON COS 226 SPECIFIC CHECKS                                      -->
        <!-- =========================================================================== -->

    </module>
</module>
